├── LICENSE ├── README.md ├── dir ├── array.sh ├── break.sh ├── case.sh ├── continue.sh ├── for.sh ├── function.sh ├── hello.php ├── hello.py ├── hello.sh ├── if-then-elif.sh ├── if-then-elif2.sh ├── operation.sh ├── string.sh └── while.sh ├── hello.txt ├── img ├── [1].jpg ├── [2].jpg ├── awk.jpg ├── cal.jpg ├── cat.jpg ├── clear.png ├── copy.jpg ├── date.jpg ├── diff.jpg ├── du.jpg ├── echo.jpg ├── etc:passwd.jpg ├── export.jpg ├── find.jpg ├── grep.jpg ├── grep_w.jpg ├── head.jpg ├── ls.jpg ├── mkdir.jpg ├── mv.jpg ├── ps.jpg ├── rm.jpg ├── sed.jpg ├── shell.jpg ├── sort.jpg ├── ssh.jpg ├── string-integer.jpg ├── test.jpg ├── testEx.jpg ├── top.jpg ├── touch.jpg ├── wc.jpg ├── whatis.png ├── whereis.png └── which.jpg ├── index.php ├── linux-user-group-file.md └── ssr.sh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 OMGZui 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bash 跟着敲 2 | 3 | 前言:本文不单单是介绍常用的命令,还融入了bash语法,每个知识点都有浅显的例子配合,让你很容易消化并吸收,最后还有一个boss任务等你挑战,耐心学完的同学肯定会有很大的收获的。大家觉得有用的话,star一下,然后可以随意分享给需要的人,重点是加颗星星哦,加颗星星哦,加颗星星哦。 4 | 5 | 6 | 7 | - [bash 跟着敲](#bash-跟着敲) 8 | - [一. 硬件、内核、shell](#一-硬件内核shell) 9 | - [二. 命令行](#二-命令行) 10 | - [1. 基本操作](#1-基本操作) 11 | - [export](#export) 12 | - [whatis](#whatis) 13 | - [whereis](#whereis) 14 | - [which](#which) 15 | - [clear](#clear) 16 | - [2. 文件操作](#2-文件操作) 17 | - [cat](#cat) 18 | - [chmod](#chmod) 19 | - [cp](#cp) 20 | - [diff](#diff) 21 | - [find](#find) 22 | - [head](#head) 23 | - [ls](#ls) 24 | - [mv](#mv) 25 | - [rm](#rm) 26 | - [touch](#touch) 27 | - [3. 文本操作](#3-文本操作) 28 | - [awk](#awk) 29 | - [grep](#grep) 30 | - [sed](#sed) 31 | - [sort](#sort) 32 | - [wc](#wc) 33 | - [4. 目录操作](#4-目录操作) 34 | - [cd](#cd) 35 | - [mkdir](#mkdir) 36 | - [pwd](#pwd) 37 | - [5. SSH,系统信息,网络操作](#5-ssh系统信息网络操作) 38 | - [cal](#cal) 39 | - [date](#date) 40 | - [df](#df) 41 | - [du](#du) 42 | - [ps](#ps) 43 | - [ssh](#ssh) 44 | - [top](#top) 45 | - [三. 语法](#三-语法) 46 | - [1 条件判断](#1-条件判断) 47 | - [1.1 test判断语句](#11-test判断语句) 48 | - [1.2 []条件判断](#12-条件判断) 49 | - [2 if then else语句](#2-if-then-else语句) 50 | - [3 case语句](#3-case语句) 51 | - [4 for循环](#4-for循环) 52 | - [5 while循环](#5-while循环) 53 | - [6 使用break和continue控制循环](#6-使用break和continue控制循环) 54 | - [四. 数组](#四-数组) 55 | - [1 数组定义](#1-数组定义) 56 | - [2 数组操作](#2-数组操作) 57 | - [五.函数](#五函数) 58 | - [六.数值运算](#六数值运算) 59 | - [七. 字符运算](#七-字符运算) 60 | - [八. bash调试](#八-bash调试) 61 | - [bash [-nvx] scripts.sh](#bash--nvx-scriptssh) 62 | - [echo [-neE] string](#echo--nee-string) 63 | - [九. bash内建指令](#九-bash内建指令) 64 | - [echo](#echo) 65 | - [read](#read) 66 | - [alias](#alias) 67 | - [export](#export-1) 68 | - [exec](#exec) 69 | - [.](#) 70 | - [exit](#exit) 71 | - [十. 参考资料](#十-参考资料) 72 | - [十一. 大BOSS](#十一-大boss) 73 | 74 | 75 | 76 | ## 一. 硬件、内核、shell 77 | 78 | 下面这张摘自鸟哥的图可以很好的说明 79 |  80 | 81 | ## 二. 命令行 82 | 83 | ### 1. 基本操作 84 | 85 | #### export 86 | 87 | 展示全部的环境变量,如果你想获取某个特殊的变量,用 `echo $变量名` 88 |  89 |  90 | 91 | #### whatis 92 | 93 | 展示用户命令,系统调用、库函数等 94 |  95 | 96 | #### whereis 97 | 98 | 搜索可执行文件、源文件 99 |  100 | 101 | #### which 102 | 103 | 在环境变量中搜索可执行文件,并打印完整路径 104 |  105 | 106 | #### clear 107 | 108 | 清空屏幕 109 |  110 | 111 | ### 2. 文件操作 112 | 113 | #### cat 114 | 115 | 在屏幕上显示文本文件 116 |  117 | 118 | #### chmod 119 | 120 | 可以改变文件和目录的读、写、执行权限 121 | [linux 中的用户、组、文件][1] 122 | 123 | #### cp 124 | 125 | 复制文件 126 |  127 | 128 | #### diff 129 | 130 | 比较文件,我在上面复制的文件中加了一行diff 131 |  132 | 133 | #### find 134 | 135 | 查找文件,可以通过正则来查 136 |  137 | 138 | #### head 139 | 140 | 查看文件前10行 141 |  142 | 143 | #### ls 144 | 145 | 显示所有文件,`-l`显示长格式化 `-a`显示包括隐藏文件 146 |  147 | 148 | #### mv 149 | 150 | 移动文件,同时也可以重命名文件 151 |  152 | 153 | #### rm 154 | 155 | 删除文件,`-r`删除目录 `-f`强制删除 156 |  157 | 158 | #### touch 159 | 160 | 创建新文件 161 |  162 | 163 | ### 3. 文本操作 164 | 165 | #### awk 166 | 167 | 非常有用的一个文本处理命令,逐行运行,默认使用空格分割,`-F`表示分割的样式 168 |  169 |  170 | 171 | #### grep 172 | 173 | 匹配正则表达式的文本行,并输出,`-E`正则模糊匹配 `-F`精确字母匹配 `-w`精确单词匹配 174 |  175 |  176 | 177 | #### sed 178 | 179 | 正则替换 180 |  181 | 182 | #### sort 183 | 184 | 排序 185 |  186 | 187 | #### wc 188 | 189 | 统计文本行数,单词数,字符数 190 |  191 | 192 | ### 4. 目录操作 193 | 194 | #### cd 195 | 196 | 进入目录 197 | 198 | #### mkdir 199 | 200 | 创建目录 201 | 202 | #### pwd 203 | 204 | 当前目录的路径 205 |  206 | 207 | ### 5. SSH,系统信息,网络操作 208 | 209 | #### cal 210 | 211 | 月历 212 |  213 | 214 | #### date 215 | 216 | 当前日期和时间 217 |  218 | 219 | #### df 220 | 221 | 磁盘使用情况 222 | 223 | #### du 224 | 225 | 文件或目录使用情况 226 |  227 | 228 | #### ps 229 | 230 | 列出你的进程 231 |  232 | 233 | #### ssh 234 | 235 | 远程连接 236 |  237 | 238 | #### top 239 | 240 | 列出当然活动进程 241 |  242 | 243 | ## 三. 语法 244 | 245 | ### 1 条件判断 246 | 247 | #### 1.1 test判断语句 248 | 249 | test是关键字,表示判断;EXPRESSION是被判断的语句。 250 | 251 |  252 | 253 | `echo $?` 输出判断结果,0表示成功,其他表示失败。 254 |  255 | 256 | #### 1.2 []条件判断 257 | 258 | 中括号的左右扩弧和EXPRESSION之间都必须有空格! 259 |  260 | 261 | 文件类型判断 262 |  263 | 字符串和数字判断 264 |  265 | 266 | ### 2 if then else语句 267 | 268 | 例子1:判断文件README.md是不是文件 269 | 270 | ```sh 271 | #!/bin/bash 272 | 273 | if [ -f ../README.md ];then 274 | echo 'file exist' 275 | else 276 | echo 'file not exist' 277 | fi 278 | 279 | exit 0 280 | ``` 281 | 282 | 例子2:提示用户输入值,如果大于0输出’正数’,小于0输出’负数‘,等于0输出’零‘ 283 | 284 | ```sh 285 | #!/bin/bash 286 | 287 | # 提示用户输入一个值 288 | echo -n "请输入一个数字:" 289 | 290 | # 保存用户输入的值到num中 291 | read num 292 | 293 | if [ "$num" -gt 0 ];then 294 | echo '正数' 295 | elif [ "$num" -lt 0 ];then 296 | echo '负数' 297 | else 298 | echo '零' 299 | fi 300 | 301 | exit 0 302 | ``` 303 | 304 | ### 3 case语句 305 | 306 | 例子:提示用户输入Y/y或N/n。若输入Y/y,则输出“我们约起来吧”;若输入N/n,则输出“不约,再见”;否则,“输入有误” 307 | 308 | ```sh 309 | #!/bin/bash 310 | 311 | echo -n "你单身吗?(y/n)" 312 | 313 | read val 314 | 315 | case $val in 316 | Y|y) 317 | echo "我们约起来吧" 318 | ;; 319 | N|n) 320 | echo "不约,再见" 321 | ;; 322 | *) 323 | echo "输入有误" 324 | ;; 325 | esac 326 | 327 | exit 0 328 | ``` 329 | 330 | ### 4 for循环 331 | 332 | 例子1:输出当前文件夹的一级子目录中文件名字 333 | 334 | ```sh 335 | #!/bin/bash 336 | 337 | # 将ls的结果保存到变量CUR_DIR中 338 | CUR_DIR=`ls` 339 | 340 | # 显示ls的结果 341 | echo $CUR_DIR 342 | 343 | for val in $CUR_DIR 344 | do 345 | if [ -f $val ];then 346 | echo "FILE: $val" 347 | fi 348 | done 349 | 350 | exit 0 351 | ``` 352 | 353 | 例子2:输出1-10之间数字的总和 354 | 355 | ```sh 356 | #!/bin/bash 357 | 358 | sum=0 359 | for ((i=1;i<10;i++)) 360 | do 361 | ((sum=$sum+$i)) 362 | done 363 | 364 | echo "sum=$sum" 365 | 366 | exit 0 367 | ``` 368 | 369 | ### 5 while循环 370 | 371 | 例子:从0开始逐步递增,当数值等于5时,停止递增 372 | 373 | ```sh 374 | #!/bin/bash 375 | 376 | val=0 377 | 378 | while [ "$val" -lt 5 ] 379 | do 380 | echo "val=$val" 381 | ((val++)) 382 | done 383 | 384 | exit 0 385 | ``` 386 | 387 | ### 6 使用break和continue控制循环 388 | 389 | break命令允许跳出循环 390 | 391 | continue命令类似于 break命令,只有一点重要差别,它不会跳出循环,只是跳过这个循环步。 392 | 393 | 例子1:[break应用]从0开始逐步递增,当数值等于5时,停止递增。 394 | 395 | ```sh 396 | #!/bin/bash 397 | 398 | # 设置起始值为0 399 | val=0 400 | 401 | while true 402 | do 403 | if [ "$val" -eq "5" ];then 404 | # 如果val=5,则跳出循环 405 | break; 406 | else 407 | # 输出数值 408 | echo "val=$val" 409 | # 将数值加1 410 | ((val++)) 411 | fi 412 | done 413 | 414 | exit 0 415 | ``` 416 | 417 | 例子2:[continue应用]从0开始逐步递增到10:当数值为5时,将数值递增2;否则,输出数值 418 | 419 | ```sh 420 | #!/bin/bash 421 | 422 | # 设置起始值为0 423 | val=0 424 | 425 | while [ "$val" -le "10" ] 426 | do 427 | if [ "$val" -eq "5" ];then 428 | # 如果val=5,则将数值加2 429 | ((val=$val+2)) 430 | continue; 431 | else 432 | # 输出数值 433 | echo "val=$val" 434 | # 将数值加1 435 | ((val++)) 436 | fi 437 | done 438 | 439 | exit 0 440 | ``` 441 | 442 | ## 四. 数组 443 | 444 | ### 1 数组定义 445 | 446 | - array=(10 20 30 40 50) 447 | 448 | 一对括号表示是数组,数组元素用“空格”符号分割开。引用数组时从序号0开始。 449 | 450 | - 除了上面的定义方式外,也可以单独定义数组: 451 | 452 | ```sh 453 | array[0]=10 454 | array[1]=20 455 | array[2]=30 456 | array[3]=40 457 | array[4]=50 458 | ``` 459 | 460 | - var="10 20 30 40 50"; array=($var) 461 | 462 | ### 2 数组操作 463 | 464 | [数组操作][2] 465 | 466 | ```sh 467 | #!/bin/bash 468 | 469 | array=(10 20 30 40 50) 470 | 471 | # 显示数组中所有元素 472 | echo '显示数组中所有元素' 473 | echo ${array[*]} 474 | echo ${array[@]} 475 | 476 | # 显示数组第2项 477 | echo '显示数组第2项' 478 | echo ${array[1]} 479 | 480 | # 显示数组长度 481 | echo '显示数组长度' 482 | echo ${#array[@]} 483 | 484 | # 输出数组的第1-3项 485 | echo '输出数组的第1-3项' 486 | echo ${array[@]:0:3} 487 | 488 | # 将数组中的0替换成1 489 | echo '将数组中的0替换成1' 490 | echo ${array[@]/0/1} 491 | 492 | # 删除数组第2项元素 493 | # 说明: 494 | # unset仅仅只清除array[1]的值,并没有将array[1]删除掉 495 | echo '删除数组第2项元素' 496 | unset array[1] 497 | echo ${array[@]} 498 | 499 | exit 0 500 | ``` 501 | 502 | ## 五.函数 503 | 504 | [函数实例][3] 505 | 506 | ```sh 507 | #!/bin/bash 508 | 509 | # 编辑一个函数foo:打印foo的输入参数的总数,并输入每个参数和参数对应的序号。 510 | function foo() 511 | { 512 | # 定义局部变量i 513 | local i=0 514 | # 定义局部变量total=传入foo的参数总数 515 | local total=$# 516 | # 输出参数总数 517 | echo "total param =$total" 518 | # 输出传入foo的每一个参数 519 | for val in $@ 520 | do 521 | ((i++)) 522 | echo "$i -- val=$val" 523 | done 524 | 525 | # 返回参数总数 526 | return $total 527 | } 528 | 529 | foo 530 | foo param1 param2 param3 531 | # 输出foo param1 param2 param3的返回值 532 | echo "return value=$?" 533 | 534 | exit 0 535 | ``` 536 | 537 | ## 六.数值运算 538 | 539 | ```sh 540 | 数值元算主要有4种实现方式:(())、let、expr、bc。 541 | 工作效率:(()) == let > expr > bc** 542 | (())和let是bash内建命令,执行效率高;而expr和bc是系统命令,会消耗内存,执行效率低。 543 | (())、let和expr只支持整数运算,不支持浮点运算;而bc支持浮点运算。 544 | ``` 545 | 546 | [数值运算][4] 547 | 实例1:用4中方式实现`3*(5+2)` 548 | 549 | ```sh 550 | #!/bin/bash 551 | 552 | # (()) 553 | val1=$((3*(5+2))) 554 | echo "val1=$val1" 555 | 556 | # let 557 | let "val2=3*(5+2)" 558 | echo "val2=$val2" 559 | 560 | # expr 561 | val3=`expr 3 \* \(5+2\)` 562 | echo "val3=$val3" 563 | 564 | # bc 565 | val4=`echo "3*(5+2)"|bc` 566 | echo "val4=$val4" 567 | 568 | exit 0 569 | ``` 570 | 571 | 实例3:5/3浮点运算,保留3位小数 572 | 573 | ```sh 574 | #!/bin/bash 575 | 576 | # bc 实现5/3浮点运算,保留3位小数 577 | val5=`echo "scale=3; 5/3"|bc` 578 | echo "val5=$val5" 579 | 580 | exit 0 581 | ``` 582 | 583 | ## 七. 字符运算 584 | 585 | [字符运算][5] 586 | 587 | ```sh 588 | #!/bin/bash 589 | 590 | str='hello world' 591 | 592 | # 显示字符串 593 | echo '显示字符串' 594 | echo ${str} 595 | 596 | # 显示字符串长度 597 | echo '显示字符串长度' 598 | echo ${#str} 599 | 600 | # 提取world 601 | echo '提取world' 602 | echo ${str:6} 603 | 604 | # 提取or 605 | echo '提取or' 606 | echo ${str:7:2} 607 | 608 | # 删除hello 609 | echo '删除hello' 610 | echo ${str#hello} 611 | 612 | # 删除world 613 | echo '删除world' 614 | echo ${str%world} 615 | 616 | # 将所有的字符l替换为m 617 | echo '将所有的字符l替换为m' 618 | echo ${str//l/m} 619 | 620 | exit 0 621 | ``` 622 | 623 | ## 八. bash调试 624 | 625 | ### bash [-nvx] scripts.sh 626 | 627 | ```sh 628 | 选项与参数: 629 | -n: 不要执行 script,仅查询语法的问题; 630 | -v: 再执行 sccript 前,先将 scripts 的内容输出到屏幕上; 631 | -x: 将使用到的 script 内容显示到屏幕上,这是很有用的参数! 632 | ``` 633 | 634 | 例子:想要执行bash脚本,并查看bash的调用流程,可以通过以下命令: 635 | 636 | `bash -x test.sh` 637 | 638 | ### echo [-neE] string 639 | 640 | ```sh 641 | 选项与参数: 642 | -n: 输出内容之后,不换行。默认是输入内容之后,换行。 643 | -e: 开启反斜线“\”转义功能 644 | -E: 开启反斜线“\”转义功能(默认)。 645 | ``` 646 | 647 | 例子:输出please input a number:之后不换行 648 | 649 | `echo -n "please input a number:"` 650 | 651 | ## 九. bash内建指令 652 | 653 | ### echo 654 | 655 | 在屏幕上显示出指定的字串 656 | 657 | ### read 658 | 659 | 从标准输入设备读入一行,分解成若干字,赋值给bash程序内部定义的变量 660 | 661 | ### alias 662 | 663 | 别名,`alias l='ls -al'` 664 | 665 | ### export 666 | 667 | export可以把bash的变量向下带入子bash(即子bash中可以使用父bash的变量),从而让子进程继承父进程中的环境变量。但子bash不能用export把它的变量向上带入父bash。 668 | 669 | ### exec 670 | 671 | 当bash执行到exec语句时,不会去创建新的子进程,而是转去执行指定的命令,当指定的命令执行完时,该进程(也就是最初的bash)就终止了,所以bash程序中exec后面的语句将不再被执行。 672 | 673 | ### . 674 | 675 | 使bash读入指定的bash程序文件并依次执行文件中的所有语句。 676 | 677 | ### exit 678 | 679 | 退出Shell程序,在exit之后可有选择地指定一个数位作为返回状态。 680 | 681 | ## 十. 参考资料 682 | 683 | 后语:大家觉得有用的话,star一下,然后可以随意分享给需要的人,重点是加颗星星哦,加颗星星哦,加颗星星哦。 684 | 685 | - [Linux bash总结(一) 基础部分(适合初学者学习和非初学者参考)][6] 686 | - [bash-guide][7] 687 | - [ssr.sh][8] 688 | - [Markdown-TOC][9] 689 | 690 | ## 十一. 大BOSS 691 | 692 | [大BOSS][10] 693 | 694 | [1]:./linux-user-group-file.md 695 | [2]:./dir/array.sh 696 | [3]:./dir/function.sh 697 | [4]:./dir/operation.sh 698 | [5]:./dir/string.sh 699 | [6]:http://www.cnblogs.com/skywang12345/archive/2013/05/30/3106570.html 700 | [7]:https://github.com/Idnan/bash-guide 701 | [8]:https://doub.bid/ss-jc42/ 702 | [9]:https://github.com/AlanWalk/Markdown-TOC 703 | [10]:./ssr.sh -------------------------------------------------------------------------------- /dir/array.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | array=(10 20 30 40 50) 4 | 5 | # 显示数组中所有元素 6 | echo '显示数组中所有元素' 7 | echo ${array[*]} 8 | echo ${array[@]} 9 | 10 | # 显示数组第2项 11 | echo '显示数组第2项' 12 | echo ${array[1]} 13 | 14 | # 显示数组长度 15 | echo '显示数组长度' 16 | echo ${#array[@]} 17 | 18 | # 输出数组的第1-3项 19 | echo '输出数组的第1-3项' 20 | echo ${array[@]:0:3} 21 | 22 | # 将数组中的0替换成1 23 | echo '将数组中的0替换成1' 24 | echo ${array[@]/0/1} 25 | 26 | # 删除数组第2项元素 27 | # 说明: 28 | # unset仅仅只清除array[1]的值,并没有将array[1]删除掉 29 | echo '删除数组第2项元素' 30 | unset array[1] 31 | echo ${array[@]} 32 | 33 | exit 0 -------------------------------------------------------------------------------- /dir/break.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 设置起始值为0 4 | val=0 5 | 6 | while true 7 | do 8 | if [ "$val" -eq "5" ];then 9 | # 如果val=5,则跳出循环 10 | break; 11 | else 12 | # 输出数值 13 | echo "val=$val" 14 | # 将数值加1 15 | ((val++)) 16 | fi 17 | done 18 | 19 | exit 0 -------------------------------------------------------------------------------- /dir/case.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -n "你单身吗?(y/n)" 4 | 5 | read val 6 | 7 | case $val in 8 | Y|y) 9 | echo "我们约起来吧" 10 | ;; 11 | N|n) 12 | echo "不约,再见" 13 | ;; 14 | *) 15 | echo "输入有误" 16 | ;; 17 | esac 18 | 19 | exit 0 -------------------------------------------------------------------------------- /dir/continue.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 设置起始值为0 4 | val=0 5 | 6 | while [ "$val" -le "10" ] 7 | do 8 | if [ "$val" -eq "5" ];then 9 | # 如果val=5,则将数值加2 10 | ((val=$val+2)) 11 | continue; 12 | else 13 | # 输出数值 14 | echo "val=$val" 15 | # 将数值加1 16 | ((val++)) 17 | fi 18 | done 19 | 20 | exit 0 -------------------------------------------------------------------------------- /dir/for.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 将ls的结果保存到变量CUR_DIR中 4 | CUR_DIR=`ls` 5 | 6 | # 显示ls的结果 7 | echo $CUR_DIR 8 | 9 | for val in $CUR_DIR 10 | do 11 | if [ -f $val ];then 12 | echo "FILE: $val" 13 | fi 14 | done 15 | 16 | exit 0 -------------------------------------------------------------------------------- /dir/function.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 编辑一个函数foo:打印foo的输入参数的总数,并输入每个参数和参数对应的序号。 4 | function foo() 5 | { 6 | # 定义局部变量i 7 | local i=0 8 | # 定义局部变量total=传入foo的参数总数 9 | local total=$# 10 | # 输出参数总数 11 | echo "total param =$total" 12 | # 输出传入foo的每一个参数 13 | for val in $@ 14 | do 15 | ((i++)) 16 | echo "$i -- val=$val" 17 | done 18 | 19 | # 返回参数总数 20 | return $total 21 | } 22 | 23 | foo 24 | foo param1 param2 param3 25 | # 输出foo param1 param2 param3的返回值 26 | echo "return value=$?" 27 | 28 | exit 0 29 | -------------------------------------------------------------------------------- /dir/hello.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php 2 | getLine()}: " . htmlSpecialChars($e->getMessage()); 20 | die(); 21 | }); 22 | 23 | $rawPost = NULL; 24 | if ($hookSecret !== NULL) { 25 | if (!isset($_SERVER['HTTP_X_HUB_SIGNATURE'])) { 26 | throw new \Exception("HTTP header 'X-Hub-Signature' is missing."); 27 | } elseif (!extension_loaded('hash')) { 28 | throw new \Exception("Missing 'hash' extension to check the secret code validity."); 29 | } 30 | 31 | list($algo, $hash) = explode('=', $_SERVER['HTTP_X_HUB_SIGNATURE'], 2) + array('', ''); 32 | if (!in_array($algo, hash_algos(), TRUE)) { 33 | throw new \Exception("Hash algorithm '$algo' is not supported."); 34 | } 35 | 36 | $rawPost = file_get_contents('php://input'); 37 | if ($hash !== hash_hmac($algo, $rawPost, $hookSecret)) { 38 | throw new \Exception('Hook secret does not match.'); 39 | } 40 | }; 41 | 42 | if (!isset($_SERVER['HTTP_CONTENT_TYPE'])) { 43 | throw new \Exception("Missing HTTP 'Content-Type' header."); 44 | } elseif (!isset($_SERVER['HTTP_X_GITHUB_EVENT'])) { 45 | throw new \Exception("Missing HTTP 'X-Github-Event' header."); 46 | } 47 | 48 | switch ($_SERVER['HTTP_CONTENT_TYPE']) { 49 | case 'application/json': 50 | $json = $rawPost ?: file_get_contents('php://input'); 51 | break; 52 | 53 | case 'application/x-www-form-urlencoded': 54 | $json = $_POST['payload']; 55 | break; 56 | 57 | default: 58 | throw new \Exception("Unsupported content type: $_SERVER[HTTP_CONTENT_TYPE]"); 59 | } 60 | 61 | # Payload structure depends on triggered event 62 | # https://developer.github.com/v3/activity/events/types/ 63 | $payload = json_decode($json); 64 | 65 | switch (strtolower($_SERVER['HTTP_X_GITHUB_EVENT'])) { 66 | case 'ping': 67 | echo 'pong'; 68 | break; 69 | 70 | // case 'push': 71 | // break; 72 | 73 | // case 'create': 74 | // break; 75 | 76 | default: 77 | header('HTTP/1.0 404 Not Found'); 78 | echo "Event:$_SERVER[HTTP_X_GITHUB_EVENT] Payload:\n"; 79 | print_r($payload); # For debug only. Can be found in GitHub hook log. 80 | die(); 81 | } -------------------------------------------------------------------------------- /linux-user-group-file.md: -------------------------------------------------------------------------------- 1 | # linux 中用户、组、文件 2 | 3 | 前言:在linux中一切都是文件 4 | 5 | 由于修改文本文件如此简单,Linux系统本身肯定要加以规范。这就引出了用户(组)和权限这2个概念。 6 | 7 | > 由于一切皆为文件。所以Linux 引入了2个文件来管理用户(组), /etc/passwd存放用户,/etc/group存放组, 然后在文件系统中的每个文件的文件头里面添加了用户和文件之间的关系信息。 8 | 9 | ```sh 10 | 用户和文件的关系只有2种, 拥有和不拥有。 11 | 组和文件的关系只有2种,拥有和不拥有 12 | 用户和组的关系只有2种, 属于和不属于 13 | ``` 14 | 15 | 将这三种关系叠加,用户和文件的最终关系可以归纳为3类 16 | 17 | ```sh 18 | 1,用户拥有该文件 19 | 2,用户属于某个组, 某个组拥有该文件(即用户通过属于某组来拥有该文件) 20 | 3,用户不拥有该文件 21 | ``` 22 | 23 | 下面要说明一下权限。 24 | 25 | > 权限一共有三种读4(缩写为r),写2(缩写为w),执行1(缩写为x) 26 | 27 | 读(缩写为r):查看 28 | 写(缩写为w):修改 29 | 执行(缩写为x):运行 30 | 31 | ```sh 32 | - rw- rw- r-- 1 root root 451 10月 31 2016 default.conf 33 | - 文件类型,我们这里不需要关注 34 | rw- 用户(缩写为u)的权限 35 | rw- 组(缩写为g)的权限 36 | r-- 其他用户(缩写为o)的权限 37 | 38 | 用户root可以读+写 default.conf 39 | 组root 可以读+写 default.conf 40 | 41 | 按照前面我们说的,比如shengj用户属于root组,那么它就拥有组root的所有权限,可以读+写default.conf 42 | 43 | ``` 44 | 45 | 修改权限 46 | 47 | ```sh 48 | chmod g+x default.conf 给default.conf的组加上执行x权限 49 | chmod g-x default.conf 给default.conf的组减去执行x权限 50 | 51 | ``` 52 | 53 | 用户操作 54 | 55 | ```sh 56 | 1. 增加用户 57 | # 新增 58 | useradd shengj 59 | # 设置密码 60 | passwd shengj 61 | # 配置sudo权限 62 | vim /etc/sudoers 63 | 找到 root ALL=(ALL) ALL 64 | 在下面加条 shengj ALL=(ALL) ALL 65 | 66 | 2. 修改用户 67 | # 将shengj用户的登录目录改成/home/shengj,并加入root组。 68 | usermod -d /home/shengj -G root shengj 69 | # 将用户shengj加入到root组 70 | gpasswd -a shengj root 71 | # 将用户shengj从root组中移出 72 | gpasswd -d shengj root 73 | 74 | 3. 删除用户 75 | userdel shengj 76 | 77 | 4. 查看用户 78 | # 查看当前登录用户 79 | w 80 | who 81 | # 查看当前登录用户 82 | whoami 83 | # 查看单个用户信息 84 | finger shengj 85 | id shengj 86 | # 查看用户登录记录 87 | 查看登录成功的用户记录 88 | last 89 | 查看登录不成功的用户记录 90 | lastb 91 | # 查看所有用户 92 | cut -d : -f 1 /etc/passwd 93 | cat /etc/passwd |awk -F \: '{print $1}' 94 | ``` 95 | 96 | 组操作 97 | 98 | ```sh 99 | 1. 创建组 100 | groupadd shengj 101 | 102 | 2,修改组 103 | groupmod -n shengj2 shengj 104 | 将shengj组的名字改成shengj2 105 | 106 | 3,删除组 107 | groupdel shengj 108 | 109 | 4,查看组 110 | # 查看当前登录用户所在的组groups 111 | groups shengj 112 | 113 | # 查看所有组 114 | cat /etc/group 115 | 116 | # 有的linux系统没有/etc/group文件的,这个时候看下面的这个方法 117 | cat /etc/passwd |awk -F [:] '{print $4}' |sort|uniq | getent group |awk -F [:] '{print $1}' 118 | 这里用到一个命令是getent,可以通过组ID来查找组信息,如果这个命令没有的话,那就很难查找,系统中所有的组了. 119 | ``` 120 | -------------------------------------------------------------------------------- /ssr.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 3 | export PATH 4 | 5 | #================================================= 6 | # System Required: CentOS 6+/Debian 6+/Ubuntu 14.04+ 7 | # Description: Install the ShadowsocksR server 8 | # Version: 2.0.30 9 | # Author: Toyo 10 | # Blog: https://doub.io/ss-jc42/ 11 | #================================================= 12 | 13 | sh_ver="2.0.30" 14 | filepath=$(cd "$(dirname "$0")"; pwd) 15 | file=$(echo -e "${filepath}"|awk -F "$0" '{print $1}') 16 | ssr_folder="/usr/local/shadowsocksr" 17 | ssr_ss_file="${ssr_folder}/shadowsocks" 18 | config_file="${ssr_folder}/config.json" 19 | config_folder="/etc/shadowsocksr" 20 | config_user_file="${config_folder}/user-config.json" 21 | ssr_log_file="${ssr_ss_file}/ssserver.log" 22 | Libsodiumr_file="/usr/local/lib/libsodium.so" 23 | Libsodiumr_ver_backup="1.0.13" 24 | Server_Speeder_file="/serverspeeder/bin/serverSpeeder.sh" 25 | LotServer_file="/appex/bin/serverSpeeder.sh" 26 | BBR_file="${file}/bbr.sh" 27 | jq_file="${ssr_folder}/jq" 28 | Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m" 29 | Info="${Green_font_prefix}[信息]${Font_color_suffix}" 30 | Error="${Red_font_prefix}[错误]${Font_color_suffix}" 31 | Tip="${Green_font_prefix}[注意]${Font_color_suffix}" 32 | Separator_1="——————————————————————————————" 33 | 34 | check_root(){ 35 | [[ $EUID != 0 ]] && echo -e "${Error} 当前账号非ROOT(或没有ROOT权限),无法继续操作,请使用${Green_background_prefix} sudo su ${Font_color_suffix}来获取临时ROOT权限(执行后会提示输入当前账号的密码)。" && exit 1 36 | } 37 | check_sys(){ 38 | if [[ -f /etc/redhat-release ]]; then 39 | release="centos" 40 | elif cat /etc/issue | grep -q -E -i "debian"; then 41 | release="debian" 42 | elif cat /etc/issue | grep -q -E -i "ubuntu"; then 43 | release="ubuntu" 44 | elif cat /etc/issue | grep -q -E -i "centos|red hat|redhat"; then 45 | release="centos" 46 | elif cat /proc/version | grep -q -E -i "debian"; then 47 | release="debian" 48 | elif cat /proc/version | grep -q -E -i "ubuntu"; then 49 | release="ubuntu" 50 | elif cat /proc/version | grep -q -E -i "centos|red hat|redhat"; then 51 | release="centos" 52 | fi 53 | bit=`uname -m` 54 | } 55 | check_pid(){ 56 | PID=`ps -ef |grep -v grep | grep server.py |awk '{print $2}'` 57 | } 58 | SSR_installation_status(){ 59 | [[ ! -e ${config_user_file} ]] && echo -e "${Error} 没有发现 ShadowsocksR 配置文件,请检查 !" && exit 1 60 | [[ ! -e ${ssr_folder} ]] && echo -e "${Error} 没有发现 ShadowsocksR 文件夹,请检查 !" && exit 1 61 | } 62 | Server_Speeder_installation_status(){ 63 | [[ ! -e ${Server_Speeder_file} ]] && echo -e "${Error} 没有安装 锐速(Server Speeder),请检查 !" && exit 1 64 | } 65 | LotServer_installation_status(){ 66 | [[ ! -e ${LotServer_file} ]] && echo -e "${Error} 没有安装 LotServer,请检查 !" && exit 1 67 | } 68 | BBR_installation_status(){ 69 | if [[ ! -e ${BBR_file} ]]; then 70 | echo -e "${Error} 没有发现 BBR脚本,开始下载..." 71 | cd "${file}" 72 | if ! wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/bbr.sh; then 73 | echo -e "${Error} BBR 脚本下载失败 !" && exit 1 74 | else 75 | echo -e "${Info} BBR 脚本下载完成 !" 76 | chmod +x bbr.sh 77 | fi 78 | fi 79 | } 80 | # 设置 防火墙规则 81 | Add_iptables(){ 82 | iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport ${ssr_port} -j ACCEPT 83 | iptables -I INPUT -m state --state NEW -m udp -p udp --dport ${ssr_port} -j ACCEPT 84 | } 85 | Del_iptables(){ 86 | iptables -D INPUT -m state --state NEW -m tcp -p tcp --dport ${port} -j ACCEPT 87 | iptables -D INPUT -m state --state NEW -m udp -p udp --dport ${port} -j ACCEPT 88 | } 89 | Save_iptables(){ 90 | if [[ ${release} == "centos" ]]; then 91 | service iptables save 92 | else 93 | iptables-save > /etc/iptables.up.rules 94 | fi 95 | } 96 | Set_iptables(){ 97 | if [[ ${release} == "centos" ]]; then 98 | service iptables save 99 | chkconfig --level 2345 iptables on 100 | elif [[ ${release} == "debian" ]]; then 101 | iptables-save > /etc/iptables.up.rules 102 | echo -e '#!/bin/bash\n/sbin/iptables-restore < /etc/iptables.up.rules' > /etc/network/if-pre-up.d/iptables 103 | chmod +x /etc/network/if-pre-up.d/iptables 104 | elif [[ ${release} == "ubuntu" ]]; then 105 | iptables-save > /etc/iptables.up.rules 106 | echo -e '\npre-up iptables-restore < /etc/iptables.up.rules\npost-down iptables-save > /etc/iptables.up.rules' >> /etc/network/interfaces 107 | chmod +x /etc/network/interfaces 108 | fi 109 | } 110 | # 读取 配置信息 111 | Get_IP(){ 112 | ip=$(wget -qO- -t1 -T2 ipinfo.io/ip) 113 | if [[ -z "${ip}" ]]; then 114 | ip=$(wget -qO- -t1 -T2 api.ip.sb/ip) 115 | if [[ -z "${ip}" ]]; then 116 | ip=$(wget -qO- -t1 -T2 members.3322.org/dyndns/getip) 117 | if [[ -z "${ip}" ]]; then 118 | ip="VPS_IP" 119 | fi 120 | fi 121 | fi 122 | } 123 | Get_User(){ 124 | [[ ! -e ${jq_file} ]] && echo -e "${Error} JQ解析器 不存在,请检查 !" && exit 1 125 | port=`${jq_file} '.server_port' ${config_user_file}` 126 | password=`${jq_file} '.password' ${config_user_file} | sed 's/^.//;s/.$//'` 127 | method=`${jq_file} '.method' ${config_user_file} | sed 's/^.//;s/.$//'` 128 | protocol=`${jq_file} '.protocol' ${config_user_file} | sed 's/^.//;s/.$//'` 129 | obfs=`${jq_file} '.obfs' ${config_user_file} | sed 's/^.//;s/.$//'` 130 | protocol_param=`${jq_file} '.protocol_param' ${config_user_file} | sed 's/^.//;s/.$//'` 131 | speed_limit_per_con=`${jq_file} '.speed_limit_per_con' ${config_user_file}` 132 | speed_limit_per_user=`${jq_file} '.speed_limit_per_user' ${config_user_file}` 133 | connect_verbose_info=`${jq_file} '.connect_verbose_info' ${config_user_file}` 134 | } 135 | urlsafe_base64(){ 136 | date=$(echo -n "$1"|base64|sed ':a;N;s/\n/ /g;ta'|sed 's/ //g;s/=//g;s/+/-/g;s/\//_/g') 137 | echo -e "${date}" 138 | } 139 | ss_link_qr(){ 140 | SSbase64=$(urlsafe_base64 "${method}:${password}@${ip}:${port}") 141 | SSurl="ss://${SSbase64}" 142 | SSQRcode="http://doub.pw/qr/qr.php?text=${SSurl}" 143 | ss_link=" SS 链接 : ${Green_font_prefix}${SSurl}${Font_color_suffix} \n SS 二维码 : ${Green_font_prefix}${SSQRcode}${Font_color_suffix}" 144 | } 145 | ssr_link_qr(){ 146 | SSRprotocol=$(echo ${protocol} | sed 's/_compatible//g') 147 | SSRobfs=$(echo ${obfs} | sed 's/_compatible//g') 148 | SSRPWDbase64=$(urlsafe_base64 "${password}") 149 | SSRbase64=$(urlsafe_base64 "${ip}:${port}:${SSRprotocol}:${method}:${SSRobfs}:${SSRPWDbase64}") 150 | SSRurl="ssr://${SSRbase64}" 151 | SSRQRcode="http://doub.pw/qr/qr.php?text=${SSRurl}" 152 | ssr_link=" SSR 链接 : ${Red_font_prefix}${SSRurl}${Font_color_suffix} \n SSR 二维码 : ${Red_font_prefix}${SSRQRcode}${Font_color_suffix} \n " 153 | } 154 | ss_ssr_determine(){ 155 | protocol_suffix=`echo ${protocol} | awk -F "_" '{print $NF}'` 156 | obfs_suffix=`echo ${obfs} | awk -F "_" '{print $NF}'` 157 | if [[ ${protocol} = "origin" ]]; then 158 | if [[ ${obfs} = "plain" ]]; then 159 | ss_link_qr 160 | ssr_link="" 161 | else 162 | if [[ ${obfs_suffix} != "compatible" ]]; then 163 | ss_link="" 164 | else 165 | ss_link_qr 166 | fi 167 | fi 168 | else 169 | if [[ ${protocol_suffix} != "compatible" ]]; then 170 | ss_link="" 171 | else 172 | if [[ ${obfs_suffix} != "compatible" ]]; then 173 | if [[ ${obfs_suffix} = "plain" ]]; then 174 | ss_link_qr 175 | else 176 | ss_link="" 177 | fi 178 | else 179 | ss_link_qr 180 | fi 181 | fi 182 | fi 183 | ssr_link_qr 184 | } 185 | # 显示 配置信息 186 | View_User(){ 187 | SSR_installation_status 188 | Get_IP 189 | Get_User 190 | now_mode=$(cat "${config_user_file}"|grep '"port_password"') 191 | [[ -z ${protocol_param} ]] && protocol_param="0(无限)" 192 | if [[ -z "${now_mode}" ]]; then 193 | ss_ssr_determine 194 | clear && echo "===================================================" && echo 195 | echo -e " ShadowsocksR账号 配置信息:" && echo 196 | echo -e " I P\t : ${Green_font_prefix}${ip}${Font_color_suffix}" 197 | echo -e " 端口\t : ${Green_font_prefix}${port}${Font_color_suffix}" 198 | echo -e " 密码\t : ${Green_font_prefix}${password}${Font_color_suffix}" 199 | echo -e " 加密\t : ${Green_font_prefix}${method}${Font_color_suffix}" 200 | echo -e " 协议\t : ${Red_font_prefix}${protocol}${Font_color_suffix}" 201 | echo -e " 混淆\t : ${Red_font_prefix}${obfs}${Font_color_suffix}" 202 | echo -e " 设备数限制 : ${Green_font_prefix}${protocol_param}${Font_color_suffix}" 203 | echo -e " 单线程限速 : ${Green_font_prefix}${speed_limit_per_con} KB/S${Font_color_suffix}" 204 | echo -e " 端口总限速 : ${Green_font_prefix}${speed_limit_per_user} KB/S${Font_color_suffix}" 205 | echo -e "${ss_link}" 206 | echo -e "${ssr_link}" 207 | echo -e " ${Green_font_prefix} 提示: ${Font_color_suffix} 208 | 在浏览器中,打开二维码链接,就可以看到二维码图片。 209 | 协议和混淆后面的[ _compatible ],指的是 兼容原版协议/混淆。" 210 | echo && echo "===================================================" 211 | else 212 | user_total=`${jq_file} '.port_password' ${config_user_file} | sed '$d' | sed "1d" | wc -l` 213 | [[ ${user_total} = "0" ]] && echo -e "${Error} 没有发现 多端口用户,请检查 !" && exit 1 214 | clear && echo "===================================================" && echo 215 | echo -e " ShadowsocksR账号 配置信息:" && echo 216 | echo -e " I P\t : ${Green_font_prefix}${ip}${Font_color_suffix}" 217 | echo -e " 加密\t : ${Green_font_prefix}${method}${Font_color_suffix}" 218 | echo -e " 协议\t : ${Red_font_prefix}${protocol}${Font_color_suffix}" 219 | echo -e " 混淆\t : ${Red_font_prefix}${obfs}${Font_color_suffix}" 220 | echo -e " 设备数限制 : ${Green_font_prefix}${protocol_param}${Font_color_suffix}" 221 | echo -e " 单线程限速 : ${Green_font_prefix}${speed_limit_per_con} KB/S${Font_color_suffix}" 222 | echo -e " 端口总限速 : ${Green_font_prefix}${speed_limit_per_user} KB/S${Font_color_suffix}" && echo 223 | for((integer = ${user_total}; integer >= 1; integer--)) 224 | do 225 | port=`${jq_file} '.port_password' ${config_user_file} | sed '$d' | sed "1d" | awk -F ":" '{print $1}' | sed -n "${integer}p" | sed -r 's/.*\"(.+)\".*/\1/'` 226 | password=`${jq_file} '.port_password' ${config_user_file} | sed '$d' | sed "1d" | awk -F ":" '{print $2}' | sed -n "${integer}p" | sed -r 's/.*\"(.+)\".*/\1/'` 227 | ss_ssr_determine 228 | echo -e ${Separator_1} 229 | echo -e " 端口\t : ${Green_font_prefix}${port}${Font_color_suffix}" 230 | echo -e " 密码\t : ${Green_font_prefix}${password}${Font_color_suffix}" 231 | echo -e "${ss_link}" 232 | echo -e "${ssr_link}" 233 | done 234 | echo -e " ${Green_font_prefix} 提示: ${Font_color_suffix} 235 | 在浏览器中,打开二维码链接,就可以看到二维码图片。 236 | 协议和混淆后面的[ _compatible ],指的是 兼容原版协议/混淆。" 237 | echo && echo "===================================================" 238 | fi 239 | } 240 | # 设置 配置信息 241 | Set_config_port(){ 242 | while true 243 | do 244 | echo -e "请输入要设置的ShadowsocksR账号 端口" 245 | stty erase '^H' && read -p "(默认: 2333):" ssr_port 246 | [[ -z "$ssr_port" ]] && ssr_port="2333" 247 | expr ${ssr_port} + 0 &>/dev/null 248 | if [[ $? == 0 ]]; then 249 | if [[ ${ssr_port} -ge 1 ]] && [[ ${ssr_port} -le 65535 ]]; then 250 | echo && echo ${Separator_1} && echo -e " 端口 : ${Green_font_prefix}${ssr_port}${Font_color_suffix}" && echo ${Separator_1} && echo 251 | break 252 | else 253 | echo -e "${Error} 请输入正确的数字(1-65535)" 254 | fi 255 | else 256 | echo -e "${Error} 请输入正确的数字(1-65535)" 257 | fi 258 | done 259 | } 260 | Set_config_password(){ 261 | echo "请输入要设置的ShadowsocksR账号 密码" 262 | stty erase '^H' && read -p "(默认: doub.io):" ssr_password 263 | [[ -z "${ssr_password}" ]] && ssr_password="doub.io" 264 | echo && echo ${Separator_1} && echo -e " 密码 : ${Green_font_prefix}${ssr_password}${Font_color_suffix}" && echo ${Separator_1} && echo 265 | } 266 | Set_config_method(){ 267 | echo -e "请选择要设置的ShadowsocksR账号 加密方式 268 | ${Green_font_prefix} 1.${Font_color_suffix} none 269 | ${Tip} 如果使用 auth_chain_a 协议,请加密方式选择 none,混淆随意(建议 plain) 270 | 271 | ${Green_font_prefix} 2.${Font_color_suffix} rc4 272 | ${Green_font_prefix} 3.${Font_color_suffix} rc4-md5 273 | ${Green_font_prefix} 4.${Font_color_suffix} rc4-md5-6 274 | 275 | ${Green_font_prefix} 5.${Font_color_suffix} aes-128-ctr 276 | ${Green_font_prefix} 6.${Font_color_suffix} aes-192-ctr 277 | ${Green_font_prefix} 7.${Font_color_suffix} aes-256-ctr 278 | 279 | ${Green_font_prefix} 8.${Font_color_suffix} aes-128-cfb 280 | ${Green_font_prefix} 9.${Font_color_suffix} aes-192-cfb 281 | ${Green_font_prefix}10.${Font_color_suffix} aes-256-cfb 282 | 283 | ${Green_font_prefix}11.${Font_color_suffix} aes-128-cfb8 284 | ${Green_font_prefix}12.${Font_color_suffix} aes-192-cfb8 285 | ${Green_font_prefix}13.${Font_color_suffix} aes-256-cfb8 286 | 287 | ${Green_font_prefix}14.${Font_color_suffix} salsa20 288 | ${Green_font_prefix}15.${Font_color_suffix} chacha20 289 | ${Green_font_prefix}16.${Font_color_suffix} chacha20-ietf 290 | ${Tip} salsa20/chacha20-*系列加密方式,需要额外安装依赖 libsodium ,否则会无法启动ShadowsocksR !" && echo 291 | stty erase '^H' && read -p "(默认: 5. aes-128-ctr):" ssr_method 292 | [[ -z "${ssr_method}" ]] && ssr_method="5" 293 | if [[ ${ssr_method} == "1" ]]; then 294 | ssr_method="none" 295 | elif [[ ${ssr_method} == "2" ]]; then 296 | ssr_method="rc4" 297 | elif [[ ${ssr_method} == "3" ]]; then 298 | ssr_method="rc4-md5" 299 | elif [[ ${ssr_method} == "4" ]]; then 300 | ssr_method="rc4-md5-6" 301 | elif [[ ${ssr_method} == "5" ]]; then 302 | ssr_method="aes-128-ctr" 303 | elif [[ ${ssr_method} == "6" ]]; then 304 | ssr_method="aes-192-ctr" 305 | elif [[ ${ssr_method} == "7" ]]; then 306 | ssr_method="aes-256-ctr" 307 | elif [[ ${ssr_method} == "8" ]]; then 308 | ssr_method="aes-128-cfb" 309 | elif [[ ${ssr_method} == "9" ]]; then 310 | ssr_method="aes-192-cfb" 311 | elif [[ ${ssr_method} == "10" ]]; then 312 | ssr_method="aes-256-cfb" 313 | elif [[ ${ssr_method} == "11" ]]; then 314 | ssr_method="aes-128-cfb8" 315 | elif [[ ${ssr_method} == "12" ]]; then 316 | ssr_method="aes-192-cfb8" 317 | elif [[ ${ssr_method} == "13" ]]; then 318 | ssr_method="aes-256-cfb8" 319 | elif [[ ${ssr_method} == "14" ]]; then 320 | ssr_method="salsa20" 321 | elif [[ ${ssr_method} == "15" ]]; then 322 | ssr_method="chacha20" 323 | elif [[ ${ssr_method} == "16" ]]; then 324 | ssr_method="chacha20-ietf" 325 | else 326 | ssr_method="aes-128-ctr" 327 | fi 328 | echo && echo ${Separator_1} && echo -e " 加密 : ${Green_font_prefix}${ssr_method}${Font_color_suffix}" && echo ${Separator_1} && echo 329 | } 330 | Set_config_protocol(){ 331 | echo -e "请选择要设置的ShadowsocksR账号 协议插件 332 | ${Green_font_prefix}1.${Font_color_suffix} origin 333 | ${Green_font_prefix}2.${Font_color_suffix} auth_sha1_v4 334 | ${Green_font_prefix}3.${Font_color_suffix} auth_aes128_md5 335 | ${Green_font_prefix}4.${Font_color_suffix} auth_aes128_sha1 336 | ${Green_font_prefix}5.${Font_color_suffix} auth_chain_a 337 | ${Green_font_prefix}6.${Font_color_suffix} auth_chain_b 338 | ${Tip} 如果使用 auth_chain_a 协议,请加密方式选择 none,混淆随意(建议 plain)" && echo 339 | stty erase '^H' && read -p "(默认: 2. auth_sha1_v4):" ssr_protocol 340 | [[ -z "${ssr_protocol}" ]] && ssr_protocol="2" 341 | if [[ ${ssr_protocol} == "1" ]]; then 342 | ssr_protocol="origin" 343 | elif [[ ${ssr_protocol} == "2" ]]; then 344 | ssr_protocol="auth_sha1_v4" 345 | elif [[ ${ssr_protocol} == "3" ]]; then 346 | ssr_protocol="auth_aes128_md5" 347 | elif [[ ${ssr_protocol} == "4" ]]; then 348 | ssr_protocol="auth_aes128_sha1" 349 | elif [[ ${ssr_protocol} == "5" ]]; then 350 | ssr_protocol="auth_chain_a" 351 | elif [[ ${ssr_protocol} == "6" ]]; then 352 | ssr_protocol="auth_chain_b" 353 | else 354 | ssr_protocol="auth_sha1_v4" 355 | fi 356 | echo && echo ${Separator_1} && echo -e " 协议 : ${Green_font_prefix}${ssr_protocol}${Font_color_suffix}" && echo ${Separator_1} && echo 357 | if [[ ${ssr_protocol} != "origin" ]]; then 358 | if [[ ${ssr_protocol} == "auth_sha1_v4" ]]; then 359 | stty erase '^H' && read -p "是否设置 协议插件兼容原版(_compatible)?[Y/n]" ssr_protocol_yn 360 | [[ -z "${ssr_protocol_yn}" ]] && ssr_protocol_yn="y" 361 | [[ $ssr_protocol_yn == [Yy] ]] && ssr_protocol=${ssr_protocol}"_compatible" 362 | echo 363 | fi 364 | fi 365 | } 366 | Set_config_obfs(){ 367 | echo -e "请选择要设置的ShadowsocksR账号 混淆插件 368 | ${Green_font_prefix}1.${Font_color_suffix} plain 369 | ${Green_font_prefix}2.${Font_color_suffix} http_simple 370 | ${Green_font_prefix}3.${Font_color_suffix} http_post 371 | ${Green_font_prefix}4.${Font_color_suffix} random_head 372 | ${Green_font_prefix}5.${Font_color_suffix} tls1.2_ticket_auth 373 | ${Tip} 如果使用 ShadowsocksR 加速游戏,请选择 混淆兼容原版或 plain 混淆,然后客户端选择 plain,否则会增加延迟 !" && echo 374 | stty erase '^H' && read -p "(默认: 5. tls1.2_ticket_auth):" ssr_obfs 375 | [[ -z "${ssr_obfs}" ]] && ssr_obfs="5" 376 | if [[ ${ssr_obfs} == "1" ]]; then 377 | ssr_obfs="plain" 378 | elif [[ ${ssr_obfs} == "2" ]]; then 379 | ssr_obfs="http_simple" 380 | elif [[ ${ssr_obfs} == "3" ]]; then 381 | ssr_obfs="http_post" 382 | elif [[ ${ssr_obfs} == "4" ]]; then 383 | ssr_obfs="random_head" 384 | elif [[ ${ssr_obfs} == "5" ]]; then 385 | ssr_obfs="tls1.2_ticket_auth" 386 | else 387 | ssr_obfs="tls1.2_ticket_auth" 388 | fi 389 | echo && echo ${Separator_1} && echo -e " 混淆 : ${Green_font_prefix}${ssr_obfs}${Font_color_suffix}" && echo ${Separator_1} && echo 390 | if [[ ${ssr_obfs} != "plain" ]]; then 391 | stty erase '^H' && read -p "是否设置 混淆插件兼容原版(_compatible)?[Y/n]" ssr_obfs_yn 392 | [[ -z "${ssr_obfs_yn}" ]] && ssr_obfs_yn="y" 393 | [[ $ssr_obfs_yn == [Yy] ]] && ssr_obfs=${ssr_obfs}"_compatible" 394 | echo 395 | fi 396 | } 397 | Set_config_protocol_param(){ 398 | while true 399 | do 400 | echo -e "请输入要设置的ShadowsocksR账号 欲限制的设备数 (${Green_font_prefix} auth_* 系列协议 不兼容原版才有效 ${Font_color_suffix})" 401 | echo -e "${Tip} 设备数限制:每个端口同一时间能链接的客户端数量(多端口模式,每个端口都是独立计算),建议最少 2个。" 402 | stty erase '^H' && read -p "(默认: 无限):" ssr_protocol_param 403 | [[ -z "$ssr_protocol_param" ]] && ssr_protocol_param="" && echo && break 404 | expr ${ssr_protocol_param} + 0 &>/dev/null 405 | if [[ $? == 0 ]]; then 406 | if [[ ${ssr_protocol_param} -ge 1 ]] && [[ ${ssr_protocol_param} -le 9999 ]]; then 407 | echo && echo ${Separator_1} && echo -e " 设备数限制 : ${Green_font_prefix}${ssr_protocol_param}${Font_color_suffix}" && echo ${Separator_1} && echo 408 | break 409 | else 410 | echo -e "${Error} 请输入正确的数字(1-9999)" 411 | fi 412 | else 413 | echo -e "${Error} 请输入正确的数字(1-9999)" 414 | fi 415 | done 416 | } 417 | Set_config_speed_limit_per_con(){ 418 | while true 419 | do 420 | echo -e "请输入要设置的每个端口 单线程 限速上限(单位:KB/S)" 421 | echo -e "${Tip} 单线程限速:每个端口 单线程的限速上限,多线程即无效。" 422 | stty erase '^H' && read -p "(默认: 无限):" ssr_speed_limit_per_con 423 | [[ -z "$ssr_speed_limit_per_con" ]] && ssr_speed_limit_per_con=0 && echo && break 424 | expr ${ssr_speed_limit_per_con} + 0 &>/dev/null 425 | if [[ $? == 0 ]]; then 426 | if [[ ${ssr_speed_limit_per_con} -ge 1 ]] && [[ ${ssr_speed_limit_per_con} -le 131072 ]]; then 427 | echo && echo ${Separator_1} && echo -e " 单线程限速 : ${Green_font_prefix}${ssr_speed_limit_per_con} KB/S${Font_color_suffix}" && echo ${Separator_1} && echo 428 | break 429 | else 430 | echo -e "${Error} 请输入正确的数字(1-131072)" 431 | fi 432 | else 433 | echo -e "${Error} 请输入正确的数字(1-131072)" 434 | fi 435 | done 436 | } 437 | Set_config_speed_limit_per_user(){ 438 | while true 439 | do 440 | echo 441 | echo -e "请输入要设置的每个端口 总速度 限速上限(单位:KB/S)" 442 | echo -e "${Tip} 端口总限速:每个端口 总速度 限速上限,单个端口整体限速。" 443 | stty erase '^H' && read -p "(默认: 无限):" ssr_speed_limit_per_user 444 | [[ -z "$ssr_speed_limit_per_user" ]] && ssr_speed_limit_per_user=0 && echo && break 445 | expr ${ssr_speed_limit_per_user} + 0 &>/dev/null 446 | if [[ $? == 0 ]]; then 447 | if [[ ${ssr_speed_limit_per_user} -ge 1 ]] && [[ ${ssr_speed_limit_per_user} -le 131072 ]]; then 448 | echo && echo ${Separator_1} && echo -e " 端口总限速 : ${Green_font_prefix}${ssr_speed_limit_per_user} KB/S${Font_color_suffix}" && echo ${Separator_1} && echo 449 | break 450 | else 451 | echo -e "${Error} 请输入正确的数字(1-131072)" 452 | fi 453 | else 454 | echo -e "${Error} 请输入正确的数字(1-131072)" 455 | fi 456 | done 457 | } 458 | Set_config_all(){ 459 | Set_config_port 460 | Set_config_password 461 | Set_config_method 462 | Set_config_protocol 463 | Set_config_obfs 464 | Set_config_protocol_param 465 | Set_config_speed_limit_per_con 466 | Set_config_speed_limit_per_user 467 | } 468 | # 修改 配置信息 469 | Modify_config_port(){ 470 | sed -i 's/"server_port": '"$(echo ${port})"'/"server_port": '"$(echo ${ssr_port})"'/g' ${config_user_file} 471 | } 472 | Modify_config_password(){ 473 | sed -i 's/"password": "'"$(echo ${password})"'"/"password": "'"$(echo ${ssr_password})"'"/g' ${config_user_file} 474 | } 475 | Modify_config_method(){ 476 | sed -i 's/"method": "'"$(echo ${method})"'"/"method": "'"$(echo ${ssr_method})"'"/g' ${config_user_file} 477 | } 478 | Modify_config_protocol(){ 479 | sed -i 's/"protocol": "'"$(echo ${protocol})"'"/"protocol": "'"$(echo ${ssr_protocol})"'"/g' ${config_user_file} 480 | } 481 | Modify_config_obfs(){ 482 | sed -i 's/"obfs": "'"$(echo ${obfs})"'"/"obfs": "'"$(echo ${ssr_obfs})"'"/g' ${config_user_file} 483 | } 484 | Modify_config_protocol_param(){ 485 | sed -i 's/"protocol_param": "'"$(echo ${protocol_param})"'"/"protocol_param": "'"$(echo ${ssr_protocol_param})"'"/g' ${config_user_file} 486 | } 487 | Modify_config_speed_limit_per_con(){ 488 | sed -i 's/"speed_limit_per_con": '"$(echo ${speed_limit_per_con})"'/"speed_limit_per_con": '"$(echo ${ssr_speed_limit_per_con})"'/g' ${config_user_file} 489 | } 490 | Modify_config_speed_limit_per_user(){ 491 | sed -i 's/"speed_limit_per_user": '"$(echo ${speed_limit_per_user})"'/"speed_limit_per_user": '"$(echo ${ssr_speed_limit_per_user})"'/g' ${config_user_file} 492 | } 493 | Modify_config_connect_verbose_info(){ 494 | sed -i 's/"connect_verbose_info": '"$(echo ${connect_verbose_info})"'/"connect_verbose_info": '"$(echo ${ssr_connect_verbose_info})"'/g' ${config_user_file} 495 | } 496 | Modify_config_all(){ 497 | Modify_config_port 498 | Modify_config_password 499 | Modify_config_method 500 | Modify_config_protocol 501 | Modify_config_obfs 502 | Modify_config_protocol_param 503 | Modify_config_speed_limit_per_con 504 | Modify_config_speed_limit_per_user 505 | } 506 | Modify_config_port_many(){ 507 | sed -i 's/"'"$(echo ${port})"'":/"'"$(echo ${ssr_port})"'":/g' ${config_user_file} 508 | } 509 | Modify_config_password_many(){ 510 | sed -i 's/"'"$(echo ${password})"'"/"'"$(echo ${ssr_password})"'"/g' ${config_user_file} 511 | } 512 | # 写入 配置信息 513 | Write_configuration(){ 514 | cat > ${config_user_file}<<-EOF 515 | { 516 | "server": "0.0.0.0", 517 | "server_ipv6": "::", 518 | "server_port": ${ssr_port}, 519 | "local_address": "127.0.0.1", 520 | "local_port": 1080, 521 | 522 | "password": "${ssr_password}", 523 | "method": "${ssr_method}", 524 | "protocol": "${ssr_protocol}", 525 | "protocol_param": "${ssr_protocol_param}", 526 | "obfs": "${ssr_obfs}", 527 | "obfs_param": "", 528 | "speed_limit_per_con": ${ssr_speed_limit_per_con}, 529 | "speed_limit_per_user": ${ssr_speed_limit_per_user}, 530 | 531 | "additional_ports" : {}, 532 | "timeout": 120, 533 | "udp_timeout": 60, 534 | "dns_ipv6": false, 535 | "connect_verbose_info": 0, 536 | "redirect": "", 537 | "fast_open": false 538 | } 539 | EOF 540 | } 541 | Write_configuration_many(){ 542 | cat > ${config_user_file}<<-EOF 543 | { 544 | "server": "0.0.0.0", 545 | "server_ipv6": "::", 546 | "local_address": "127.0.0.1", 547 | "local_port": 1080, 548 | 549 | "port_password":{ 550 | "${ssr_port}":"${ssr_password}" 551 | }, 552 | "method": "${ssr_method}", 553 | "protocol": "${ssr_protocol}", 554 | "protocol_param": "${ssr_protocol_param}", 555 | "obfs": "${ssr_obfs}", 556 | "obfs_param": "", 557 | "speed_limit_per_con": ${ssr_speed_limit_per_con}, 558 | "speed_limit_per_user": ${ssr_speed_limit_per_user}, 559 | 560 | "additional_ports" : {}, 561 | "timeout": 120, 562 | "udp_timeout": 60, 563 | "dns_ipv6": false, 564 | "connect_verbose_info": 0, 565 | "redirect": "", 566 | "fast_open": false 567 | } 568 | EOF 569 | } 570 | Check_python(){ 571 | python_ver=`python -h` 572 | if [[ -z ${python_ver} ]]; then 573 | echo -e "${Info} 没有安装Python,开始安装..." 574 | if [[ ${release} == "centos" ]]; then 575 | yum install -y python 576 | else 577 | apt-get install -y python 578 | fi 579 | fi 580 | } 581 | Centos_yum(){ 582 | yum update 583 | cat /etc/redhat-release |grep 7\..*|grep -i centos>/dev/null 584 | if [[ $? = 0 ]]; then 585 | yum install -y vim git net-tools 586 | else 587 | yum install -y vim git 588 | fi 589 | } 590 | Debian_apt(){ 591 | apt-get update 592 | apt-get install -y vim git 593 | } 594 | # 下载 ShadowsocksR 595 | Download_SSR(){ 596 | cd "/usr/local" 597 | #git config --global http.sslVerify false 598 | env GIT_SSL_NO_VERIFY=true git clone -b manyuser https://github.com/ToyoDAdoubi/shadowsocksr.git 599 | [[ ! -e ${ssr_folder} ]] && echo -e "${Error} ShadowsocksR服务端 下载失败 !" && exit 1 600 | [[ -e ${config_folder} ]] && rm -rf ${config_folder} 601 | mkdir ${config_folder} 602 | [[ ! -e ${config_folder} ]] && echo -e "${Error} ShadowsocksR配置文件的文件夹 建立失败 !" && exit 1 603 | echo -e "${Info} ShadowsocksR服务端 下载完成 !" 604 | } 605 | Service_SSR(){ 606 | if [[ ${release} = "centos" ]]; then 607 | if ! wget --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/other/ssr_centos -O /etc/init.d/ssr; then 608 | echo -e "${Error} ShadowsocksR服务 管理脚本下载失败 !" && exit 1 609 | fi 610 | chmod +x /etc/init.d/ssr 611 | chkconfig --add ssr 612 | chkconfig ssr on 613 | else 614 | if ! wget --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/other/ssr_debian -O /etc/init.d/ssr; then 615 | echo -e "${Error} ShadowsocksR服务 管理脚本下载失败 !" && exit 1 616 | fi 617 | chmod +x /etc/init.d/ssr 618 | update-rc.d -f ssr defaults 619 | fi 620 | echo -e "${Info} ShadowsocksR服务 管理脚本下载完成 !" 621 | } 622 | # 安装 JQ解析器 623 | JQ_install(){ 624 | if [[ ! -e ${jq_file} ]]; then 625 | if [[ ${bit} = "x86_64" ]]; then 626 | wget --no-check-certificate "https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64" -O ${jq_file} 627 | else 628 | wget --no-check-certificate "https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux32" -O ${jq_file} 629 | fi 630 | [[ ! -e ${jq_file} ]] && echo -e "${Error} JQ解析器 下载失败,请检查 !" && exit 1 631 | chmod +x ${jq_file} 632 | echo -e "${Info} JQ解析器 安装完成,继续..." 633 | else 634 | echo -e "${Info} JQ解析器 已安装,继续..." 635 | fi 636 | } 637 | # 安装 依赖 638 | Installation_dependency(){ 639 | if [[ ${release} == "centos" ]]; then 640 | Centos_yum 641 | else 642 | Debian_apt 643 | fi 644 | [[ ! -e "/usr/bin/git" ]] && echo -e "${Error} 依赖 Git 安装失败,多半是软件包源的问题,请检查 !" && exit 1 645 | Check_python 646 | #echo "nameserver 8.8.8.8" > /etc/resolv.conf 647 | #echo "nameserver 8.8.4.4" >> /etc/resolv.conf 648 | cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 649 | } 650 | Install_SSR(){ 651 | check_root 652 | [[ -e ${config_user_file} ]] && echo -e "${Error} ShadowsocksR 配置文件已存在,请检查( 如安装失败或者存在旧版本,请先卸载 ) !" && exit 1 653 | [[ -e ${ssr_folder} ]] && echo -e "${Error} ShadowsocksR 文件夹已存在,请检查( 如安装失败或者存在旧版本,请先卸载 ) !" && exit 1 654 | echo -e "${Info} 开始设置 ShadowsocksR账号配置..." 655 | Set_config_all 656 | echo -e "${Info} 开始安装/配置 ShadowsocksR依赖..." 657 | Installation_dependency 658 | echo -e "${Info} 开始下载/安装 ShadowsocksR文件..." 659 | Download_SSR 660 | echo -e "${Info} 开始下载/安装 ShadowsocksR服务脚本(init)..." 661 | Service_SSR 662 | echo -e "${Info} 开始下载/安装 JSNO解析器 JQ..." 663 | JQ_install 664 | echo -e "${Info} 开始写入 ShadowsocksR配置文件..." 665 | Write_configuration 666 | echo -e "${Info} 开始设置 iptables防火墙..." 667 | Set_iptables 668 | echo -e "${Info} 开始添加 iptables防火墙规则..." 669 | Add_iptables 670 | echo -e "${Info} 开始保存 iptables防火墙规则..." 671 | Save_iptables 672 | echo -e "${Info} 所有步骤 安装完毕,开始启动 ShadowsocksR服务端..." 673 | Start_SSR 674 | } 675 | Update_SSR(){ 676 | SSR_installation_status 677 | echo -e "因破娃暂停更新ShadowsocksR服务端,所以此功能临时禁用。" 678 | #cd ${ssr_folder} 679 | #git pull 680 | #Restart_SSR 681 | } 682 | Uninstall_SSR(){ 683 | [[ ! -e ${config_user_file} ]] && [[ ! -e ${ssr_folder} ]] && echo -e "${Error} 没有安装 ShadowsocksR,请检查 !" && exit 1 684 | echo "确定要 卸载ShadowsocksR?[y/N]" && echo 685 | stty erase '^H' && read -p "(默认: n):" unyn 686 | [[ -z ${unyn} ]] && unyn="n" 687 | if [[ ${unyn} == [Yy] ]]; then 688 | check_pid 689 | [[ ! -z "${PID}" ]] && kill -9 ${PID} 690 | if [[ -z "${now_mode}" ]]; then 691 | port=`${jq_file} '.server_port' ${config_user_file}` 692 | Del_iptables 693 | else 694 | user_total=`${jq_file} '.port_password' ${config_user_file} | sed '$d' | sed "1d" | wc -l` 695 | for((integer = 1; integer <= ${user_total}; integer++)) 696 | do 697 | port=`${jq_file} '.port_password' ${config_user_file} | sed '$d' | sed "1d" | awk -F ":" '{print $1}' | sed -n "${integer}p" | sed -r 's/.*\"(.+)\".*/\1/'` 698 | Del_iptables 699 | done 700 | fi 701 | if [[ ${release} = "centos" ]]; then 702 | chkconfig --del ssr 703 | else 704 | update-rc.d -f ssr remove 705 | fi 706 | rm -rf ${ssr_folder} && rm -rf ${config_folder} && rm -rf /etc/init.d/ssr 707 | echo && echo " ShadowsocksR 卸载完成 !" && echo 708 | else 709 | echo && echo " 卸载已取消..." && echo 710 | fi 711 | } 712 | Check_Libsodium_ver(){ 713 | echo -e "${Info} 开始获取 libsodium 最新版本..." 714 | Libsodiumr_ver=`wget -qO- https://github.com/jedisct1/libsodium/releases/latest | grep "