重新学习Bash脚本(二)

2019-05-27

书接上回

重新学习Bash脚本(一)

数据流重定向

重定向:将命令的输入由标准IO(键盘)转移至文件;或将命令的输出由标准IO(Terminal)转移至文件;

$ ls > ls.log
$ cat ls.log 
  • 运算符

    • 标准输入(stdin):<或«;
    • 标准输出(stdout):>或»;
    • 错误输出(stderr):2>或2»;
  • 单个重定向运算符(比如>)和两个重定向运算符(比如>>)的区别:

    • 单个运算符>:覆盖
    • 两个运算符>>:追加
  • 垃圾桶黑洞/dev/null

    将输出重定向至此,用于忽略信息输出

命令分隔符

  • ;:串行执行命令,从左到右依次执行

    $ sync; sync; shutdown
    
  • &&:若左侧命令为真,才执行右侧指令

    $ ls /tmp/abc && touch /tmp/abc/hehe
    
  • ||:若左侧命令错误,才执行右侧指令

    $ ls /tmp/abc || mkdir /tmp/abc
    
  • |:管道,将上一个命令的结果传递到下一个命令,详细见下

管道

管道左右的命令关系为:上一个命令的标准输出,重定向到下一个命令作为标准输入。作为右侧管道的命令必须要有接收标准输入的功能才行,比如lessmore等。

管道选取命令:

  • cut:选取列(切割)

    • -d:分隔符,与-f一起用
    • -f:以-d声明的分隔符来切割字符串,选取第几段
    $ echo ${PATH} | cut -d ':' -f 3 #选取PATH中第三条记录
    
  • grep:选取包含特定表达式的行

    $ ps -Af | grep root #选取所有root进程
    

管道整理命令:

  • sort:排序
  • uniq:去除重复数据

总的来说,因为bash中传来传去的几乎都是字符串,管道的设想虽然好,但是实际挺鸡肋的。

脚本文件编写

脚本执行方式

  • bash命令:在子bash进程内执行,执行结果不会对原进程生效(排除子进程执行了export等命令)
  • source命令:在本bash进程内执行,结果生效。

判断表达式

判断命令test和判断符号[]

$ test ! -e file.txt && exit
  • -e判断文件是否存在
  • 若文件不存在,则返回
  • 语法挺奇葩的

参数传递

在一个脚本文件中,有一些默认的变量:

  • $0为脚本名称
  • $1$N为脚本接收的参数
  • $#为参数个数

条件语法:if

if [条件表达式] then
	...
fi

循环语法:while

while [条件表达式]
do
	...
done