UP | HOME

Shell

Table of Contents

shell命令解析流程

常见命令

文本处理

  • grep
  • sed
  • awk
  • sort
  • diff
  • vi

其他常用命令

  • crontab
  • curl 支持ftp,http等多种协议处理
  • find
  • ftp
  • file 查看文件类型
  • free
  • lsof 查看打开的文件(文件被哪个进程打开;进程打开了哪些文件)
  • jq 处理json
  • pgrep
  • ps
  • top
  • tar
  • tcpdump
  • rsync 文件拷贝同步,支持远程拷贝,使用差量快速同步
  • df
  • du
  • bc 强大的可编程计算器
  • md5sum
  • hexdump
  • usradd
  • usrmod
  • chown
  • chmod

学会看手册

命令有很多,而且选项也很多,单靠记忆是很难全部记住的。所以要学会 RTFM。下面是看手册也的一些基本要点:

  • man man
  • 手册页
       The table below shows the section numbers of the manual followed by the types  of  pages  they contain.

       1   Executable programs or shell commands
       2   System calls (functions provided by the kernel)
       3   Library calls (functions within program libraries)
       4   Special files (usually found in /dev)
       5   File formats and conventions eg /etc/passwd
       6   Games
       7   Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7)
       8   System administration commands (usually only for root)
       9   Kernel routines [Non standard]

初探

原则

  • 一次做好一件事
  • 处理文本,不要处理二进制数据
    文本易懂,而且可用的工具更多。
  • 使用正则表达式
    使用正则,功能会更强大。
  • 默认使用标准输入/输出
    为了和其他工具在管道中使用
  • 避免喋喋不休
    仅输出必要的信息。unix工具程序遵循你叫它做什么,它就做什么的设计哲学。它们不会问“Are you sure?”
  • 输出格式必须与可接受的输入格式一致
    保持输入格式一致,以便其他工具可以继续处理
  • 让工具去做困难的部分
    尽量使用已有成熟的工具
  • 构建特定工具前,先想一想
    是否有必要,其他人是否也要做,是否这个特殊的要求是一个一般的要求的特例?

规范

可以参考 google shell脚本编程规范
这里特别提两点,变量名使用小写加小划线,环境变量以及全局变量放开头,并用大写加下划线;
shell脚本不需要用.sh作为结尾,除非是作为库函数使用,而且作为库函数使用时,不需要有执行权限。之所以不需要以.sh结尾的原因在于,文件后缀对于
Linux下的可执行文件没有特殊意义,另外,脚本有可能使用其他语言重写,调用方只需要知道脚本的功能,没有必要知道脚本的编写语言。

执行

Linux在执行命令的时候,首先会判断命令是否是一个可执行的二进制文件,如果是,则直接执行。如果不是且文件以`#!`开头,则把该命令作为一个脚本执行(解释器文件)。并以`#!`后面指定的命令作为解释器。
例子

#!/path/to/cmd -pf
script content comes here...

变量

bash支持定义readonly变量,整型变量等。

条件判断

bash支持if条件判断(条件测试包括文件是否存在,命令是否执行成功等。

循环

ash支持for以及while循环语句。

参考

日常使用

一些不好的习惯

  • 可执行脚本以.sh后缀结尾
  • 脚本第一行不是#!/bin/bash
  • 喜欢使用root用户或其他具有超级用户权限的用户操作
    这样做的坏处首先是不安全,跳过了系统按用户以及权限划分的边界,很容易误操作。打乱了系统的管理。同时,使用超级用户进行日常操作,就像一个野蛮人一
    样,侵犯了正常操作的普通用户以及造成不便。在公共服务器上,使用超级用户权限时,需要尊重其他人。
  • 给文件或目录加上777权限
    没有必要,而且不符合最小权限的原则。
  • 习惯一问一答的操作,例如rm -i以及mv -i等
    这样一问一答的操作浪费时间,特别是这种日常操作更是如此。另外,这里有一个陷阱,以rm -i为例子,确认式删除好像看起来操作更加谨慎,但实际上可能在
    习惯了这种操作之后,还是会顺手输入确认,导致误删。从这个角度而言,直接删除和交互式删除是一样。但是交互式删除浪费了更多的时间,而且,另一方面,
    时刻提醒自己,一旦执行rm}就会删除,会让你在删除时更加谨慎,并养成习惯。真正谨慎的操作是养成谨慎的习惯。
  • 脚本不检查输入
    严格检查外部输入,内部错误则要快速出错。
  • 文件或目录名称滥用大写字母
    一般使用大写字母的作用是为了强调,但是如果滥用大写字母,就起不到强调的作用了!就像到处使用叹号一样!!而且输入的时候,要多按一个shift键!!!

一些好的习惯

  • 保证脚本在任何工作目录都可以正常执行,关键是在脚本里使用绝对路径。
  • 合理使用引号。例如,grep的*pattern*参数最好用单引号包起来。
  • 谨慎处理批量操作,尽量精确匹配。特别是删除文件等。
  • 文件或目录名不要包含对shell有特殊含义的特殊字符,例如() , > , |等。
  • 从标准输入读入数据,输出到标准输出,同时错误信息输出到标准错误

一些容易混淆的概念

环境变量

设置环境变量仅对当前进程以及它的子进程有效。

技巧

脚本传递参数

举例

#!/bin/bash
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";

sh ./dem.sh 1 2 3
执行的文件名:./demo.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3

特殊字符

参数处理 说明
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数
$- 显示Shell使用的当前选项,与set命令功能相同
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误

参考

First created: 2021-02-20 Sat 00:00
Last updated: 2022-05-25 Wed 23:26
Power by Emacs 27.1 (Org mode 9.4)
© 2017 – 2021 by josephzeng