第二堂课:
以前没有仔细学过shell script,现在认真学一下。
1.
写一个mcd.sh包含以下内容,并source mcd.sh
mcd () { mkdir -p "$1" cd "$1" }
上述代码是一个函数,因此source时并不会执行任何命令,但是在source之后,主shell就定义了这个函数mcd
接下来在主shell键入 mcd test,就会执行被定义的命令
2.
$0 是脚本名字
$1-$9 是参数
$_ 最后一个参数
$? 从上一个命令获取错误代码。比如当上一个命令执行失败时返回错误代码1,则使用$?会得到1
!! 上一个由于权限不够而执行失败的命令
从上述代码和返回结果来看,可以看出 $? 的作用,以及“|| &&”的作用
NOTE:用了这么多年ubuntu,没想到shell也有" || && ",太牛了
此外,分号 ";" 能够在同一行里串行执行多个命令,无论前面的命令是否失败,后面的命令总会执行(除非linux kernel crash?)。
3.
echo "we are in $(pwd)" :会把$(pwd)里的内容扩展成字符串并打印出来
cat <(ls) <(ls ..) 会把当前目录和父目录下的内容使用cat打印出来 (注意!括号前面不要加空格!否则会报错!)
#!/bin/bash #这一行的意思是使用bash
echo "Starting program at $(date)" # date会被替换成日期和时间
echo "Running program $0 with $# arguments with pid $$"
for file in "$@"; do
grep foobar "$file" > /dev/null 2> /dev/null
# 如果模式没有找到,则grep退出状态为 1
# 我们将标准输出流和标准错误流重定向到Null,因为我们并不关心这些信息
if [[ $? -ne 0 ]]; then
echo "File $file does not have any foobar, adding one"
echo "# foobar" >> "$file"
fi
done
在条件语句中,我们比较 $?
是否等于0。 Bash实现了许多类似的比较操作,您可以查看 test 手册
(NOTE:test手册中包含了许多bash种用于比较的指令)。 在bash中进行比较时,尽量使用双方括号 [[ ]]
而不是单方括号 [ ]
,这样会降低犯错的几率,尽管这样并不能兼容 sh(NOTE: sh不能兼容双方括号)
。
$#:参数个数 $$:进程pid $@:所有的参数,以空格分隔
4.
使用 ls project? "?"会扩展成一个字符,可以是字母也可以是数字,这个命令会把当前目录下所有project1,2,3,a,b,c的列出来,并且列出来这些目录下的内容(深度为1)
例如 shellcheck这样的工具可以帮助你定位sh/bash脚本中的错误。(TODO:一个可以用来debug shell script的工具?!太棒了!)
5.
一个新名词:shebang
In computing, a shebang is the character sequence consisting of the characters number sign and exclamation mark (#!) at the beginning of a script. It is also called sha-bang,[1][2] hashbang,[3][4] pound-bang,[5][6] or hash-pling.[7]
就是像 #!/usr/local/bin/python 这样的东西就叫shebang
6.