└── README.md /README.md: -------------------------------------------------------------------------------- 1 |

2 | bash logo 3 |

4 | 5 | ## 目录 6 | 1. [基本操作](#1-basic-operations) 7 | 1.1. [文件操作](#11-file-operations) 8 | 1.2. [文本操作](#12-text-operations) 9 | 1.3. [目录操作](#13-directory-operations) 10 | 1.4. [SSH、系统信息和网络操作](#14-ssh-system-info--network-operations) 11 | 1.5. [进程监控操作](#15-process-monitoring-operations) 12 | 2. [基本 shell 编程](#2-basic-shell-programming) 13 | 2.1. [变量](#21-variables) 14 | 2.2 [数组](#22-array) 15 | 2.3. [字符串替换](#23-string-substitution) 16 | 2.4. [函数](#24-functions) 17 | 2.5. [条件语句](#25-conditionals) 18 | 2.6. [循环语句](#26-loops) 19 | 3. [小技巧](#3-tricks) 20 | 4. [调试](#4-debugging) 21 | 22 | 23 | # 1. 基本操作 24 | 25 | ### a. `export` 26 | 输出所有的环境变量。 如果你想查看某个特定变量的值,用`echo $VARIABLE_NAME` 27 | ```bash 28 | export 29 | ``` 30 | 示例: 31 | ```bash 32 | $ export 33 | AWS_HOME=/Users/adnanadnan/.aws 34 | LANG=en_US.UTF-8 35 | LC_CTYPE=en_US.UTF-8 36 | LESS=-R 37 | 38 | $ echo $AWS_HOME 39 | /Users/adnanadnan/.aws 40 | ``` 41 | 42 | ### b. `whatis` 43 | whatis 显示某个用户命令、系统调用或库函数的描述文档,或操作手册中存在的其他文档。 44 | ```bash 45 | whatis something 46 | ``` 47 | 示例: 48 | ```bash 49 | $ whatis bash 50 | bash (1) - GNU Bourne-Again SHell 51 | ``` 52 | 53 | ### c. `whereis` 54 | whereis 查找可执行文件、源文件或者说明文档的位置,使用的是一个系统自动构建的数据库。 55 | ```bash 56 | whereis name 57 | ``` 58 | 示例: 59 | ```bash 60 | $ whereis php 61 | /usr/bin/php 62 | ``` 63 | 64 | ### d. `which` 65 | which 在环境变量 PATH 指定的所有文件夹中查找可执行文件的位置。它会打印出可执行文件的绝对路径。 66 | ```bash 67 | which program_name 68 | ``` 69 | 示例: 70 | ```bash 71 | $ which php 72 | /c/xampp/php/php 73 | ``` 74 | 75 | ### e. clear 76 | 清空窗口中的内容。 77 | 78 | ## 1.1. File Operations 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 |
catchmodchowncpdifffilefindgunzipgzcatgziphead
lpqlprlprmlsmoremvrmtailtouch
105 | 106 | ### a. `cat` 107 | 在 UNIX 和 Linux 中,它有以下几种用途 108 | * 把文本文件显示在屏幕上 109 | * 复制文本文件 110 | * 合并文本文件 111 | * 创建新的文本文件 112 | ```bash 113 | cat filename 114 | cat file1 file2 115 | cat file1 file2 > newcombinedfile 116 | cat < file1 > file2 #copy file1 to file2 117 | ``` 118 | 119 | ### b. `chmod` 120 | `chmod` 是 `change mod` 的意思,它用来改变文件或文件夹的读、写和执行权限。详细信息参见[这个链接](https://ss64.com/bash/chmod.html) 121 | ```bash 122 | chmod -options filename 123 | ``` 124 | 125 | ### c. `chown` 126 | `chown` 是 `change owner` 的意思,它用来改变一个文件或者文件夹的所有者,所有者可以是一个用户或一个用户组。 127 | ```bash 128 | chown -options user:group filename 129 | ``` 130 | 131 | ### d. `cp` 132 | 把一个文件从一个位置复制到另外一个位置 133 | ```bash 134 | cp filename1 filename2 135 | ``` 136 | 上面 `filename1` 是源文件位置, `filename2` 是目标位置(精确到文件名)。 137 | 138 | ### e. `diff` 139 | 比对两个文件,输出他们的差异。 140 | ```bash 141 | diff filename1 filename2 142 | ``` 143 | 144 | ### f. `file` 145 | 检测文件类型 146 | ```bash 147 | file filename 148 | ``` 149 | 示例: 150 | ```bash 151 | $ file index.html 152 | index.html: HTML document, ASCII text 153 | ``` 154 | ### g. `find` 155 | 在某个文件夹中用一定规则查找文件 156 | ```bash 157 | find directory options pattern 158 | ``` 159 | 示例: 160 | ```bash 161 | $ find . -name README.md 162 | $ find /home/user1 -name '*.png' 163 | ``` 164 | 165 | ### h. `gunzip` 166 | 解压用 gzip 方法压缩的文件 167 | ```bash 168 | gunzip filename 169 | ``` 170 | 171 | ### i. `gzcat` 172 | 在不解压的情况下,查看 gzip 压缩过的文件 173 | ```bash 174 | gzcat filename 175 | ``` 176 | 177 | ### j. `gzip` 178 | 压缩文件 179 | ```bash 180 | gzip filename 181 | ``` 182 | 183 | ### k. `head` 184 | 输出文件的前 10 行 185 | ```bash 186 | head filename 187 | ``` 188 | 189 | ### l. `lpq` 190 | 输出打印机列表 191 | ```bash 192 | lpq 193 | ``` 194 | 示例: 195 | ```bash 196 | $ lpq 197 | Rank Owner Job File(s) Total Size 198 | active adnanad 59 demo 399360 bytes 199 | 1st adnanad 60 (stdin) 0 bytes 200 | ``` 201 | 202 | ### m. `lpr` 203 | 打印一个文件 204 | ```bash 205 | lpr filename 206 | ``` 207 | 208 | ### n. `lprm` 209 | 从打印机任务队列中移除某个任务 210 | ```bash 211 | lprm jobnumber 212 | ``` 213 | 214 | ### o. `ls` 215 | 列出当前文件夹下所有文件。`ls` 有很多选项:`-l` 以详细信息格式列出文件,详细信息包括文件实际大小,文件所有者,可查看者,以及最后修改时间。`-a` 列出所有文件,包括隐藏文件。更多信息参见[这个链接](https://ss64.com/bash/ls.html) 216 | ```bash 217 | ls option 218 | ``` 219 | 示例: 220 |
 221 | $ ls -la
 222 | rwxr-xr-x   33 adnan  staff    1122 Mar 27 18:44 .
 223 | drwxrwxrwx  60 adnan  staff    2040 Mar 21 15:06 ..
 224 | -rw-r--r--@  1 adnan  staff   14340 Mar 23 15:05 .DS_Store
 225 | -rw-r--r--   1 adnan  staff     157 Mar 25 18:08 .bumpversion.cfg
 226 | -rw-r--r--   1 adnan  staff    6515 Mar 25 18:08 .config.ini
 227 | -rw-r--r--   1 adnan  staff    5805 Mar 27 18:44 .config.override.ini
 228 | drwxr-xr-x  17 adnan  staff     578 Mar 27 23:36 .git
 229 | -rwxr-xr-x   1 adnan  staff    2702 Mar 25 18:08 .gitignore
 230 | 
