白齣




Bash
入门漫谈



张海 二〇一六·八


楝齣







为什么












日用












普遍












强大












便利












举例












简历自动部署












配置文件自动备份












豆芽CI自动上传







黄齣







一切皆字符串





好吧,除了字符串数组。







逻辑运算




if test '1' -lt '0'

if [[ 1 -lt 0 ]]







算数运算




((++a))

a="$(expr "${a}" + 1)"


赤齣







「  」





用于划分参数。







Unix工具





做一件事,做好它。







接口





int main(int argc, char *argv[]);







分隔





一个或多个空白字符,立即分隔。

$ echo These are	four arguments
These are four arguments

$ printf '%s\n' These are	four arguments
These
are
four
arguments






连接





没有空白字符,则是一体。

$ printf '%s\n' "While	this"_is_'one'
While	this_is_one






引号





只为连接空白,不影响命令调用。

$ 'echo' echo is executed
echo is executed

$ "e"c'h'\o echo is executed
echo is executed






当心






$ rm -rf /usr/lib/nvidia-current/xorg/xorg

$ rm -rf /usr /lib/nvidia-current/xorg/xorg

$ rm -rf '/usr/lib/nvidia-current/xorg/xorg'
$ rm -rf '/usr /lib/nvidia-current/xorg/xorg'
$ [[1 -lt 0]]
bash: [[1: command not found

$ '[[' 1 -lt 0 ]]
bash: [[: command not found

$ [[ 1 -lt 0 ]]; echo "$?"
1
$ variable = cat is cute
bash: variable: command not found

$ variable= cat is cute
cat: is: 没有那个文件或目录
cat: cute: 没有那个文件或目录

$ variable='' cat is cute
cat: is: 没有那个文件或目录
cat: cute: 没有那个文件或目录

$ variable=cat is cute
bash: is: command not found

$ variable='cat' is cute
bash: is: command not found
$ variable='cat is cute'; echo "${variable}"
cat is cute

紫齣







替换和展开





字面、原地替换。







变量替换"${}"





变量名被替换为变量的值。

$ file='a simple file.txt'
$ cat $file
cat: a: 没有那个文件或目录
cat: simple: 没有那个文件或目录
cat: file.txt: 没有那个文件或目录

$ cat "${file}"






命令替换"$()"





命令被替换为标准输出。

$ date
2016年 08月 09日 星期二 16:01:33 CST
$ printf '%s\n' $(date)
2016年
08月
09日
星期二
16:01:54
CST

$ printf '%s\n' "$(date)"
2016年 08月 09日 星期二 16:02:21 CST






命令替换内的引号





引号可以嵌套的语言。

$ echo "$(echo "string1 string2")"

$ version="$(git describe --long --tags | sed 's/^v//;s/-\([0-9]\+\)-g\([0-9a-f]\+\)/+\1.\2/')"






*? 展开





根据已有文件展开,否则不展开。

$ rm -r /
rm: it is dangerous to operate recursively on ‘/’
rm: use --no-preserve-root to override this failsafe

$ rm -r /*

$ echo /*
/bin /boot /data /dev /etc /home /lib /lib64 /lost+found /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var

$ rm -r /bin /boot /data /dev /etc /home /lib /lib64 /lost+found /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var
$ ls
$ echo *
*

$ find -iname '*.md'






{,} 展开





展开当前参数为多个。

$ echo script{,.sh,.csh}
script script.sh script.csh

青齣







参考资源










Advanced Bash-Scripting Guide




http://www.tldp.org/LDP/abs/html/





Google
Shell Style
Guide




https://google.github.io/styleguide/shell.xml





Google
&
StackOverflow




https://www.google.com


黑齣


感谢