sudodpkg-reconfigure dash
在新写的shell脚本里避免使用bash的扩展特性(bashism)。[\( "$foo" = "$bar" -a -f /bin/baz \) -o ! -x /bin/quux ]
应该替换为:
((["$foo" = "$bar" ] && [ -f /bin/baz ]) || [ ! -x/bin/quux ])
不应该使用"[["命令,而应该使用"["命令使用$((…))而不是((…))做算术计算。不能使用$((n++)), $((--n)) ,而应该是$((n=n+1)) 和$((n=n-1))不要使用{}进行字符扩展,例如/usr/lib/libfoo.{a,so}; 避免使用$'…'扩展转义字符。例如,使用"$(printf '\t')" 代替$'\t'不要使用$"…"进行字符串翻译。应该使用gettext.sh脚本。大部分的${…}进行变量扩展都是可移植的。但是下面的几个不是。OPENGL_VERSION=$(glxinfo| grep "OpenGL version string:")
OPENGL_VERSION=${OPENGL_VERSION/*:/}
应该使用:
OPENGL_VERSION=$(glxinfo| grep "OpenGL version string:" | awk 'BEGIN { FS =":[[:space:]]+" }; { print $2 }')
不要使用${foo:3[:1]}进行子串切割,使用echo, sed, grep, awk等命令。例如:
string_after="somestring"
string=${string_after:0:3}
应该使用:
string=$(echo$string_after | awk '{ string=substr($0,1, 3); print string; }' )
在case语句中使用[!]而不是[^]。例如:case"foo" in
[^f]*)
echo 'not f*'
;;
esac
替换为:
case"foo" in
[!f]*)
echo 'not f*'
;;
esac
dash 不支持$LINENO,虽然它是POSIX标准。不要使用$PIPESTATUS避免使用$RANDOM,而应读取/dev/urandom或者/dev/random。例如:random=`hexdump-n 2 -e '/2 "%u"' /dev/urandom`
一些echo的选项不是portable的,可能其他shell不支持。例如-e, -n函数名前不要加function关键字。不要使用let命令,直接使用=赋值。例如let time=10 和 time=10一样
let time--和time=$((time-1))一样
bash和dash对local关键字的解释不一样。local a=5 b=6; //dash:a和b是全局变量, bash则认为a和b是局部变量。
不支持printf %q|%b不要使用select关键字,只有bash才支持。source命令也是bash才支持,应该使用'.'命令路径搜索时,`dash` 不支持 `~` 扩展,应该使用$HOME不支持declare 或 typesetbash和dash对ulimit和type有不同的选项time是bash内置的命令,但是在dash下需要使用time程序kill -[0-9] or -[A-Z]是bash内置的命令在bash里,如果read没有接变量,则会保存在REPLY变量里。在dash应该使用read REPLY替代。不要使用<<<,而是使用<<替代。例如:$cat <<<"$HOME is where the heart is."
/home/ralphis where the heart is.
替换为:
$cat <<E
>$HOME is where the heart is.
>E
/home/ralphis where the heart is.
$
#############################
Dash与Bash的语法区别
http://blog.163.com/hlz_2599/blog/static/142378474201182195320441/
如今Debian和Ubuntu中,/bin/sh默认已经指向dash,这是一个不同于bash的shell,它主要是为了执行脚本而出现,而不是交互,它速度更快,但功能相比bash要少很多,语法严格遵守POSIX标准,下面简要列举下从bash迁移到dash一般需要注意的问题
bash: function在bash中为关键字
1 2 3 4 5 6 | igi@gentoo ~ $ foo(){ echo $0;} igi@gentoo ~ $ foo /bin/bash igi@gentoo ~ $ function foo2(){ echo $0;} igi@gentoo ~ $ foo2 /bin/bash |
dash: dash中没有function这个关键字
1 2 3 4 5 | $ foo(){ echo $0;} $ foo dash $ function foo2(){ echo $0;} dash: Syntax error: "(" unexpected |
bash:支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | igi@gentoo ~ $ select input in A B > do > case $input in > A) > echo 'Input:A' > break > ;; > B) > echo 'Input:B' > break > ;; > esac > done 1) A 2) B #? 1 Input:A igi@gentoo ~ $ echo $0 /bin/bash |
dash:不支持, 替代方法:采用while+read+case来实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | menu(){ echo -n "1)A;\n2)B\n>";} menu while read input do case $input in 1) echo 'A' break ;; 2) echo 'B' break ;; *) menu continue ;; esac done |
bash:支持{n..m}展开
1 2 3 4 | igi@gentoo ~ $ echo $0 /bin/bash igi@gentoo ~ $ echo {0..10} 0 1 2 3 4 5 6 7 8 9 10 |
dash:不支持,替代方法, 采用seq外部命令
1 2 3 4 5 6 | $ echo $0 dash $ echo {0..10} {0..10} $ echo `seq 0 10` 0 1 2 3 4 5 6 7 8 9 10 |
bash:支持here string
1 2 3 4 | igi@gentoo ~ $ cat <<<"string" string igi@gentoo ~ $ echo $0 /bin/bash |
dash:不支持, 替代方法:可采用here documents
1 2 3 4 5 6 7 8 | $ echo $0 dash $ cat <<<"string" dash: Syntax error: redirection unexpected $ cat <<EOF > string > EOF string |
bash: 当word为非数字时,>&word变成重定向标准错误和标准输出到文件word, 常见用法>&/dev/null
1 2 3 4 5 6 7 8 9 | igi@gentoo ~/test $ ls a igi@gentoo ~/test $ ls a b ls: cannot access b: No such file or directory a igi@gentoo ~/test $ ls a b >&/dev/null igi@gentoo ~/test $ ls a b >/dev/null 2>&1 igi@gentoo ~/test $ echo $0 /bin/bash |
dash: >&word, word不支持非数字, 替代方法: >word 2>&1; 常见用法 >/dev/null 2>&1
1 2 3 4 5 6 7 8 9 10 11 | $ echo $0 dash $ ls a a $ ls a b ls: cannot access b: No such file or directory a $ ls a b >&/dev/null dash: Syntax error: Bad fd number $ ls a b >/dev/null 2>&1 $ |
bash: 支持数组, bash4支持关联数组
1 2 3 4 5 | igi@gentoo ~/test $ echo $0 /bin/bash igi@gentoo ~/test $ array=( a b c ) igi@gentoo ~/test $ echo ${array[2]} c |
dash: 不支持数组,替代方法, 采用变量名+序号来实现类似的效果
1 2 3 4 5 6 7 8 9 | $ for i in a b c > do > id=$((${id:=-1}+1)) > eval array_$id=$i > done $ echo ${array_1} b $ echo $0 dash |
很蛋疼的方法,非不得以不建议这么用
bash: 支持${parameter:offset:length},${parameter:offset}
1 2 3 4 5 6 7 | igi@gentoo ~/test $ string='hello' igi@gentoo ~/test $ echo ${string:1:3} ell igi@gentoo ~/test $ echo ${string:1} ello igi@gentoo ~/test $ echo $0 /bin/bash |
dash: 不支持, 替代方法:采用expr或cut外部命令代替
1 2 3 4 5 6 7 8 9 10 11 12 | $ string='hello' $ expr substr "$string" 2 3 ell $ echo "$string" | cut -c2-4 ell $ expr substr "$string" 2 "${#string}" ello $ echo "$string" | cut -c2- ello $ echo $0 dash $ |
bash: 支持${parameter^pattern},${parameter^^pattern},${parameter,pattern},${parameter,,pattern}
1 2 3 4 5 6 7 8 9 | igi@gentoo ~/test $ string="abcABC" igi@gentoo ~/test $ echo ${string^^} ABCABC igi@gentoo ~/test $ echo ${string,,} abcabc igi@gentoo ~/test $ echo ${string^^b} aBcABC igi@gentoo ~/test $ echo $0 /bin/bash |
dash: 不支持,替代方法:采用tr/sed/awk等外部命令转换
1 2 3 4 5 6 7 8 | $ string='abcABC' $ echo "$string" | tr '[a-z]' '[A-Z]' ABCABC $ echo "$string" | tr '[A-Z]' '[a-z]' abcabc $ echo "$string" | sed 's/b/\U&/g' aBcABC $ |
bash: 支持进程替换
1 2 3 4 5 | igi@gentoo ~ $ diff <(seq 3) <(seq 4) 3a4 > 4 igi@gentoo ~ $ echo $0 /bin/bash |
dash: 不支持, 替代方法, 通过临时文件中转
1 2 3 4 5 6 7 8 9 10 | $ diff <(seq 3) <(seq 4) dash: Syntax error: "(" unexpected $ seq 3 >tmp1 $ seq 4 >tmp2 $ diff tmp1 tmp2 3a4 > 4 $ echo $0 dash $ |
bash: 支持两者
1 2 3 4 5 6 | igi@gentoo ~ $ [ 'a' = 'a' ] && echo 'equal' equal igi@gentoo ~ $ [ 'a' == 'a' ] && echo 'equal' equal igi@gentoo ~ $ echo $0 /bin/bash |
dash: 只支持=
1 2 3 4 5 6 7 | $ [ 'a' = 'a' ] && echo 'equal' equal $ [ 'a' == 'a' ] && echo 'equal' [: 2: a: unexpected operator $ echo $0 dash $ |
bash: 支持[[ ]], 可实现正则匹配等强大功能
1 2 3 4 | igi@gentoo ~ $ [[ 'xyz123' =~ xyz[0-9]+ ]] && echo 'equal' equal igi@gentoo ~ $ echo $0 /bin/bash |
dash: 不支持[[ ]], 替代方法,采用外部命令
1 2 3 4 5 6 7 | $ [[ 'xyz123' =~ xyz[0-9]+ ]] && echo 'equal' dash: [[: not found $ echo 'xyz123' | grep -q 'xyz[0-9]\+' && echo 'equal' equal $ echo $0 dash $ |
bash: 支持C语言格式的for循环
1 2 3 4 5 6 7 | igi@gentoo ~ $ for((i=0;i<=3;i++));do echo "$i";done 0 1 2 3 igi@gentoo ~ $ echo $0 /bin/bash |
dash: 不支持该格式的for, 替代方法,用while+$((expression))实现
1 2 3 4 5 6 7 8 9 10 11 12 13 | $ i=0 $ while [ "$i" -le 3 ] > do > echo "$i" > i=$((i+1)) > done 0 1 2 3 $ echo $0 dash $ |
bash: 有内置命令let, 也支持((expression))方式
1 2 3 4 5 6 7 8 9 | igi@gentoo ~ $ i=0 igi@gentoo ~ $ let i++ igi@gentoo ~ $ echo $i 1 igi@gentoo ~ $ ((i++)) igi@gentoo ~ $ echo $i 2 igi@gentoo ~ $ echo $0 /bin/bash |
dash: 不支持,替代方法,采用$((expression))或者外部命令做计算
1 2 3 4 5 6 7 | $ i=0 $ i=$((i+1)) $ echo $i 1 $ echo $0 dash $ |
bash: 支持id++,id--,++id,--id这样到表达式
1 2 3 4 5 6 7 8 9 10 11 | igi@gentoo ~ $ i=0 igi@gentoo ~ $ echo $((i++)) 0 igi@gentoo ~ $ echo $i 1 igi@gentoo ~ $ echo $((++i)) 2 igi@gentoo ~ $ echo $i 2 igi@gentoo ~ $ echo $0 /bin/bash |
dash: 不支持++,--, 替代方法:id+=1,id-=1, id=id+1,id=id-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $ i=0 $ echo $((i++)) dash: arithmetic expression: expecting primary: "i++" $ echo $i;i=$((i+1)) 0 $ echo $i 1 $ echo $((i+=1)) 2 $ echo $i 2 $ echo $0 dash $ |
参考:
https://wiki.ubuntu.com/DashAsBinSh
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_title.html
-----------------
转载请著明出处: