如今Debian和Ubuntu中,/bin/sh默认已经指向dash,这是一个不同于bash的shell,它主要是为了执行脚本而出现,而不是交 互,它速度更快,但功能相比bash要少很多,语法严格遵守POSIX标准,下面简要列举下从bash迁移到dash一般需要注意的问题
(将先前默认的 bash shell 更换为了 dash。其表现是 /bin/sh 链接到了 /bin/dash 而不是传统的 /bin/bash。Ubuntu Edgy 是第一个将 dash 作为默认 shell 的发行,这似乎是受了 Debian 的影响。在 Ubuntu Wiki 上可以了解到更换的相关原因,dash 更小,且运行更快,还与 POSIX 兼容。
但问题是目前网上有大片的用户由于 shell 的更换而致使脚本出错,毕竟现有的很多脚本都不是 100% POSIX 兼容。如需将默认的 shell 改回 bash,可以在执行 sudo dpkg-reconfigure dash 后,选择 no。)
1.定义函数
bash: function在bash中为关键字
|
1
2
3
4
5
6
|
igi@gentoo ~ $ foo(){ echo $0;}igi@gentoo ~ $ foo/bin/bashigi@gentoo ~ $ function foo2(){ echo $0;}igi@gentoo ~ $ foo2/bin/bash |
dash: dash中没有function这个关键字
|
1
2
3
4
5
|
$ foo(){ echo $0;}$ foodash$ function foo2(){ echo $0;}dash: Syntax error: "(" unexpected |
2.select var in list; do command; done
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> done1) A2) B#? 1Input:Aigi@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>";}menuwhile read inputdo case $input in 1) echo 'A' break ;; 2) echo 'B' break ;; *) menu continue ;; esacdone |
3. echo {0..10}
bash:支持{n..m}展开
|
1
2
3
4
|
igi@gentoo ~ $ echo $0/bin/bashigi@gentoo ~ $ echo {0..10}0 1 2 3 4 5 6 7 8 9 10 |
dash:不支持,替代方法, 采用seq外部命令
|
1
2
3
4
5
6
|
$ echo $0dash$ echo {0..10}{0..10}$ echo `seq 0 10`0 1 2 3 4 5 6 7 8 9 10 |
4. here string
bash:支持here string
|
1
2
3
4
|
igi@gentoo ~ $ cat <<<"string"stringigi@gentoo ~ $ echo $0/bin/bash |
dash:不支持, 替代方法:可采用here documents
|
1
2
3
4
5
6
7
8
|
$ echo $0dash$ cat <<<"string"dash: Syntax error: redirection unexpected$ cat <<EOF> string> EOFstring |
5. >&word重定向标准输出和标准错误
bash: 当word为非数字时,>&word变成重定向标准错误和标准输出到文件word, 常见用法>&/dev/null
|
1
2
3
4
5
6
7
8
9
|
igi@gentoo ~/test $ lsaigi@gentoo ~/test $ ls a bls: cannot access b: No such file or directoryaigi@gentoo ~/test $ ls a b >&/dev/nulligi@gentoo ~/test $ ls a b >/dev/null 2>&1igi@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 $0dash$ ls aa$ ls a bls: cannot access b: No such file or directorya$ ls a b >&/dev/nulldash: Syntax error: Bad fd number$ ls a b >/dev/null 2>&1$ |
6. 数组
bash: 支持数组, bash4支持关联数组
|
1
2
3
4
5
|
igi@gentoo ~/test $ echo $0/bin/bashigi@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 $0dash |
很蛋疼的方法,非不得以不建议这么用
7. 子字符串扩展
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}elligi@gentoo ~/test $ echo ${string:1}elloigi@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 3ell$ echo "$string" | cut -c2-4ell$ expr substr "$string" 2 "${#string}"ello$ echo "$string" | cut -c2-ello$ echo $0dash$ |
8. 大小写转换
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^^}ABCABCigi@gentoo ~/test $ echo ${string,,}abcabcigi@gentoo ~/test $ echo ${string^^b}aBcABCigi@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$ |
9. 进程替换<(command), >(command)
bash: 支持进程替换
|
1
2
3
4
5
|
igi@gentoo ~ $ diff <(seq 3) <(seq 4)3a4> 4igi@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 tmp23a4> 4$ echo $0dash$ |
10. [ string1 = string2 ] 和 [ string1 == string2 ]
bash: 支持两者
|
1
2
3
4
5
6
|
igi@gentoo ~ $ [ 'a' = 'a' ] && echo 'equal'equaligi@gentoo ~ $ [ 'a' == 'a' ] && echo 'equal'equaligi@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 $0dash$ |
11. [[ 加强版test
bash: 支持[[ ]], 可实现正则匹配等强大功能
|
1
2
3
4
|
igi@gentoo ~ $ [[ 'xyz123' =~ xyz[0-9]+ ]] && echo 'equal'equaligi@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 $0dash$ |
12. for (( expr1 ; expr2 ; expr3 )) ; do list ; done
bash: 支持C语言格式的for循环
|
1
2
3
4
5
6
7
|
igi@gentoo ~ $ for((i=0;i<=3;i++));do echo "$i";done0123igi@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))> done0123$ echo $0dash$ |
13. let命令和((expression))
bash: 有内置命令let, 也支持((expression))方式
|
1
2
3
4
5
6
7
8
9
|
igi@gentoo ~ $ i=0igi@gentoo ~ $ let i++igi@gentoo ~ $ echo $i1igi@gentoo ~ $ ((i++))igi@gentoo ~ $ echo $i2igi@gentoo ~ $ echo $0/bin/bash |
dash: 不支持,替代方法,采用$((expression))或者外部命令做计算
|
1
2
3
4
5
6
7
|
$ i=0$ i=$((i+1))$ echo $i1$ echo $0dash$ |
14. $((expression))
bash: 支持id++,id--,++id,--id这样到表达式
|
1
2
3
4
5
6
7
8
9
10
11
|
igi@gentoo ~ $ i=0igi@gentoo ~ $ echo $((i++))0igi@gentoo ~ $ echo $i1igi@gentoo ~ $ echo $((++i))2igi@gentoo ~ $ echo $i2igi@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 $i1$ echo $((i+=1))2$ echo $i2$ echo $0dash$ |
以上列举的都是常见容易混淆的地方,更多区别可以查看manpage


浙公网安备 33010602011771号