├── 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 | ![](./img/shell.jpg) 80 | 81 | ## 二. 命令行 82 | 83 | ### 1. 基本操作 84 | 85 | #### export 86 | 87 | 展示全部的环境变量,如果你想获取某个特殊的变量,用 `echo $变量名` 88 | ![](./img/export.jpg) 89 | ![](./img/echo.jpg) 90 | 91 | #### whatis 92 | 93 | 展示用户命令,系统调用、库函数等 94 | ![](./img/whatis.png) 95 | 96 | #### whereis 97 | 98 | 搜索可执行文件、源文件 99 | ![](./img/whereis.png) 100 | 101 | #### which 102 | 103 | 在环境变量中搜索可执行文件,并打印完整路径 104 | ![](./img/which.jpg) 105 | 106 | #### clear 107 | 108 | 清空屏幕 109 | ![](./img/clear.png) 110 | 111 | ### 2. 文件操作 112 | 113 | #### cat 114 | 115 | 在屏幕上显示文本文件 116 | ![](./img/cat.jpg) 117 | 118 | #### chmod 119 | 120 | 可以改变文件和目录的读、写、执行权限 121 | [linux 中的用户、组、文件][1] 122 | 123 | #### cp 124 | 125 | 复制文件 126 | ![](./img/copy.jpg) 127 | 128 | #### diff 129 | 130 | 比较文件,我在上面复制的文件中加了一行diff 131 | ![](./img/diff.jpg) 132 | 133 | #### find 134 | 135 | 查找文件,可以通过正则来查 136 | ![](./img/find.jpg) 137 | 138 | #### head 139 | 140 | 查看文件前10行 141 | ![](./img/head.jpg) 142 | 143 | #### ls 144 | 145 | 显示所有文件,`-l`显示长格式化 `-a`显示包括隐藏文件 146 | ![](./img/ls.jpg) 147 | 148 | #### mv 149 | 150 | 移动文件,同时也可以重命名文件 151 | ![](./img/mv.jpg) 152 | 153 | #### rm 154 | 155 | 删除文件,`-r`删除目录 `-f`强制删除 156 | ![](./img/rm.jpg) 157 | 158 | #### touch 159 | 160 | 创建新文件 161 | ![](./img/touch.jpg) 162 | 163 | ### 3. 文本操作 164 | 165 | #### awk 166 | 167 | 非常有用的一个文本处理命令,逐行运行,默认使用空格分割,`-F`表示分割的样式 168 | ![](./img/etc:passwd.jpg) 169 | ![](./img/awk.jpg) 170 | 171 | #### grep 172 | 173 | 匹配正则表达式的文本行,并输出,`-E`正则模糊匹配 `-F`精确字母匹配 `-w`精确单词匹配 174 | ![](./img/grep.jpg) 175 | ![](./img/grep_w.jpg) 176 | 177 | #### sed 178 | 179 | 正则替换 180 | ![](./img/sed.jpg) 181 | 182 | #### sort 183 | 184 | 排序 185 | ![](./img/sort.jpg) 186 | 187 | #### wc 188 | 189 | 统计文本行数,单词数,字符数 190 | ![](./img/wc.jpg) 191 | 192 | ### 4. 目录操作 193 | 194 | #### cd 195 | 196 | 进入目录 197 | 198 | #### mkdir 199 | 200 | 创建目录 201 | 202 | #### pwd 203 | 204 | 当前目录的路径 205 | ![](./img/mkdir.jpg) 206 | 207 | ### 5. SSH,系统信息,网络操作 208 | 209 | #### cal 210 | 211 | 月历 212 | ![](./img/cal.jpg) 213 | 214 | #### date 215 | 216 | 当前日期和时间 217 | ![](./img/date.jpg) 218 | 219 | #### df 220 | 221 | 磁盘使用情况 222 | 223 | #### du 224 | 225 | 文件或目录使用情况 226 | ![](./img/du.jpg) 227 | 228 | #### ps 229 | 230 | 列出你的进程 231 | ![](./img/ps.jpg) 232 | 233 | #### ssh 234 | 235 | 远程连接 236 | ![](./img/ssh.jpg) 237 | 238 | #### top 239 | 240 | 列出当然活动进程 241 | ![](./img/top.jpg) 242 | 243 | ## 三. 语法 244 | 245 | ### 1 条件判断 246 | 247 | #### 1.1 test判断语句 248 | 249 | test是关键字,表示判断;EXPRESSION是被判断的语句。 250 | 251 | ![](./img/testEx.jpg) 252 | 253 | `echo $?` 输出判断结果,0表示成功,其他表示失败。 254 | ![](./img/test.jpg) 255 | 256 | #### 1.2 []条件判断 257 | 258 | 中括号的左右扩弧和EXPRESSION之间都必须有空格! 259 | ![](./img/[1].jpg) 260 | 261 | 文件类型判断 262 | ![](./img/[2].jpg) 263 | 字符串和数字判断 264 | ![](./img/string-integer.jpg) 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 "" | sed -r 's/.*Release (.+) · jedisct1.*/\1/'` 715 | [[ -z ${Libsodiumr_ver} ]] && Libsodiumr_ver=${Libsodiumr_ver_backup} 716 | echo -e "${Info} libsodium 最新版本为 ${Green_font_prefix}${Libsodiumr_ver}${Font_color_suffix} !" 717 | } 718 | Install_Libsodium(){ 719 | [[ -e ${Libsodiumr_file} ]] && echo -e "${Error} libsodium 已安装 !" && exit 1 720 | echo -e "${Info} libsodium 未安装,开始安装..." 721 | Check_Libsodium_ver 722 | if [[ ${release} == "centos" ]]; then 723 | yum update 724 | yum -y groupinstall "Development Tools" 725 | wget --no-check-certificate -N https://github.com/jedisct1/libsodium/releases/download/${Libsodiumr_ver}/libsodium-${Libsodiumr_ver}.tar.gz 726 | tar -xzf libsodium-${Libsodiumr_ver}.tar.gz && cd libsodium-${Libsodiumr_ver} 727 | ./configure --disable-maintainer-mode && make -j2 && make install 728 | echo /usr/local/lib > /etc/ld.so.conf.d/usr_local_lib.conf 729 | else 730 | apt-get update 731 | apt-get install -y build-essential 732 | wget --no-check-certificate -N https://github.com/jedisct1/libsodium/releases/download/${Libsodiumr_ver}/libsodium-${Libsodiumr_ver}.tar.gz 733 | tar -xzf libsodium-${Libsodiumr_ver}.tar.gz && cd libsodium-${Libsodiumr_ver} 734 | ./configure --disable-maintainer-mode && make -j2 && make install 735 | fi 736 | ldconfig 737 | cd .. && rm -rf libsodium-${Libsodiumr_ver}.tar.gz && rm -rf libsodium-${Libsodiumr_ver} 738 | [[ ! -e ${Libsodiumr_file} ]] && echo -e "${Error} libsodium 安装失败 !" && exit 1 739 | echo && echo -e "${Info} libsodium 安装成功 !" && echo 740 | } 741 | # 显示 连接信息 742 | debian_View_user_connection_info(){ 743 | format_1=$1 744 | if [[ -z "${now_mode}" ]]; then 745 | now_mode="单端口" && user_total="1" 746 | IP_total=`netstat -anp |grep 'ESTABLISHED' |grep 'python' |grep 'tcp6' |awk '{print $5}' |awk -F ":" '{print $1}' |sort -u |wc -l` 747 | user_port=`${jq_file} '.server_port' ${config_user_file}` 748 | user_IP_1=`netstat -anp |grep 'ESTABLISHED' |grep 'python' |grep 'tcp6' |grep ":${user_port} " |awk '{print $5}' |awk -F ":" '{print $1}' |sort -u` 749 | if [[ -z ${user_IP_1} ]]; then 750 | user_IP_total="0" 751 | else 752 | user_IP_total=`echo -e "${user_IP_1}"|wc -l` 753 | if [[ ${format_1} == "IP_address" ]]; then 754 | get_IP_address 755 | else 756 | user_IP=`echo -e "\n${user_IP_1}"` 757 | fi 758 | fi 759 | user_list_all="端口: ${Green_font_prefix}"${user_port}"${Font_color_suffix}, 链接IP总数: ${Green_font_prefix}"${user_IP_total}"${Font_color_suffix}, 当前链接IP: ${Green_font_prefix}${user_IP}${Font_color_suffix}\n" 760 | user_IP="" 761 | echo -e "当前模式: ${Green_background_prefix} "${now_mode}" ${Font_color_suffix},链接IP总数: ${Green_background_prefix} "${IP_total}" ${Font_color_suffix}" 762 | echo -e "${user_list_all}" 763 | else 764 | now_mode="多端口" && user_total=`${jq_file} '.port_password' ${config_user_file} |sed '$d;1d' | wc -l` 765 | IP_total=`netstat -anp |grep 'ESTABLISHED' |grep 'python' |grep 'tcp6' |awk '{print $5}' |awk -F ":" '{print $1}' |sort -u |wc -l` 766 | user_list_all="" 767 | for((integer = ${user_total}; integer >= 1; integer--)) 768 | do 769 | user_port=`${jq_file} '.port_password' ${config_user_file} |sed '$d;1d' |awk -F ":" '{print $1}' |sed -n "${integer}p" |sed -r 's/.*\"(.+)\".*/\1/'` 770 | user_IP_1=`netstat -anp |grep 'ESTABLISHED' |grep 'python' |grep 'tcp6' |grep "${user_port}" |awk '{print $5}' |awk -F ":" '{print $1}' |sort -u` 771 | if [[ -z ${user_IP_1} ]]; then 772 | user_IP_total="0" 773 | else 774 | user_IP_total=`echo -e "${user_IP_1}"|wc -l` 775 | if [[ ${format_1} == "IP_address" ]]; then 776 | get_IP_address 777 | else 778 | user_IP=`echo -e "\n${user_IP_1}"` 779 | fi 780 | fi 781 | user_list_all=${user_list_all}"端口: ${Green_font_prefix}"${user_port}"${Font_color_suffix}, 链接IP总数: ${Green_font_prefix}"${user_IP_total}"${Font_color_suffix}, 当前链接IP: ${Green_font_prefix}${user_IP}${Font_color_suffix}\n" 782 | user_IP="" 783 | done 784 | echo -e "当前模式: ${Green_background_prefix} "${now_mode}" ${Font_color_suffix} ,用户总数: ${Green_background_prefix} "${user_total}" ${Font_color_suffix} ,链接IP总数: ${Green_background_prefix} "${IP_total}" ${Font_color_suffix} " 785 | echo -e "${user_list_all}" 786 | fi 787 | } 788 | centos_View_user_connection_info(){ 789 | format_1=$1 790 | if [[ -z "${now_mode}" ]]; then 791 | now_mode="单端口" && user_total="1" 792 | IP_total=`netstat -anp |grep 'ESTABLISHED' |grep 'python' |grep 'tcp' |grep '::ffff:' |awk '{print $5}' |awk -F ":" '{print $4}' |sort -u |wc -l` 793 | user_port=`${jq_file} '.server_port' ${config_user_file}` 794 | user_IP_1=`netstat -anp |grep 'ESTABLISHED' |grep 'python' |grep 'tcp' |grep ":${user_port} " | grep '::ffff:' |awk '{print $5}' |awk -F ":" '{print $4}' |sort -u` 795 | if [[ -z ${user_IP_1} ]]; then 796 | user_IP_total="0" 797 | else 798 | user_IP_total=`echo -e "${user_IP_1}"|wc -l` 799 | if [[ ${format_1} == "IP_address" ]]; then 800 | get_IP_address 801 | else 802 | user_IP=`echo -e "\n${user_IP_1}"` 803 | fi 804 | fi 805 | user_list_all="端口: ${Green_font_prefix}"${user_port}"${Font_color_suffix}, 链接IP总数: ${Green_font_prefix}"${user_IP_total}"${Font_color_suffix}, 当前链接IP: ${Green_font_prefix}${user_IP}${Font_color_suffix}\n" 806 | user_IP="" 807 | echo -e "当前模式: ${Green_background_prefix} "${now_mode}" ${Font_color_suffix},链接IP总数: ${Green_background_prefix} "${IP_total}" ${Font_color_suffix}" 808 | echo -e "${user_list_all}" 809 | else 810 | now_mode="多端口" && user_total=`${jq_file} '.port_password' ${config_user_file} |sed '$d;1d' | wc -l` 811 | IP_total=`netstat -anp |grep 'ESTABLISHED' |grep 'python' |grep 'tcp' | grep '::ffff:' |awk '{print $5}' |awk -F ":" '{print $4}' |sort -u |wc -l` 812 | user_list_all="" 813 | for((integer = 1; integer <= ${user_total}; integer++)) 814 | do 815 | user_port=`${jq_file} '.port_password' ${config_user_file} |sed '$d;1d' |awk -F ":" '{print $1}' |sed -n "${integer}p" |sed -r 's/.*\"(.+)\".*/\1/'` 816 | user_IP_1=`netstat -anp |grep 'ESTABLISHED' |grep 'python' |grep 'tcp' |grep "${user_port}"|grep '::ffff:' |awk '{print $5}' |awk -F ":" '{print $4}' |sort -u` 817 | if [[ -z ${user_IP_1} ]]; then 818 | user_IP_total="0" 819 | else 820 | user_IP_total=`echo -e "${user_IP_1}"|wc -l` 821 | if [[ ${format_1} == "IP_address" ]]; then 822 | get_IP_address 823 | else 824 | user_IP=`echo -e "\n${user_IP_1}"` 825 | fi 826 | fi 827 | user_list_all=${user_list_all}"端口: ${Green_font_prefix}"${user_port}"${Font_color_suffix}, 链接IP总数: ${Green_font_prefix}"${user_IP_total}"${Font_color_suffix}, 当前链接IP: ${Green_font_prefix}${user_IP}${Font_color_suffix}\n" 828 | user_IP="" 829 | done 830 | echo -e "当前模式: ${Green_background_prefix} "${now_mode}" ${Font_color_suffix} ,用户总数: ${Green_background_prefix} "${user_total}" ${Font_color_suffix} ,链接IP总数: ${Green_background_prefix} "${IP_total}" ${Font_color_suffix} " 831 | echo -e "${user_list_all}" 832 | fi 833 | } 834 | View_user_connection_info(){ 835 | SSR_installation_status 836 | echo && echo -e "请选择要显示的格式: 837 | ${Green_font_prefix}1.${Font_color_suffix} 显示 IP 格式 838 | ${Green_font_prefix}2.${Font_color_suffix} 显示 IP+IP归属地 格式" && echo 839 | stty erase '^H' && read -p "(默认: 1):" ssr_connection_info 840 | [[ -z "${ssr_connection_info}" ]] && ssr_connection_info="1" 841 | if [[ ${ssr_connection_info} == "1" ]]; then 842 | View_user_connection_info_1 "" 843 | elif [[ ${ssr_connection_info} == "2" ]]; then 844 | echo -e "${Tip} 检测IP归属地(ipip.net),如果IP较多,可能时间会比较长..." 845 | View_user_connection_info_1 "IP_address" 846 | else 847 | echo -e "${Error} 请输入正确的数字(1-2)" && exit 1 848 | fi 849 | } 850 | View_user_connection_info_1(){ 851 | format=$1 852 | if [[ ${release} = "centos" ]]; then 853 | cat /etc/redhat-release |grep 7\..*|grep -i centos>/dev/null 854 | if [[ $? = 0 ]]; then 855 | debian_View_user_connection_info "$format" 856 | else 857 | centos_View_user_connection_info "$format" 858 | fi 859 | else 860 | debian_View_user_connection_info "$format" 861 | fi 862 | } 863 | get_IP_address(){ 864 | #echo "user_IP_1=${user_IP_1}" 865 | if [[ ! -z ${user_IP_1} ]]; then 866 | #echo "user_IP_total=${user_IP_total}" 867 | for((integer_1 = ${user_IP_total}; integer_1 >= 1; integer_1--)) 868 | do 869 | IP=`echo "${user_IP_1}" |sed -n "$integer_1"p` 870 | #echo "IP=${IP}" 871 | IP_address=`wget -qO- -t1 -T2 http://freeapi.ipip.net/${IP}|sed 's/\"//g;s/,//g;s/\[//g;s/\]//g'` 872 | #echo "IP_address=${IP_address}" 873 | user_IP="${user_IP}\n${IP}(${IP_address})" 874 | #echo "user_IP=${user_IP}" 875 | sleep 1s 876 | done 877 | fi 878 | } 879 | # 修改 用户配置 880 | Modify_Config(){ 881 | SSR_installation_status 882 | if [[ -z "${now_mode}" ]]; then 883 | echo && echo -e "当前模式: 单端口,你要做什么? 884 | ${Green_font_prefix}1.${Font_color_suffix} 修改 用户端口 885 | ${Green_font_prefix}2.${Font_color_suffix} 修改 用户密码 886 | ${Green_font_prefix}3.${Font_color_suffix} 修改 加密方式 887 | ${Green_font_prefix}4.${Font_color_suffix} 修改 协议插件 888 | ${Green_font_prefix}5.${Font_color_suffix} 修改 混淆插件 889 | ${Green_font_prefix}6.${Font_color_suffix} 修改 设备数限制 890 | ${Green_font_prefix}7.${Font_color_suffix} 修改 单线程限速 891 | ${Green_font_prefix}8.${Font_color_suffix} 修改 端口总限速 892 | ${Green_font_prefix}9.${Font_color_suffix} 修改 全部配置" && echo 893 | stty erase '^H' && read -p "(默认: 取消):" ssr_modify 894 | [[ -z "${ssr_modify}" ]] && echo "已取消..." && exit 1 895 | Get_User 896 | if [[ ${ssr_modify} == "1" ]]; then 897 | Set_config_port 898 | Modify_config_port 899 | Add_iptables 900 | Del_iptables 901 | Save_iptables 902 | elif [[ ${ssr_modify} == "2" ]]; then 903 | Set_config_password 904 | Modify_config_password 905 | elif [[ ${ssr_modify} == "3" ]]; then 906 | Set_config_method 907 | Modify_config_method 908 | elif [[ ${ssr_modify} == "4" ]]; then 909 | Set_config_protocol 910 | Modify_config_protocol 911 | elif [[ ${ssr_modify} == "5" ]]; then 912 | Set_config_obfs 913 | Modify_config_obfs 914 | elif [[ ${ssr_modify} == "6" ]]; then 915 | Set_config_protocol_param 916 | Modify_config_protocol_param 917 | elif [[ ${ssr_modify} == "7" ]]; then 918 | Set_config_speed_limit_per_con 919 | Modify_config_speed_limit_per_con 920 | elif [[ ${ssr_modify} == "8" ]]; then 921 | Set_config_speed_limit_per_user 922 | Modify_config_speed_limit_per_user 923 | elif [[ ${ssr_modify} == "9" ]]; then 924 | Set_config_all 925 | Modify_config_all 926 | else 927 | echo -e "${Error} 请输入正确的数字(1-9)" && exit 1 928 | fi 929 | else 930 | echo && echo -e "当前模式: 多端口,你要做什么? 931 | ${Green_font_prefix}1.${Font_color_suffix} 添加 用户配置 932 | ${Green_font_prefix}2.${Font_color_suffix} 删除 用户配置 933 | ${Green_font_prefix}3.${Font_color_suffix} 修改 用户配置 934 | —————————— 935 | ${Green_font_prefix}4.${Font_color_suffix} 修改 加密方式 936 | ${Green_font_prefix}5.${Font_color_suffix} 修改 协议插件 937 | ${Green_font_prefix}6.${Font_color_suffix} 修改 混淆插件 938 | ${Green_font_prefix}7.${Font_color_suffix} 修改 设备数限制 939 | ${Green_font_prefix}8.${Font_color_suffix} 修改 单线程限速 940 | ${Green_font_prefix}9.${Font_color_suffix} 修改 端口总限速 941 | ${Green_font_prefix}10.${Font_color_suffix} 修改 全部配置" && echo 942 | stty erase '^H' && read -p "(默认: 取消):" ssr_modify 943 | [[ -z "${ssr_modify}" ]] && echo "已取消..." && exit 1 944 | Get_User 945 | if [[ ${ssr_modify} == "1" ]]; then 946 | Add_multi_port_user 947 | elif [[ ${ssr_modify} == "2" ]]; then 948 | Del_multi_port_user 949 | elif [[ ${ssr_modify} == "3" ]]; then 950 | Modify_multi_port_user 951 | elif [[ ${ssr_modify} == "4" ]]; then 952 | Set_config_method 953 | Modify_config_method 954 | elif [[ ${ssr_modify} == "5" ]]; then 955 | Set_config_protocol 956 | Modify_config_protocol 957 | elif [[ ${ssr_modify} == "6" ]]; then 958 | Set_config_obfs 959 | Modify_config_obfs 960 | elif [[ ${ssr_modify} == "7" ]]; then 961 | Set_config_protocol_param 962 | Modify_config_protocol_param 963 | elif [[ ${ssr_modify} == "8" ]]; then 964 | Set_config_speed_limit_per_con 965 | Modify_config_speed_limit_per_con 966 | elif [[ ${ssr_modify} == "9" ]]; then 967 | Set_config_speed_limit_per_user 968 | Modify_config_speed_limit_per_user 969 | elif [[ ${ssr_modify} == "10" ]]; then 970 | Set_config_method 971 | Set_config_protocol 972 | Set_config_obfs 973 | Set_config_protocol_param 974 | Set_config_speed_limit_per_con 975 | Set_config_speed_limit_per_user 976 | Modify_config_method 977 | Modify_config_protocol 978 | Modify_config_obfs 979 | Modify_config_protocol_param 980 | Modify_config_speed_limit_per_con 981 | Modify_config_speed_limit_per_user 982 | else 983 | echo -e "${Error} 请输入正确的数字(1-9)" && exit 1 984 | fi 985 | fi 986 | Restart_SSR 987 | } 988 | # 显示 多端口用户配置 989 | List_multi_port_user(){ 990 | user_total=`${jq_file} '.port_password' ${config_user_file} | sed '$d' | sed "1d" | wc -l` 991 | [[ ${user_total} = "0" ]] && echo -e "${Error} 没有发现 多端口用户,请检查 !" && exit 1 992 | user_list_all="" 993 | for((integer = ${user_total}; integer >= 1; integer--)) 994 | do 995 | user_port=`${jq_file} '.port_password' ${config_user_file} | sed '$d' | sed "1d" | awk -F ":" '{print $1}' | sed -n "${integer}p" | sed -r 's/.*\"(.+)\".*/\1/'` 996 | user_password=`${jq_file} '.port_password' ${config_user_file} | sed '$d' | sed "1d" | awk -F ":" '{print $2}' | sed -n "${integer}p" | sed -r 's/.*\"(.+)\".*/\1/'` 997 | user_list_all=${user_list_all}"端口: "${user_port}" 密码: "${user_password}"\n" 998 | done 999 | echo && echo -e "用户总数 ${Green_font_prefix}"${user_total}"${Font_color_suffix}" 1000 | echo -e ${user_list_all} 1001 | } 1002 | # 添加 多端口用户配置 1003 | Add_multi_port_user(){ 1004 | Set_config_port 1005 | Set_config_password 1006 | sed -i "8 i \" \"${ssr_port}\":\"${ssr_password}\"," ${config_user_file} 1007 | sed -i "8s/^\"//" ${config_user_file} 1008 | Add_iptables 1009 | Save_iptables 1010 | echo -e "${Info} 多端口用户添加完成 ${Green_font_prefix}[端口: ${ssr_port} , 密码: ${ssr_password}]${Font_color_suffix} " 1011 | } 1012 | # 修改 多端口用户配置 1013 | Modify_multi_port_user(){ 1014 | List_multi_port_user 1015 | echo && echo -e "请输入要修改的用户端口" 1016 | stty erase '^H' && read -p "(默认: 取消):" modify_user_port 1017 | [[ -z "${modify_user_port}" ]] && echo -e "已取消..." && exit 1 1018 | del_user=`cat ${config_user_file}|grep '"'"${modify_user_port}"'"'` 1019 | if [[ ! -z "${del_user}" ]]; then 1020 | port="${modify_user_port}" 1021 | password=`echo -e ${del_user}|awk -F ":" '{print $NF}'|sed -r 's/.*\"(.+)\".*/\1/'` 1022 | Set_config_port 1023 | Set_config_password 1024 | sed -i 's/"'$(echo ${port})'":"'$(echo ${password})'"/"'$(echo ${ssr_port})'":"'$(echo ${ssr_password})'"/g' ${config_user_file} 1025 | Del_iptables 1026 | Add_iptables 1027 | Save_iptables 1028 | echo -e "${Inof} 多端口用户修改完成 ${Green_font_prefix}[旧: ${modify_user_port} ${password} , 新: ${ssr_port} ${ssr_password}]${Font_color_suffix} " 1029 | else 1030 | echo -e "${Error} 请输入正确的端口 !" && exit 1 1031 | fi 1032 | } 1033 | # 删除 多端口用户配置 1034 | Del_multi_port_user(){ 1035 | List_multi_port_user 1036 | user_total=`${jq_file} '.port_password' ${config_user_file} | sed '$d' | sed "1d" | wc -l` 1037 | [[ "${user_total}" = "1" ]] && echo -e "${Error} 多端口用户仅剩 1个,不能删除 !" && exit 1 1038 | echo -e "请输入要删除的用户端口" 1039 | stty erase '^H' && read -p "(默认: 取消):" del_user_port 1040 | [[ -z "${del_user_port}" ]] && echo -e "已取消..." && exit 1 1041 | del_user=`cat ${config_user_file}|grep '"'"${del_user_port}"'"'` 1042 | if [[ ! -z ${del_user} ]]; then 1043 | port=${del_user_port} 1044 | Del_iptables 1045 | Save_iptables 1046 | del_user_determine=`echo ${del_user:((${#del_user} - 1))}` 1047 | if [[ ${del_user_determine} != "," ]]; then 1048 | del_user_num=$(sed -n -e "/${port}/=" ${config_user_file}) 1049 | del_user_num=$(expr $del_user_num - 1) 1050 | sed -i "${del_user_num}s/,//g" ${config_user_file} 1051 | fi 1052 | sed -i "/${port}/d" ${config_user_file} 1053 | echo -e "${Info} 多端口用户删除完成 ${Green_font_prefix} ${del_user_port} ${Font_color_suffix} " 1054 | else 1055 | echo "${Error} 请输入正确的端口 !" && exit 1 1056 | fi 1057 | } 1058 | # 手动修改 用户配置 1059 | Manually_Modify_Config(){ 1060 | SSR_installation_status 1061 | port=`${jq_file} '.server_port' ${config_user_file}` 1062 | vi ${config_user_file} 1063 | if [[ -z "${now_mode}" ]]; then 1064 | ssr_port=`${jq_file} '.server_port' ${config_user_file}` 1065 | Del_iptables 1066 | Add_iptables 1067 | fi 1068 | Restart_SSR 1069 | } 1070 | # 切换端口模式 1071 | Port_mode_switching(){ 1072 | SSR_installation_status 1073 | if [[ -z "${now_mode}" ]]; then 1074 | echo && echo -e " 当前模式: ${Green_font_prefix}单端口${Font_color_suffix}" && echo 1075 | echo -e "确定要切换为 多端口模式?[y/N]" 1076 | stty erase '^H' && read -p "(默认: n):" mode_yn 1077 | [[ -z ${mode_yn} ]] && mode_yn="n" 1078 | if [[ ${mode_yn} == [Yy] ]]; then 1079 | port=`${jq_file} '.server_port' ${config_user_file}` 1080 | Set_config_all 1081 | Write_configuration_many 1082 | Del_iptables 1083 | Add_iptables 1084 | Save_iptables 1085 | Restart_SSR 1086 | else 1087 | echo && echo " 已取消..." && echo 1088 | fi 1089 | else 1090 | echo && echo -e " 当前模式: ${Green_font_prefix}多端口${Font_color_suffix}" && echo 1091 | echo -e "确定要切换为 单端口模式?[y/N]" 1092 | stty erase '^H' && read -p "(默认: n):" mode_yn 1093 | [[ -z ${mode_yn} ]] && mode_yn="n" 1094 | if [[ ${mode_yn} == [Yy] ]]; then 1095 | user_total=`${jq_file} '.port_password' ${config_user_file} | sed '$d' | sed "1d" | wc -l` 1096 | for((integer = 1; integer <= ${user_total}; integer++)) 1097 | do 1098 | port=`${jq_file} '.port_password' ${config_user_file} | sed '$d' | sed "1d" | awk -F ":" '{print $1}' | sed -n "${integer}p" | sed -r 's/.*\"(.+)\".*/\1/'` 1099 | Del_iptables 1100 | done 1101 | Set_config_all 1102 | Write_configuration 1103 | Add_iptables 1104 | Restart_SSR 1105 | else 1106 | echo && echo " 已取消..." && echo 1107 | fi 1108 | fi 1109 | } 1110 | Start_SSR(){ 1111 | SSR_installation_status 1112 | check_pid 1113 | [[ ! -z ${PID} ]] && echo -e "${Error} ShadowsocksR 正在运行 !" && exit 1 1114 | /etc/init.d/ssr start 1115 | check_pid 1116 | [[ ! -z ${PID} ]] && View_User 1117 | } 1118 | Stop_SSR(){ 1119 | SSR_installation_status 1120 | check_pid 1121 | [[ -z ${PID} ]] && echo -e "${Error} ShadowsocksR 未运行 !" && exit 1 1122 | /etc/init.d/ssr stop 1123 | } 1124 | Restart_SSR(){ 1125 | SSR_installation_status 1126 | check_pid 1127 | [[ ! -z ${PID} ]] && /etc/init.d/ssr stop 1128 | /etc/init.d/ssr start 1129 | check_pid 1130 | [[ ! -z ${PID} ]] && View_User 1131 | } 1132 | View_Log(){ 1133 | SSR_installation_status 1134 | [[ ! -e ${ssr_log_file} ]] && echo -e "${Error} ShadowsocksR日志文件不存在 !" && exit 1 1135 | echo && echo -e "${Tip} 按 ${Red_font_prefix}Ctrl+C${Font_color_suffix} 终止查看日志" && echo 1136 | tail -f ${ssr_log_file} 1137 | } 1138 | # 锐速 1139 | Configure_Server_Speeder(){ 1140 | echo && echo -e "你要做什么? 1141 | ${Green_font_prefix}1.${Font_color_suffix} 安装 锐速 1142 | ${Green_font_prefix}2.${Font_color_suffix} 卸载 锐速 1143 | ———————— 1144 | ${Green_font_prefix}3.${Font_color_suffix} 启动 锐速 1145 | ${Green_font_prefix}4.${Font_color_suffix} 停止 锐速 1146 | ${Green_font_prefix}5.${Font_color_suffix} 重启 锐速 1147 | ${Green_font_prefix}6.${Font_color_suffix} 查看 锐速 状态 1148 | 1149 | 注意: 锐速和LotServer不能同时安装/启动!" && echo 1150 | stty erase '^H' && read -p "(默认: 取消):" server_speeder_num 1151 | [[ -z "${server_speeder_num}" ]] && echo "已取消..." && exit 1 1152 | if [[ ${server_speeder_num} == "1" ]]; then 1153 | Install_ServerSpeeder 1154 | elif [[ ${server_speeder_num} == "2" ]]; then 1155 | Server_Speeder_installation_status 1156 | Uninstall_ServerSpeeder 1157 | elif [[ ${server_speeder_num} == "3" ]]; then 1158 | Server_Speeder_installation_status 1159 | ${Server_Speeder_file} start 1160 | ${Server_Speeder_file} status 1161 | elif [[ ${server_speeder_num} == "4" ]]; then 1162 | Server_Speeder_installation_status 1163 | ${Server_Speeder_file} stop 1164 | elif [[ ${server_speeder_num} == "5" ]]; then 1165 | Server_Speeder_installation_status 1166 | ${Server_Speeder_file} restart 1167 | ${Server_Speeder_file} status 1168 | elif [[ ${server_speeder_num} == "6" ]]; then 1169 | Server_Speeder_installation_status 1170 | ${Server_Speeder_file} status 1171 | else 1172 | echo -e "${Error} 请输入正确的数字(1-6)" && exit 1 1173 | fi 1174 | } 1175 | Install_ServerSpeeder(){ 1176 | [[ -e ${Server_Speeder_file} ]] && echo -e "${Error} 锐速(Server Speeder) 已安装 !" && exit 1 1177 | cd /root 1178 | #借用91yun.rog的开心版锐速 1179 | wget -N --no-check-certificate https://raw.githubusercontent.com/91yun/serverspeeder/master/serverspeeder.sh 1180 | [[ ! -e "serverspeeder.sh" ]] && echo -e "${Error} 锐速安装脚本下载失败 !" && exit 1 1181 | bash serverspeeder.sh 1182 | sleep 2s 1183 | PID=`ps -ef |grep -v grep |grep "serverspeeder" |awk '{print $2}'` 1184 | if [[ ! -z ${PID} ]]; then 1185 | rm -rf /root/serverspeeder.sh 1186 | rm -rf /root/91yunserverspeeder 1187 | rm -rf /root/91yunserverspeeder.tar.gz 1188 | echo -e "${Info} 锐速(Server Speeder) 安装完成 !" && exit 1 1189 | else 1190 | echo -e "${Error} 锐速(Server Speeder) 安装失败 !" && exit 1 1191 | fi 1192 | } 1193 | Uninstall_ServerSpeeder(){ 1194 | echo "确定要卸载 锐速(Server Speeder)?[y/N]" && echo 1195 | stty erase '^H' && read -p "(默认: n):" unyn 1196 | [[ -z ${unyn} ]] && echo && echo "已取消..." && exit 1 1197 | if [[ ${unyn} == [Yy] ]]; then 1198 | chattr -i /serverspeeder/etc/apx* 1199 | /serverspeeder/bin/serverSpeeder.sh uninstall -f 1200 | echo && echo "锐速(Server Speeder) 卸载完成 !" && echo 1201 | fi 1202 | } 1203 | # LotServer 1204 | Configure_LotServer(){ 1205 | echo && echo -e "你要做什么? 1206 | ${Green_font_prefix}1.${Font_color_suffix} 安装 LotServer 1207 | ${Green_font_prefix}2.${Font_color_suffix} 卸载 LotServer 1208 | ———————— 1209 | ${Green_font_prefix}3.${Font_color_suffix} 启动 LotServer 1210 | ${Green_font_prefix}4.${Font_color_suffix} 停止 LotServer 1211 | ${Green_font_prefix}5.${Font_color_suffix} 重启 LotServer 1212 | ${Green_font_prefix}6.${Font_color_suffix} 查看 LotServer 状态 1213 | 1214 | 注意: 锐速和LotServer不能同时安装/启动!" && echo 1215 | stty erase '^H' && read -p "(默认: 取消):" lotserver_num 1216 | [[ -z "${lotserver_num}" ]] && echo "已取消..." && exit 1 1217 | if [[ ${lotserver_num} == "1" ]]; then 1218 | Install_LotServer 1219 | elif [[ ${lotserver_num} == "2" ]]; then 1220 | LotServer_installation_status 1221 | Uninstall_LotServer 1222 | elif [[ ${lotserver_num} == "3" ]]; then 1223 | LotServer_installation_status 1224 | ${LotServer_file} start 1225 | ${LotServer_file} status 1226 | elif [[ ${lotserver_num} == "4" ]]; then 1227 | LotServer_installation_status 1228 | ${LotServer_file} stop 1229 | elif [[ ${lotserver_num} == "5" ]]; then 1230 | LotServer_installation_status 1231 | ${LotServer_file} restart 1232 | ${LotServer_file} status 1233 | elif [[ ${lotserver_num} == "6" ]]; then 1234 | LotServer_installation_status 1235 | ${LotServer_file} status 1236 | else 1237 | echo -e "${Error} 请输入正确的数字(1-6)" && exit 1 1238 | fi 1239 | } 1240 | Install_LotServer(){ 1241 | [[ -e ${LotServer_file} ]] && echo -e "${Error} LotServer 已安装 !" && exit 1 1242 | #Github: https://github.com/0oVicero0/serverSpeeder_Install 1243 | wget --no-check-certificate -qO /tmp/appex.sh "https://raw.githubusercontent.com/0oVicero0/serverSpeeder_Install/master/appex.sh" 1244 | [[ ! -e "/tmp/appex.sh" ]] && echo -e "${Error} LotServer 安装脚本下载失败 !" && exit 1 1245 | bash /tmp/appex.sh 'install' 1246 | sleep 2s 1247 | PID=`ps -ef |grep -v grep |grep "appex" |awk '{print $2}'` 1248 | if [[ ! -z ${PID} ]]; then 1249 | echo -e "${Info} LotServer 安装完成 !" && exit 1 1250 | else 1251 | echo -e "${Error} LotServer 安装失败 !" && exit 1 1252 | fi 1253 | } 1254 | Uninstall_LotServer(){ 1255 | echo "确定要卸载 LotServer?[y/N]" && echo 1256 | stty erase '^H' && read -p "(默认: n):" unyn 1257 | [[ -z ${unyn} ]] && echo && echo "已取消..." && exit 1 1258 | if [[ ${unyn} == [Yy] ]]; then 1259 | wget --no-check-certificate -qO /tmp/appex.sh "https://raw.githubusercontent.com/0oVicero0/serverSpeeder_Install/master/appex.sh" && bash /tmp/appex.sh 'uninstall' 1260 | echo && echo "LotServer 卸载完成 !" && echo 1261 | fi 1262 | } 1263 | # BBR 1264 | Configure_BBR(){ 1265 | echo && echo -e " 你要做什么? 1266 | 1267 | ${Green_font_prefix}1.${Font_color_suffix} 安装 BBR 1268 | ———————— 1269 | ${Green_font_prefix}2.${Font_color_suffix} 启动 BBR 1270 | ${Green_font_prefix}3.${Font_color_suffix} 停止 BBR 1271 | ${Green_font_prefix}4.${Font_color_suffix} 查看 BBR 状态" && echo 1272 | echo -e "${Green_font_prefix} [安装前 请注意] ${Font_color_suffix} 1273 | 1. 安装开启BBR,需要更换内核,存在更换失败等风险(重启后无法开机) 1274 | 2. 本脚本仅支持 Debian / Ubuntu 系统更换内核,OpenVZ和Docker 不支持更换内核 1275 | 3. Debian 更换内核过程中会提示 [ 是否终止卸载内核 ] ,请选择 ${Green_font_prefix} NO ${Font_color_suffix} 1276 | 4. 安装BBR并重启服务器后,需要重新运行脚本 启动BBR" && echo 1277 | stty erase '^H' && read -p "(默认: 取消):" bbr_num 1278 | [[ -z "${bbr_num}" ]] && echo "已取消..." && exit 1 1279 | if [[ ${bbr_num} == "1" ]]; then 1280 | Install_BBR 1281 | elif [[ ${bbr_num} == "2" ]]; then 1282 | Start_BBR 1283 | elif [[ ${bbr_num} == "3" ]]; then 1284 | Stop_BBR 1285 | elif [[ ${bbr_num} == "4" ]]; then 1286 | Status_BBR 1287 | else 1288 | echo -e "${Error} 请输入正确的数字(1-4)" && exit 1 1289 | fi 1290 | } 1291 | Install_BBR(){ 1292 | [[ ${release} = "centos" ]] && echo -e "${Error} 本脚本不支持 CentOS系统安装 BBR !" && exit 1 1293 | BBR_installation_status 1294 | bash "${BBR_file}" 1295 | } 1296 | Start_BBR(){ 1297 | BBR_installation_status 1298 | bash "${BBR_file}" start 1299 | } 1300 | Stop_BBR(){ 1301 | BBR_installation_status 1302 | bash "${BBR_file}" stop 1303 | } 1304 | Status_BBR(){ 1305 | BBR_installation_status 1306 | bash "${BBR_file}" status 1307 | } 1308 | # 其他功能 1309 | Other_functions(){ 1310 | echo && echo -e " 你要做什么? 1311 | 1312 | ${Green_font_prefix}1.${Font_color_suffix} 配置 BBR 1313 | ${Green_font_prefix}2.${Font_color_suffix} 配置 锐速(ServerSpeeder) 1314 | ${Green_font_prefix}3.${Font_color_suffix} 配置 LotServer(锐速母公司) 1315 | 注意: 锐速/LotServer/BBR 不支持 OpenVZ! 1316 | 注意: 锐速和LotServer不能同时安装/启动! 1317 | ———————————— 1318 | ${Green_font_prefix}4.${Font_color_suffix} 一键封禁 BT/PT/SPAM (iptables) 1319 | ${Green_font_prefix}5.${Font_color_suffix} 一键解封 BT/PT/SPAM (iptables) 1320 | ${Green_font_prefix}6.${Font_color_suffix} 切换 ShadowsocksR日志输出模式 1321 | ——说明:SSR默认只输出错误日志,此项可切换为输出详细的访问日志" && echo 1322 | stty erase '^H' && read -p "(默认: 取消):" other_num 1323 | [[ -z "${other_num}" ]] && echo "已取消..." && exit 1 1324 | if [[ ${other_num} == "1" ]]; then 1325 | Configure_BBR 1326 | elif [[ ${other_num} == "2" ]]; then 1327 | Configure_Server_Speeder 1328 | elif [[ ${other_num} == "3" ]]; then 1329 | Configure_LotServer 1330 | elif [[ ${other_num} == "4" ]]; then 1331 | BanBTPTSPAM 1332 | elif [[ ${other_num} == "5" ]]; then 1333 | UnBanBTPTSPAM 1334 | elif [[ ${other_num} == "6" ]]; then 1335 | Set_config_connect_verbose_info 1336 | else 1337 | echo -e "${Error} 请输入正确的数字 [1-6]" && exit 1 1338 | fi 1339 | } 1340 | # 封禁 BT PT SPAM 1341 | BanBTPTSPAM(){ 1342 | wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/ban_iptables.sh && chmod +x ban_iptables.sh && bash ban_iptables.sh banall 1343 | rm -rf ban_iptables.sh 1344 | } 1345 | # 解封 BT PT SPAM 1346 | UnBanBTPTSPAM(){ 1347 | wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/ban_iptables.sh && chmod +x ban_iptables.sh && bash ban_iptables.sh unbanall 1348 | rm -rf ban_iptables.sh 1349 | } 1350 | Set_config_connect_verbose_info(){ 1351 | SSR_installation_status 1352 | Get_User 1353 | if [[ ${connect_verbose_info} = "0" ]]; then 1354 | echo && echo -e "当前日志模式: ${Green_font_prefix}简单模式(只输出错误日志)${Font_color_suffix}" && echo 1355 | echo -e "确定要切换为 ${Green_font_prefix}详细模式(输出详细连接日志+错误日志)${Font_color_suffix}?[y/N]" 1356 | stty erase '^H' && read -p "(默认: n):" connect_verbose_info_ny 1357 | [[ -z "${connect_verbose_info_ny}" ]] && connect_verbose_info_ny="n" 1358 | if [[ ${connect_verbose_info_ny} == [Yy] ]]; then 1359 | ssr_connect_verbose_info="1" 1360 | Modify_config_connect_verbose_info 1361 | Restart_SSR 1362 | else 1363 | echo && echo " 已取消..." && echo 1364 | fi 1365 | else 1366 | echo && echo -e "当前日志模式: ${Green_font_prefix}详细模式(输出详细连接日志+错误日志)${Font_color_suffix}" && echo 1367 | echo -e "确定要切换为 ${Green_font_prefix}简单模式(只输出错误日志)${Font_color_suffix}?[y/N]" 1368 | stty erase '^H' && read -p "(默认: n):" connect_verbose_info_ny 1369 | [[ -z "${connect_verbose_info_ny}" ]] && connect_verbose_info_ny="n" 1370 | if [[ ${connect_verbose_info_ny} == [Yy] ]]; then 1371 | ssr_connect_verbose_info="0" 1372 | Modify_config_connect_verbose_info 1373 | Restart_SSR 1374 | else 1375 | echo && echo " 已取消..." && echo 1376 | fi 1377 | fi 1378 | } 1379 | Update_Shell(){ 1380 | echo -e "当前版本为 [ ${sh_ver} ],开始检测最新版本..." 1381 | sh_new_ver=$(wget --no-check-certificate -qO- "https://softs.fun/Bash/ssr.sh"|grep 'sh_ver="'|awk -F "=" '{print $NF}'|sed 's/\"//g'|head -1) && sh_new_type="softs" 1382 | [[ -z ${sh_new_ver} ]] && sh_new_ver=$(wget --no-check-certificate -qO- "https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/ssr.sh"|grep 'sh_ver="'|awk -F "=" '{print $NF}'|sed 's/\"//g'|head -1) && sh_new_type="github" 1383 | [[ -z ${sh_new_ver} ]] && echo -e "${Error} 检测最新版本失败 !" && exit 0 1384 | if [[ ${sh_new_ver} != ${sh_ver} ]]; then 1385 | echo -e "发现新版本[ ${sh_new_ver} ],是否更新?[Y/n]" 1386 | stty erase '^H' && read -p "(默认: y):" yn 1387 | [[ -z "${yn}" ]] && yn="y" 1388 | if [[ ${yn} == [Yy] ]]; then 1389 | if [[ $sh_new_type == "softs" ]]; then 1390 | wget -N --no-check-certificate https://softs.fun/Bash/ssr.sh && chmod +x ssr.sh 1391 | else 1392 | wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/ssr.sh && chmod +x ssr.sh 1393 | fi 1394 | echo -e "脚本已更新为最新版本[ ${sh_new_ver} ] !" 1395 | else 1396 | echo && echo " 已取消..." && echo 1397 | fi 1398 | else 1399 | echo -e "当前已是最新版本[ ${sh_new_ver} ] !" 1400 | fi 1401 | } 1402 | # 显示 菜单状态 1403 | menu_status(){ 1404 | if [[ -e ${config_user_file} ]]; then 1405 | check_pid 1406 | if [[ ! -z "${PID}" ]]; then 1407 | echo -e " 当前状态: ${Green_font_prefix}已安装${Font_color_suffix} 并 ${Green_font_prefix}已启动${Font_color_suffix}" 1408 | else 1409 | echo -e " 当前状态: ${Green_font_prefix}已安装${Font_color_suffix} 但 ${Red_font_prefix}未启动${Font_color_suffix}" 1410 | fi 1411 | now_mode=$(cat "${config_user_file}"|grep '"port_password"') 1412 | if [[ -z "${now_mode}" ]]; then 1413 | echo -e " 当前模式: ${Green_font_prefix}单端口${Font_color_suffix}" 1414 | else 1415 | echo -e " 当前模式: ${Green_font_prefix}多端口${Font_color_suffix}" 1416 | fi 1417 | else 1418 | echo -e " 当前状态: ${Red_font_prefix}未安装${Font_color_suffix}" 1419 | fi 1420 | } 1421 | check_sys 1422 | [[ ${release} != "debian" ]] && [[ ${release} != "ubuntu" ]] && [[ ${release} != "centos" ]] && echo -e "${Error} 本脚本不支持当前系统 ${release} !" && exit 1 1423 | echo -e " ShadowsocksR 一键管理脚本 ${Red_font_prefix}[v${sh_ver}]${Font_color_suffix} 1424 | ---- Toyo | doub.io/ss-jc42 ---- 1425 | 1426 | ${Green_font_prefix}1.${Font_color_suffix} 安装 ShadowsocksR 1427 | ${Green_font_prefix}2.${Font_color_suffix} 更新 ShadowsocksR 1428 | ${Green_font_prefix}3.${Font_color_suffix} 卸载 ShadowsocksR 1429 | ${Green_font_prefix}4.${Font_color_suffix} 安装 libsodium(chacha20) 1430 | ———————————— 1431 | ${Green_font_prefix}5.${Font_color_suffix} 查看 账号信息 1432 | ${Green_font_prefix}6.${Font_color_suffix} 显示 连接信息 1433 | ${Green_font_prefix}7.${Font_color_suffix} 设置 用户配置 1434 | ${Green_font_prefix}8.${Font_color_suffix} 手动 修改配置 1435 | ${Green_font_prefix}9.${Font_color_suffix} 切换 端口模式 1436 | ———————————— 1437 | ${Green_font_prefix}10.${Font_color_suffix} 启动 ShadowsocksR 1438 | ${Green_font_prefix}11.${Font_color_suffix} 停止 ShadowsocksR 1439 | ${Green_font_prefix}12.${Font_color_suffix} 重启 ShadowsocksR 1440 | ${Green_font_prefix}13.${Font_color_suffix} 查看 ShadowsocksR 日志 1441 | ———————————— 1442 | ${Green_font_prefix}14.${Font_color_suffix} 其他功能 1443 | ${Green_font_prefix}15.${Font_color_suffix} 升级脚本 1444 | " 1445 | menu_status 1446 | echo && stty erase '^H' && read -p "请输入数字 [1-15]:" num 1447 | case "$num" in 1448 | 1) 1449 | Install_SSR 1450 | ;; 1451 | 2) 1452 | Update_SSR 1453 | ;; 1454 | 3) 1455 | Uninstall_SSR 1456 | ;; 1457 | 4) 1458 | Install_Libsodium 1459 | ;; 1460 | 5) 1461 | View_User 1462 | ;; 1463 | 6) 1464 | View_user_connection_info 1465 | ;; 1466 | 7) 1467 | Modify_Config 1468 | ;; 1469 | 8) 1470 | Manually_Modify_Config 1471 | ;; 1472 | 9) 1473 | Port_mode_switching 1474 | ;; 1475 | 10) 1476 | Start_SSR 1477 | ;; 1478 | 11) 1479 | Stop_SSR 1480 | ;; 1481 | 12) 1482 | Restart_SSR 1483 | ;; 1484 | 13) 1485 | View_Log 1486 | ;; 1487 | 14) 1488 | Other_functions 1489 | ;; 1490 | 15) 1491 | Update_Shell 1492 | ;; 1493 | *) 1494 | echo -e "${Error} 请输入正确的数字 [1-15]" 1495 | ;; 1496 | esac --------------------------------------------------------------------------------