231 | 232 | ### p. `more` 233 | 输出一个文件的第一部分(用空格移动,按 q 退出) 234 | ```bash 235 | more filename 236 | ``` 237 | 238 | ### q. `mv` 239 | 把一个文件从一个位置移动到另一个位置 240 | ```bash 241 | mv filename1 filename2 242 | ``` 243 | 上面`filename1` 是源文件的路径, `filename2`是目标路径。(都精确到文件名) 244 | 245 | 它也可以用来重命名文件 246 | ```bash 247 | mv old_name new_name 248 | ``` 249 | 250 | ### r. `rm` 251 | 删除一个文件 252 | `rm: directory: is a directory` 253 | 如果想删除文件夹,需要添加 `r` 参数,这样会递归的删除文件夹内所有内容。可以使用 `f` 参数强制删除,略过确认环节。 254 | ```bash 255 | rm filename 256 | ``` 257 | 258 | ### s. `tail` 259 | 输出文件的最后 10 行。添加`-f`可以动态输出文件新添加的文本。 260 | ```bash 261 | tail filename 262 | ``` 263 | 264 | ### t. `touch` 265 | 更新某个文件的访问和修改时间戳,如果文件不存在,将会被创建。 266 | ```bash 267 | touch filename 268 | ``` 269 | 示例: 270 | ```bash 271 | $ touch trick.md 272 | ``` 273 | 274 | ## 1.2. 文本操作 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 |
awkcutechoegrepfgrepfmtgrepnlsedsort
truniqwc
295 | 296 | ### a. `awk` 297 | awk 是文本操作最有用的命令。它按行处理整个文件,它默认用空格把每一行分隔成很多字段。最常用的语法是: 298 | 299 | ```bash 300 | awk '/search_pattern/ { action_to_take_if_pattern_matches; }' file_to_parse 301 | ``` 302 | 303 | 以 `/etc/passwd` 文件为例,该文件包含以下数据: 304 | ``` 305 | root:x:0:0:root:/root:/usr/bin/zsh 306 | daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin 307 | bin:x:2:2:bin:/bin:/usr/sbin/nologin 308 | sys:x:3:3:sys:/dev:/usr/sbin/nologin 309 | sync:x:4:65534:sync:/bin:/bin/sync 310 | ``` 311 | 我们想从这个文件中过滤出每一行的 username 部分。`-F` 参数用来指明用来把行内内容分隔的分隔符。这个例子中,我们用`:`来分隔。`{ print $1 }` 意思是输出行内第一个匹配的字段。 312 | ```bash 313 | awk -F':' '{ print $1 }' /etc/passwd 314 | ``` 315 | 执行上面的命令之后,你会得到下面的输出。 316 | ``` 317 | root 318 | daemon 319 | bin 320 | sys 321 | sync 322 | ``` 323 | 更多详细信息,参见[这个链接](https://www.cyberciti.biz/faq/bash-scripting-using-awk) 324 | 325 | 326 | ### b. `cut` 327 | 按行从文件中摘取文本并输出 328 | 329 | *example.txt* 330 | ```bash 331 | red riding hood went to the park to play 332 | ``` 333 | 334 | *用空格分隔每一行,并输出第2,7,9列* 335 | ```bash 336 | cut -d " " -f2,7,9 example.txt 337 | ``` 338 | ```bash 339 | riding park play 340 | ``` 341 | 342 | ### c. `echo` 343 | 输出命令之后的文本到标准输出或文件 344 | 345 | *输出 "Hello World"* 346 | ```bash 347 | echo Hello World 348 | ``` 349 | ```bash 350 | Hello World 351 | ``` 352 | 353 | *输出 "Hello World",单词间用换行符分隔* 354 | ```bash 355 | echo -ne "Hello\nWorld\n" 356 | ``` 357 | ```bash 358 | Hello 359 | World 360 | ``` 361 | 362 | ### d. `egrep` 363 | 输出文件中匹配指定模式的行,是 grep 命令的扩展模式,支持更多正则表达式(等同于 `grep -E`)。 364 | 365 | *example.txt* 366 | ```bash 367 | Lorem ipsum 368 | dolor sit amet, 369 | consetetur 370 | sadipscing elitr, 371 | sed diam nonumy 372 | eirmod tempor 373 | invidunt ut labore 374 | et dolore magna 375 | aliquyam erat, sed 376 | diam voluptua. At 377 | vero eos et 378 | accusam et justo 379 | duo dolores et ea 380 | rebum. Stet clita 381 | kasd gubergren, 382 | no sea takimata 383 | sanctus est Lorem 384 | ipsum dolor sit 385 | amet. 386 | ``` 387 | 388 | *输出包含 Lorem 或 dolor 的行* 389 | ```bash 390 | egrep '(Lorem|dolor)' example.txt 391 | or 392 | grep -E '(Lorem|dolor)' example.txt 393 | ``` 394 | ```bash 395 | Lorem ipsum 396 | dolor sit amet, 397 | et dolore magna 398 | duo dolores et ea 399 | sanctus est Lorem 400 | ipsum dolor sit 401 | ``` 402 | 403 | ### e. `fgrep` 404 | 输出文件中包含给定字符串的行,指定的模式将不被认做正则,而是字符串。(等同于:`grep -F`) 405 | 406 | *example.txt* 407 | ```bash 408 | Lorem ipsum 409 | dolor sit amet, 410 | consetetur 411 | sadipscing elitr, 412 | sed diam nonumy 413 | eirmod tempor 414 | foo (Lorem|dolor) 415 | invidunt ut labore 416 | et dolore magna 417 | aliquyam erat, sed 418 | diam voluptua. At 419 | vero eos et 420 | accusam et justo 421 | duo dolores et ea 422 | rebum. Stet clita 423 | kasd gubergren, 424 | no sea takimata 425 | sanctus est Lorem 426 | ipsum dolor sit 427 | amet. 428 | ``` 429 | 430 | * 输出在 example.txt 中包含字符串 `(Lorem|dolor)` 的所有行* 431 | ```bash 432 | fgrep '(Lorem|dolor)' example.txt 433 | or 434 | grep -F '(Lorem|dolor)' example.txt 435 | ``` 436 | ```bash 437 | foo (Lorem|dolor) 438 | ``` 439 | 440 | ### f. `fmt` 441 | 简单的文本格式化工具 442 | 443 | *example: example.txt (1 行)* 444 | ```bash 445 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 446 | ``` 447 | 448 | *把 example.txt 格式化为 20 个字符的宽度* 449 | ```bash 450 | cat example.txt | fmt -w 20 451 | ``` 452 | ```bash 453 | Lorem ipsum 454 | dolor sit amet, 455 | consetetur 456 | sadipscing elitr, 457 | sed diam nonumy 458 | eirmod tempor 459 | invidunt ut labore 460 | et dolore magna 461 | aliquyam erat, sed 462 | diam voluptua. At 463 | vero eos et 464 | accusam et justo 465 | duo dolores et ea 466 | rebum. Stet clita 467 | kasd gubergren, 468 | no sea takimata 469 | sanctus est Lorem 470 | ipsum dolor sit 471 | amet. 472 | ``` 473 | 474 | ### g. `grep` 475 | 在文件中查找文本。你可以用 grep 去查找匹配一个或多个正则表达式的文本行,然后输出这些行。 476 | ```bash 477 | grep pattern filename 478 | ``` 479 | 示例: 480 | ```bash 481 | $ grep admin /etc/passwd 482 | _kadmin_admin:*:218:-2:Kerberos Admin Service:/var/empty:/usr/bin/false 483 | _kadmin_changepw:*:219:-2:Kerberos Change Password Service:/var/empty:/usr/bin/false 484 | _krb_kadmin:*:231:-2:Open Directory Kerberos Admin Service:/var/empty:/usr/bin/false 485 | ``` 486 | 你也可以通过 `-i` 参数强制忽略大小写。参数`-r`则被用来递归地查找指定文件夹下的所有文件,例如: 487 | ```bash 488 | $ grep -r admin /etc/ 489 | ``` 490 | 参数 `-w` 表示只查找单词。关于 `grep`的更多信息,参见[这个链接](https://www.cyberciti.biz/faq/grep-in-bash) 491 | 492 | ### h. `nl` 493 | 给文件添加行号并输出 494 | 495 | *example.txt* 496 | ```bash 497 | Lorem ipsum 498 | dolor sit amet, 499 | consetetur 500 | sadipscing elitr, 501 | sed diam nonumy 502 | eirmod tempor 503 | invidunt ut labore 504 | et dolore magna 505 | aliquyam erat, sed 506 | diam voluptua. At 507 | vero eos et 508 | accusam et justo 509 | duo dolores et ea 510 | rebum. Stet clita 511 | kasd gubergren, 512 | no sea takimata 513 | sanctus est Lorem 514 | ipsum dolor sit 515 | amet. 516 | ``` 517 | 518 | *给 example.txt 中的内容添加行号并输出* 519 | ```bash 520 | nl -s". " example.txt 521 | ``` 522 | ```bash 523 | 1. Lorem ipsum 524 | 2. dolor sit amet, 525 | 3. consetetur 526 | 4. sadipscing elitr, 527 | 5. sed diam nonumy 528 | 6. eirmod tempor 529 | 7. invidunt ut labore 530 | 8. et dolore magna 531 | 9. aliquyam erat, sed 532 | 10. diam voluptua. At 533 | 11. vero eos et 534 | 12. accusam et justo 535 | 13. duo dolores et ea 536 | 14. rebum. Stet clita 537 | 15. kasd gubergren, 538 | 16. no sea takimata 539 | 17. sanctus est Lorem 540 | 18. ipsum dolor sit 541 | 19. amet. 542 | ``` 543 | 544 | ### i. `sed` 545 | 用于过滤和替换文本的流式编辑命令 546 | 547 | *example.txt* 548 | ```bash 549 | Hello This is a Test 1 2 3 4 550 | ``` 551 | 552 | *把 example.txt 所有空格替换为连字符并输出* 553 | ```bash 554 | sed 's/ /-/g' example.txt 555 | ``` 556 | ```bash 557 | Hello-This-is-a-Test-1-2-3-4 558 | ``` 559 | 560 | *把所有数字替换为 "d"* 561 | ```bash 562 | sed 's/[0-9]/d/g' example.txt 563 | ``` 564 | ```bash 565 | Hello This is a Test d d d d 566 | ``` 567 | 568 | ### j. `sort` 569 | 对文件中的行进行排序 570 | 571 | *example.txt* 572 | ```bash 573 | f 574 | b 575 | c 576 | g 577 | a 578 | e 579 | d 580 | ``` 581 | 582 | *对 example.txt 中的行进行排序* 583 | ```bash 584 | sort example.txt 585 | ``` 586 | ```bash 587 | a 588 | b 589 | c 590 | d 591 | e 592 | f 593 | g 594 | ``` 595 | 596 | *随机打乱已经排好序的 example.txt*(测试出现问题)// todo 597 | ```bash 598 | sort example.txt | sort -R 599 | ``` 600 | ```bash 601 | b 602 | f 603 | a 604 | c 605 | d 606 | g 607 | e 608 | ``` 609 | 610 | ### k. `tr` 611 | 转换或删除字符 612 | 613 | *example.txt* 614 | ```bash 615 | Hello World Foo Bar Baz! 616 | ``` 617 | 618 | *把所有小写字母转换成大写字母* 619 | ```bash 620 | cat example.txt | tr 'a-z' 'A-Z' 621 | ``` 622 | ```bash 623 | HELLO WORLD FOO BAR BAZ! 624 | ``` 625 | 626 | *把所有的空格都转换为换行符* 627 | ```bash 628 | cat example.txt | tr ' ' '\n' 629 | ``` 630 | ```bash 631 | Hello 632 | World 633 | Foo 634 | Bar 635 | Baz! 636 | ``` 637 | 638 | ### l. `uniq` 639 | 统计或精简重复的行 640 | 641 | *example.txt* 642 | ```bash 643 | a 644 | a 645 | b 646 | a 647 | b 648 | c 649 | d 650 | c 651 | ``` 652 | 653 | *输出 example.txt 中所有不重复的行(需要先进行排序, 否则相同行中间的行会被忽略)* 654 | ```bash 655 | sort example.txt | uniq 656 | ``` 657 | ```bash 658 | a 659 | b 660 | c 661 | d 662 | ``` 663 | 664 | *输出去重后的所有行,并显示不重复行中每一行在原文件中的重复次数* 665 | ```bash 666 | sort example.txt | uniq -c 667 | ``` 668 | ```bash 669 | 3 a 670 | 2 b 671 | 2 c 672 | 1 d 673 | ``` 674 | 675 | ### m. `wc` 676 | 输出文件中的行、单词、字符个数。 677 | ```bash 678 | wc filename 679 | ``` 680 | 示例: 681 | ```bash 682 | $ wc demo.txt 683 | 7459 15915 398400 demo.txt 684 | ``` 685 | demo.txt中有 `7459` 行, `15915` 个单词以及 `398400` 个字符. 686 | 687 | ## 1.3. Directory Operations 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 |
cdmkdirpwd
696 | 697 | ### a. `cd` 698 | 进入某个文件目录,执行: 699 | ```bash 700 | $ cd 701 | ``` 702 | 会进入 `home` 目录。这个命令接受一个可选的目录名称的参数,指示要进入的目录。 703 | ```bash 704 | cd dirname 705 | ``` 706 | 707 | ### b. `mkdir` 708 | 创建一个新文件夹 709 | ```bash 710 | mkdir dirname 711 | ``` 712 | 713 | ### c. `pwd` 714 | 显示当前所在的文件目录(绝对路径) 715 | ```bash 716 | pwd 717 | ``` 718 | 719 | ## 1.4. SSH, System Info & Network Operations 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 |
bgcaldatedfdigdufgfingerjobslast
manpasswdpingpsquotascpsshtopunameuptime
wwgetwhoamiwhois
753 | 754 | ### a. `bg` 755 | 列出所有被停止或后台运行的任务,或将一个已停止的任务后台运行。 756 | 757 | ### b. `cal` 758 | 输出当前月份的日历 759 | 760 | ### c. `date` 761 | 输出当前日期和时间 762 | 763 | ### d. `df` 764 | 输出磁盘使用统计数据 765 | 766 | ### e. `dig` 767 | 输出某个域名的 DNS 信息 768 | ```bash 769 | dig domain 770 | ``` 771 | 772 | ### f. `du` 773 | 输出某些文件或目录的硬盘使用情况。更多详细信息参见[这个链接](http://www.linfo.org/du.html) 774 | ```bash 775 | du [option] [filename|directory] 776 | ``` 777 | Options: 778 | - `-h` (人类可读) 把结果以 KB、 MB 、GB 为单位输出。 779 | - `-s` (压缩总结) 输出一个目录总的磁盘空间占用情况,总结输出子目录的报告。 780 | 781 | 示例: 782 | ```bash 783 | du -sh pictures 784 | 1.4M pictures 785 | ``` 786 | 787 | ### g. `fg` 788 | 输出前台中最近运行的任务 789 | 790 | ### h. `finger` 791 | 输出某个用户的信息 792 | ```bash 793 | finger username 794 | ``` 795 | ### i. `jobs` 796 | 列出在后台运行的任务,同时给出任务号 797 | 798 | ### j. `last` 799 | 列出特定用户的登录记录 800 | ```bash 801 | last yourUsername 802 | ``` 803 | 804 | ### k. `man` 805 | 输出特定命令的使用手册 806 | ```bash 807 | man command 808 | ``` 809 | 810 | ### l. `passwd` 811 | 让当前登录的用户更改他的密码 812 | 813 | ### m. `ping` 814 | ping 某个主机然后输出结果 815 | ```bash 816 | ping host 817 | ``` 818 | 819 | ### n. `ps` 820 | 列出某个用户的所有进程 821 | ```bash 822 | ps -u yourusername 823 | ``` 824 | 825 | ### o. `quota` 826 | 显示磁盘使用量和配额 827 | ```bash 828 | quota -v 829 | ``` 830 | 831 | ### p. `scp` 832 | 在本地主机和远程主机之间或两个远程主机之间传输文件 833 | 834 | *从本地主机复制文件到远程主机* 835 | ```bash 836 | scp source_file user@host:directory/target_file 837 | ``` 838 | *从远程主机复制文件到本地主机* 839 | ```bash 840 | scp user@host:directory/source_file target_file 841 | scp -r user@host:directory/source_folder target_folder 842 | ``` 843 | 这个命令也接受一个参数 `-P`,用来连接指定端口 844 | ```bash 845 | scp -P port user@host:directory/source_file target_file 846 | ``` 847 | 848 | ### q. `ssh` 849 | ssh(SSH 客户端)是一个用来登录到远程主机并执行命令的程序 850 | ```bash 851 | ssh user@host 852 | ``` 853 | 这个命令也接受一个可选参数 `-p`,用来指定连接到特定的端口。 854 | ```bash 855 | ssh -p port user@host 856 | ``` 857 | 858 | ### r. `top` 859 | 动态展示所有活跃的进程 860 | 861 | ### s. `uname` 862 | 输出内核信息 863 | ```bash 864 | uname -a 865 | ``` 866 | 867 | ### t. `uptime` 868 | 输出服务器运行了多长时间以及有多少个用户登录 869 | 870 | ### u. `w` 871 | 输出系统在线用户 872 | 873 | ### v. `wget` 874 | 下载文件 875 | ```bash 876 | wget file 877 | ``` 878 | 879 | ### w. `whoami` 880 | 输出现在登录的用户的用户名 881 | 882 | ### x. `whois` 883 | 获取某个域名的 whois 信息 884 | ```bash 885 | whois domain 886 | ``` 887 | 888 | ## 1.5. Process Monitoring Operations 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 |
killkillall&nohup
898 | 899 | ### a. `kill` 900 | 结束指定 PID 代表的进程 901 | ```bash 902 | kill PID 903 | ``` 904 | 905 | ### b. `killall` 906 | 结束某个名字代表的所有进程 907 | ```bash 908 | killall processname 909 | ``` 910 | 911 | ### c. & 912 | 使得 `&` 之前的命令作为后台进程运行在 subshell 中 913 | ```bash 914 | command & 915 | ``` 916 | 917 | ### d. `nohup` 918 | nohup 代表 `No Hang Up`,也即不要挂起。这条命令允许其它命令、进程或shell脚本在你退出shell之后继续在后台运行 919 | ```bash 920 | nohup command 921 | ``` 922 | 把它和 `&` 结合使用可以创建后台进程 923 | ```bash 924 | nohup command & 925 | ``` 926 | 927 | # 2. Basic Shell Programming 928 | 929 | 930 | 在 bash 脚本文件中的第一行被叫做 `shebang`。这一行决定了脚本可以像一个独立的可执行文件一样执行,而不用在终端之前输入`sh`,`bash`,`python`,`php`等。 931 | 932 | ```bash 933 | #!/bin/bash 934 | ``` 935 | 936 | ## 2.1. Variables 937 | 938 | 在 bash 中创建变量跟其它语言相似。没有变量类型,bash 中的变量可以保存一个数字、一个字符、一个字符串等等。同时无需提前声明变量,给变量赋值会直接创建变量。 939 | 940 | 示例: 941 | ```bash 942 | str="hello world" 943 | ``` 944 | 945 | 上面一行创建了一个变量 `str` 然后把 "hello world" 赋值给它。通过在变量名之前添加`$`符号,可以取到变量里面保存的值。 946 | 947 | 示例: 948 | ```bash 949 | echo $str # hello world 950 | ``` 951 | ## 2.2. Array 952 | 像其它语言一样,bash 也有数组类型。bash 中的数组是一个保存着很多值的变量,数组的长度没有限制,下标也是从 0 开始。在 bash 中有好几种方法创建一个数组,如下所示。 953 | 954 | Examples: 955 | ```bash 956 | array[0] = val 957 | array[1] = val 958 | array[2] = val 959 | array=([2]=val [0]=val [1]=val) 960 | array=(val val val) 961 | ``` 962 | 使用如下语法获得数组特定位置的值: 963 | 964 | ```bash 965 | ${array[i]} # i是数组下标 966 | ``` 967 | 968 | 如果没有指定数组下标,默认返回第一个元素。想知道数组中有多少个元素,使用下面的语法: 969 | 970 | ```bash 971 | ${#array[@]} 972 | ``` 973 | 974 | Bash 也支持三元运算符,如下面的例子所示: 975 | 976 | ```bash 977 | ${varname:-word} # 如果 varname 存在而且不为 null,返回它的值,否则返回 word 978 | ${varname:=word} # 如果 varname 存在而且不为 null,返回它的值,否则把word赋值给它并且返回 word 979 | ${varname:+word} # 如果 varname 存在而且不为 null,返回 word,否则返回 null 980 | ${varname:offset:length} # 它返回 $varname 的子字符串,从 offset 处开始,长度为 length 981 | ``` 982 | 983 | ## 2.3 String Substitution 984 | 985 | 通过下面的语法来学习字符串相关操作 986 | 987 | ```bash 988 | ${variable#pattern} # 如果 pattern 匹配变量值的起始部分,删除匹配 pattern 的最短的部分,然后返回剩余的 989 | ${variable##pattern} # 如果 pattern 匹配变量值的起始部分,删除匹配 pattern 的最长的部分,然后返回剩余的 990 | ${variable%pattern} # 如果 pattern 匹配变量值的结束部分,删除匹配 pattern 的最短的部分,然后返回剩余的 991 | ${variable%%pattern} # 如果 pattern 匹配变量值的结束部分,删除匹配 pattern 的最长的部分,然后返回剩余的 992 | ${variable/pattern/string} # 把变量值中匹配 pattern 的最长的部分替换为 string,只替换第一个匹配的部分 993 | ${variable//pattern/string} # 把变量值中匹配 pattern 的最长的部分替换为 string,全局进行替换 994 | ${#varname} # 返回变量值作为一个字符串的长度 995 | ``` 996 | 997 | ## 2.4. Functions 998 | As in almost any programming language, you can use functions to group pieces of code in a more logical way or practice the divine art of recursion. Declaring a function is just a matter of writing . Calling a function is just like calling another program, you just write its name. 999 | 就像在其它编程语言中那样,您可以使用 function 来以更合乎逻辑的方式聚合代码,或实现递归的神圣艺术。声明一个 function 只需要写下`function my_func { my_code }` ,调用 function 就像调用另外的程序一样,使用方法名称即可。 1000 | 1001 | ```bash 1002 | function name() { 1003 | shell commands 1004 | } 1005 | ``` 1006 | 1007 | 示例: 1008 | ```bash 1009 | #!/bin/bash 1010 | function hello { 1011 | echo world! 1012 | } 1013 | hello 1014 | 1015 | function say { 1016 | echo $1 1017 | } 1018 | say "hello world!" 1019 | ``` 1020 | 1021 | 当你运行上面例子中的 hello 方法时,它会输出 "world!"。上面的两个方法 `hello` 和 `say` 一模一样的, `say` 有一些不同,这个方法会打印出它接受到的第一个参数。方法中的参数,跟脚本语言中的处理方式一样。 1022 | 1023 | ## 2.5. Conditionals 1024 | 1025 | bash 中的条件语句跟其他编程语言类似。条件语句有很多种形式,就像最常见的基本形式是 `if` 表达式 `then` 语句,代表如果表达式为真,则执行响应的语句。 1026 | 1027 | ```bash 1028 | if [expression]; then 1029 | will execute only if expression is true 1030 | else 1031 | will execute if expression is false 1032 | fi 1033 | ``` 1034 | 1035 | 有些时候如果条件语句变得太复杂,你可以用 `case statements` 来完成相同的条件判断功能。 1036 | 1037 | ```bash 1038 | case expression in 1039 | pattern1 ) 1040 | statements ;; 1041 | pattern2 ) 1042 | statements ;; 1043 | ... 1044 | esac 1045 | ``` 1046 | 1047 | Expression Examples: 1048 | 1049 | ```bash 1050 | statement1 && statement2 # 两个语句都为真 1051 | statement1 || statement2 # 至少一个语句为真 1052 | 1053 | str1=str2 # str1 匹配 str2 1054 | str1!=str2 # str1 不匹配 str2 1055 | str1str2 # str1 大于 str2 1057 | -n str1 # str1 不是 null (长度大于 0) 1058 | -z str1 # str1 是 null (长度为 0) 1059 | 1060 | -a file # 文件存在 1061 | -d file # 文件存在而且是目录 1062 | -e file # 文件存在,跟 -a 一样 1063 | -f file # 文件存在,而且是常规文件(不是目录或者其他特殊类型的文件) 1064 | -r file # 你有读权限 1065 | -s file # 文件存在而且不为空 1066 | -w file # 你有写权限 1067 | -x file # 你对文件有执行权限,如果 file 是目录的话,你对它有搜索权限 1068 | -N file # 从上次读之后文件被修改过 1069 | -O file # 你是文件所有者 1070 | -G file # 文件的 group ID 跟你的 group ID (或之一,如果你在很多分组里)相同 1071 | 1072 | file1 -nt file2 # file1 比 file2 更新 1073 | file1 -ot file2 # file1 比 file2 更老 1074 | 1075 | -lt # 小于 1076 | -le # 小于等于 1077 | -eq # 等于 1078 | -ge # 大于等于 1079 | -gt # 大于 1080 | -ne # 不等于 1081 | ``` 1082 | 1083 | ## 2.6. Loops 1084 | 1085 | bash 中有三种类型的循环。`for`, `while` 和 `until`。 1086 | 1087 | 不同的 `for` 语法: 1088 | ```bash 1089 | for x := 1 to 10 do 1090 | begin 1091 | statements 1092 | end 1093 | 1094 | for name [in list] 1095 | do 1096 | statements that can use $name 1097 | done 1098 | 1099 | for (( initialisation ; ending condition ; update )) 1100 | do 1101 | statements... 1102 | done 1103 | ``` 1104 | 1105 | `while` 语法: 1106 | ```bash 1107 | while condition; do 1108 | statements 1109 | done 1110 | ``` 1111 | 1112 | `until` 语法: 1113 | ```bash 1114 | until condition; do 1115 | statements 1116 | done 1117 | ``` 1118 | 1119 | # 3. Tricks 1120 | 1121 | ## 设置别名 1122 | 执行 `nano ~/.bash_profile` 来打开 `bash_profile`。 1123 | > alias dockerlogin='ssh www-data@adnan.local -p2222' # 在 .bash_profile 中设置别名 1124 | 1125 | ## 快速进入某个目录 1126 | nano ~/.bashrc 1127 | > export hotellogs="/workspace/hotel-api/storage/logs" 1128 | 1129 | ```bash 1130 | source ~/.bashrc 1131 | cd $hotellogs 1132 | ``` 1133 | 1134 | ## 跳出陷阱 1135 | 1136 | 通过执行清理语句使得你的脚本更有鲁棒性 1137 | 1138 | ```bash 1139 | function finish { 1140 | # 在这里执行清理语句,例如,杀掉所有 fork 的进程。 1141 | jobs -p | xargs kill 1142 | } 1143 | trap finish EXIT 1144 | ``` 1145 | 1146 | ## 保存环境变量 1147 | 1148 | 当你在 shell 中执行 `export FOO = BAR`, 环境变量只在当前 shell 和它的子 shell 中存在,如果想在将来能够永久使用这个环境变量,只需要在 `~/.bash_profile` 文件后面添加要执行的命令即可。 1149 | ```bash 1150 | echo export FOO=BAR >> ~/.bash_profile 1151 | ``` 1152 | 1153 | ## 访问你的脚本 1154 | 1155 | 通过在 home 目录下创建 bin 文件夹, 你可以很容易的访问你的脚本,`mkdir ~/bin` 之后,在 bin 目录里面的所有脚本都能在任何别的目录下访问到。 1156 | 1157 | 如果还是不能访问,把下面的代码添加到 `~/.bash_profile` 文件中,然后执行`source ~/.bash_profile`。 1158 | ```bash 1159 | # 如果用户的私有 bin 目录存在的话,把它添加到 PATH 变量中 1160 | if [ -d "$HOME/bin" ] ; then 1161 | PATH="$HOME/bin:$PATH" 1162 | fi 1163 | ``` 1164 | 1165 | # 4. 调试 1166 | 你可以很容易地通过传递不同的参数给 `bash` 命令来调试脚本。例如, `-n` 将会只检查脚本的语法错误而不执行脚本。 `-v` 将会在命令执行前输出它们。 `-x` 将会在命令行处理之后输出命令。 1167 | 1168 | ```bash 1169 | bash -n scriptname 1170 | bash -v scriptname 1171 | bash -x scriptname 1172 | ``` 1173 | 1174 | ## 贡献 1175 | 1176 | - 报告问题 [How to](https://help.github.com/articles/creating-an-issue/) 1177 | - 提交改进型的合并请求 [How to](https://help.github.com/articles/about-pull-requests/) 1178 | - 帮助传播 1179 | 1180 | ## Translation 1181 | - [Turkish | Türkçe](https://github.com/omergulen/bash-guide) 1182 | - [Japanese | 日本語](https://github.com/itooww/bash-guide) 1183 | 1184 | ## License 1185 | 1186 | [![License: CC BY 4.0](https://img.shields.io/badge/License-CC%20BY%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by/4.0/) 1187 | --------------------------------------------------------------------------------