Bash编程陷阱二
当前文章接着Bash编程陷阱一写下来。
24. for arg in $*
bash使用$*或者$@来承担脚本的所有入参,但用for遍历的时候需要注意
for arg in "$@" # 或者更简单的写法 for arg
这里的$@需要添加上"",此处的"$@"相当于"$1","$2","$3",而非"$1 $2 $3"
加引号的目的自然是预防空格,如果$1存在空格,那么就多出一个参数
25. function foo()
function的写法并不在所有的shell解释器中兼容。请使用
foo() { ... }
26. echo "~"
~符号只有被引号括起来的时候才能转换为home目录的绝对地址,在""中只能打印出~符号,在特殊的日志输出里面需要注意。
示例:
tmp/oenhan $ echo ~/ /home/oenhan/ tmp/oenhan $ echo "~/" ~/
27. local varname=$(command)
一般情况下,在其后使用ret=$?获取command的返回值,但事实上获取是local定义的返回值,应该如下写法
local varname varname=$(command) rc=$?
28. export foo=~/bar
~并不在所有shell解释器中自动转换为home的绝对路径,不过bash里面是支持的。
29. sed 's/$foo/good bye/'
单引号里面不会转换$foo变量,可以使用双引号,当然,双引号内考虑的事情更多了
强迫症患者可能感觉不太美观,可以换成如下样子
sed 's/'$foo'/good bye/'
看起来有点乱,其实是正常的。
30. tr [A-Z] [a-z]
这样写法有三个问题,1,[a-z]被认为是通配符,如果当前没有单字母命名的文件,执行应该是OK的,否则就会对文件操作了。2.tr转换字符将[转换为对应的[,没有意义,直接去掉。3,A-Z在不同的语言环境中不一定会代表26个 ASCII 字母,使用前需要设定语言环境
LC_COLLATE=C tr A-Z a-z
不建议上面这个写法,推荐man手册中的写法
tr '[:upper:]' '[:lower:]'
31. ps ax | grep gedit
靠名称判断进程不靠谱,具体不解释
32. printf "$foo"
当foo中有特殊字符作为printf参数存在的时候,直接使用printf是有害的
需要在printf后面加上打印格式,示例:
$ foo='a%sdn' $ printf $foo ad $ printf %s $foo a%sdn
33. for i in {1..$n}
此处的$n不会展开,{x..y}
的展开的限制条件是:1) 整数或者单个字符; 2)两者要是同一个类型。{1..$n}不满足以上条件。具体参考GNU手册
具体实现推荐直接使用for循环搞定
34. if [[ $foo = $bar ]]
[[]]里面不加引号会做模式匹配,$bar如果*,则结果永远为真。
35. if [[ $foo =~ 'some RE' ]]
加''后正则表达式就失效了,和34结果相反。
36. [ -n $foo ] or [ -z $foo ]
仍然是字符串没有加引号,不为空有空格或者为空,都会有语法错误。
37. [[ -e "$broken_symlink" ]] returns 1 even though $broken_symlink exists
-e判断一个文件是否存在,但在判断软链接的时候,实际返回值是链接文件是否存在的结果;即链接的目标文件不存在,但软链接仍然存在,此时仍然返回失败。符号链接的判断建议用-L处理。
38. ed file <<<"g/d{0,3}/s//e/g" fails
ed使用的正则表达式,不支持0的出现次数
39. expr sub-string fails for "match"
match是expr的关键字,使用的时候需要加+号
word=match expr + "$word" : ".(.*)" atch
expr古董般难用的命令,应该被抛弃了
40. On UTF-8 and Byte-Order Marks (BOM)
BOM在脚本执行的时候和win的换行符一样可能有问题。
41. content=$(<file)
所有内容只有1行,换行符丢掉了
42. for file in ./* ; do if [[ $file != *.* ]]
file的字符串会带上./,在匹配的时候就会有问题。
43. somecmd 2>&1 >>logfile
解释器对位置敏感,此处相当于somecmd >> logfile;somecmd 2 >&1
Bash编程陷阱二来自于OenHan
链接为:https://oenhan.com/bash-pitfalls-2