ubuntu上的sh链接到dash

最近同事写的shell脚本在ubuntu上跑时总走不对if的分支。发现ubuntu上的shell默认是bash,但sh对应的是dash,这个需要注意。

1

ubuntu上sh连到dash:

[email protected]:~$ uname -a

Linux hostname1 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 17:39:31 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

[email protected]:~$ cat /etc/issue

Ubuntu 12.04.4 LTS \n \l

[email protected]:~$ echo $SHELL

/bin/bash

[email protected]:~$ type sh

sh is hashed (/bin/sh)

[email protected]:~$ ls -l /bin/sh

lrwxrwxrwx 1 root root 4 Mar 30  2012 /bin/sh -> dash

[email protected]:~$

centos上sh连到bash:

[[email protected] ~]# uname -a

Linux hostalonetest 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

[[email protected] ~]# cat /etc/issue

CentOS release 6.5 (Final)

Kernel \r on an \m

[[email protected] ~]# echo $SHELL

/bin/bash

[[email protected] ~]# type sh

sh is /bin/sh

[[email protected] ~]# ls -l /bin/sh

lrwxrwxrwx. 1 root root 4 Sep  1 07:45 /bin/sh -> bash

[[email protected] ~]# echo $SHELL

/bin/bash

[[email protected] ~]#

2

写了个小脚本测试

[email protected]:~$ nl test2.sh

1  #!/bin/bash

2  tt=‘xx‘;

3  if [ "$tt" == "YY" ]; then

4    echo "yy"

5  elif [ "$tt" == "xx" ]; then

6    echo "xx"

7  else

8    echo "fuck"

9  fi

3

在ubuntu上走sh用的是dash,测试脚本有错,同时走错了分支

[email protected]:~$ sh test2.sh

test2.sh: 5: [: xx: unexpected operator

test2.sh: 7: [: xx: unexpected operator

fuck

在ubuntu上走默认shell,用的是bash,结果ok

[email protected]:~$ ./test2.sh

xx

4

在centos上走sh用的是bash,结果ok

[[email protected] ~]# sh test.sh

yy

在centos上走默认shell,用的是bash,结果ok

[[email protected] ~]# ./test.sh

yy

5

可以用如下方法修改sh链到bash

ln -s /bin/bash /bin/sh

或者如下:

sudo dpkg-reconfigure dash

出现提示界面问是否要dash的时候,选No就行了。反馈如下:

Removing ‘diversion of /bin/sh to /bin/sh.distrib by dash‘

Adding ‘diversion of /bin/sh to /bin/sh.distrib by bash‘

Removing ‘diversion of /usr/share/man/man1/sh.1.gz to /usr/share/man/man1/sh.distrib.1.gz by dash‘

Adding ‘diversion of /usr/share/man/man1/sh.1.gz to /usr/share/man/man1/sh.distrib.1.gz by bash‘

看来第二种方法还是比第一种方法做的完善。

检验结果,已经指向bash:

[email protected]:~$ ls -l /bin/sh

lrwxrwxrwx 1 root root 4 Sep 15 11:28 /bin/sh -> bash

6

什么是bash ?

Bash(GNU Bourne-Again Shell)是许多Linux平台的内定Shell,事实上,还有许多传统UNIX上用的Shell,像tcsh、csh、ash、bsh、ksh等等,Shell Script大致都类同,当您学会一种Shell以后,其它的Shell会很快就上手,大多数的时候,一个Shell Script通常可以在很多种Shell上使用

什么是dash ?

man结果摘抄部分:

dash is the standard command interpreter for the system.  The current version of dash is in the process of being changed to conform with the POSIX 1003.2 and 1003.2a specifications for the shell.

网上抄了段,不知道信息出处:

DASH is a POSIX-compliant implementation of /bin/sh that aims to be as small as possible. It does this without sacrificing speed where possible. In fact, it is significantly faster than bash (the GNU Bourne-Again SHell) for most tasks.

比bash小而快的东西

########################

下面是有些同学翻译或总结的,也放到这儿备查

Ubuntu dash与bash的区别

http://blog.csdn.net/hansel/article/details/9817129

https://wiki.ubuntu.com/DashAsBinSh

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_title.html

从Ubuntu 6.10开始,默认使用dash(theDebian Almquist Shell)而不是bash(the GNUBourne-Again Shell). 但Login Shell还是bash. 原因是dash更快、更高效,而且它符合POSIX规范。Ubuntu在启动的时候会运行很多shell脚本,使用dash可以加快启动速度。

  • 如果解决bash和dash兼容性导致的问题

    • 在需要bash的脚本的第一行写上"#!/bin/bash"
    • 在Makefile中可以设置

SHELL = /bin/bash

  • 如果需要修改默认为bash,请运行下面命令并选择no。注意这将影响所有的系统脚本。如果有脚本需要dash的特有功能,将引起问题(这种情况比较少)。

sudodpkg-reconfigure dash

  • 在新写的shell脚本里避免使用bash的扩展特性(bashism)。

    • 使用devscripts包的checkbashisms      命令可以检查shell脚本里是否存在bashism.
    • 安装autoconf-doc包运行info autoconf命令可以阅读"Portable      Shell" 部分的文档来了解POSIX Shell。
    • 在"["命令(test)中避免使用-a, -o,应该使用多个"[]"命令并用"&&",      "||"连接。

      例如:下面的shell语句

[\( "$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脚本。
  • 大部分的${…}进行变量扩展都是可移植的。但是下面的几个不是。
    • ${!...}进行非直接变量扩展,应该使用eval命令。
    • ${parameter/pattern/string}进行模式替换
    • ${parameter:offset:length}截取子串
  • 不要使用${parm/?/pat[/str]}进行字符替换,而应该使用echo, sed, grep,     awk等命令。例如:

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 或 typeset
  • bash和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一般需要注意的问题

1.定义函数

bash: function在bash中为关键字


1

2

3

4

5

6

[email protected] ~ $ foo(){ echo $0;}

[email protected] ~ $ foo

/bin/bash

[email protected] ~ $ function foo2(){ echo $0;}

[email protected] ~ $ foo2

/bin/bash

dash: dash中没有function这个关键字


1

2

3

4

5

$ foo(){ echo $0;}

$ foo

dash

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

[email protected] ~ $ 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

[email protected] ~ $ 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

3. echo {0..10}

bash:支持{n..m}展开


1

2

3

4

[email protected] ~ $ echo $0

/bin/bash

[email protected] ~ $ 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

4. here string

bash:支持here string


1

2

3

4

[email protected] ~ $ cat <<<"string"

string

[email protected] ~ $ 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

5. >&word重定向标准输出和标准错误

bash: 当word为非数字时,>&word变成重定向标准错误和标准输出到文件word, 常见用法>&/dev/null


1

2

3

4

5

6

7

8

9

[email protected] ~/test ls

a

[email protected] ~/test ls a
b

ls: cannot access b: No such file or
directory

a

[email protected] ~/test ls a
b >&
/dev/null

[email protected] ~/test ls a
b >
/dev/null 2>&1

[email protected] ~/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

$

6. 数组

bash: 支持数组, bash4支持关联数组


1

2

3

4

5

[email protected] ~/test echo $0

/bin/bash

[email protected] ~/test $
array=( a b c )

[email protected] ~/test echo ${array[2]}

c

dash: 不支持数组,替代方法, 采用变量名+序号来实现类似的效果


1

2

3

4

5

6

7

8

9

for in a
b c

do

id=$((${id:=-1}+1))

eval array_$id=$i

done

echo ${array_1}

b

echo $0

dash

很蛋疼的方法,非不得以不建议这么用

7. 子字符串扩展

bash: 支持${parameter:offset:length},${parameter:offset}


1

2

3

4

5

6

7

[email protected] ~/test $
string=
‘hello‘

[email protected] ~/test echo ${string:1:3}

ell

[email protected] ~/test echo ${string:1}

ello

[email protected] ~/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" "${#string}"

ello

echo "$string" cut -c2-

ello

echo $0

dash

$

8. 大小写转换

bash: 支持${parameter^pattern},${parameter^^pattern},${parameter,pattern},${parameter,,pattern}


1

2

3

4

5

6

7

8

9

[email protected] ~/test $
string=
"abcABC"

[email protected] ~/test echo ${string^^}

ABCABC

[email protected] ~/test echo ${string,,}

abcabc

[email protected] ~/test echo ${string^^b}

aBcABC

[email protected] ~/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

[email protected] ~ $ diff <(seq 3)
<(
seq 4)

3a4

> 4

[email protected] ~ $ 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

$

10. [ string1 = string2 ] 和 [ string1 == string2 ]

bash: 支持两者


1

2

3

4

5

6

[email protected] ~ $ [ ‘a‘ ‘a‘ ]
&& 
echo ‘equal‘

equal

[email protected] ~ $ [ ‘a‘ == ‘a‘ ]
&& 
echo ‘equal‘

equal

[email protected] ~ $ 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

$

11. [[ 加强版test

bash: 支持[[ ]], 可实现正则匹配等强大功能


1

2

3

4

[email protected] ~ $ [[ ‘xyz123‘ =~
xyz[0-9]+ ]] && 
echo ‘equal‘

equal

[email protected] ~ $ 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

$

12. for (( expr1 ; expr2 ; expr3 )) ; do list ; done

bash: 支持C语言格式的for循环


1

2

3

4

5

6

7

[email protected] ~ $ for((i=0;i<=3;i++));do echo "$i";done

0

1

2

3

[email protected] ~ $ 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

$

13. let命令和((expression))

bash: 有内置命令let, 也支持((expression))方式


1

2

3

4

5

6

7

8

9

[email protected] ~ $ i=0

[email protected] ~ $ let i++

[email protected] ~ $ echo $i

1

[email protected] ~ $ ((i++))

[email protected] ~ $ echo $i

2

[email protected] ~ $ echo $0

/bin/bash

dash: 不支持,替代方法,采用$((expression))或者外部命令做计算


1

2

3

4

5

6

7

$ i=0

$ i=$((i+1))

echo $i

1

echo $0

dash

$

14. $((expression))

bash: 支持id++,id--,++id,--id这样到表达式


1

2

3

4

5

6

7

8

9

10

11

[email protected] ~ $ i=0

[email protected] ~ $ echo $((i++))

0

[email protected] ~ $ echo $i

1

[email protected] ~ $ echo $((++i))

2

[email protected] ~ $ echo $i

2

[email protected] ~ $ 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

-----------------

转载请著明出处:

blog.csdn.net/beiigang

时间: 2024-07-28 22:43:32

ubuntu上的sh链接到dash的相关文章

Ubuntu上让Firefox使用Chrome最新版PepperFlash插件

Adobe Flash Player 11.2 将是支持 Linux 平台的最后一个版本. Adobe 只继续为 Flash Player 11.2 for Linux 提供安全更新,而不提供版本更新. Linux上为Firefox添加Flash Player支持也非常简单. 下载Adobe为Linux提供的tar.gz包: https://get.adobe.com/cn/flashplayer/ 把压缩包里的libflashplayer.so复制或软链接到/usr/lib/mozilla/p

ubuntu上安装NVIDIA驱动、CUDA、CUDNN

Ubuntu18.04环境下的安装: 主要参考下面这个博客: https://blog.csdn.net/u010801439/article/details/80483036 https://blog.csdn.net/ice__snow/article/details/80144503 1.安装GPU英伟达驱动(针对ubuntu18.04) step .1:首先,检测你的NVIDIA图形卡和推荐的驱动程序的模型.执行命令: $ ubuntu-drivers devices 输出结果为: ==

Ubuntu上使用Redis数据库存储SessionID并实现Session共享

p { margin-bottom: 0.1in; direction: ltr; color: #00000a; line-height: 120%; text-align: left; orphans: 2; widows: 2 } p.western { font-family: "Liberation Serif", serif; font-size: 12pt } p.cjk { font-family: "Noto Sans CJK SC Regular"

介绍两个Ubuntu上的桌面小工具

经常使用Windows10,Sticky Notes和壁纸自动切换功能挺好用的.我经常会使用Sticky Notes来记录一些信息,内容是实时保存的,而且启动的时候会自动显示在桌面上.其实Ubuntu上也有类似的一些小工具. 1. Variety Variety可以在Ubuntu上实现桌面壁纸的自动轮播,壁纸定期更换,以及一些特效等.官方站点:http://peterlevi.com/variety/.通过以下命令进行安装: sudo add-apt-repository ppa:peterle

Ubuntu上搭建Hadoop环境(单机模式+伪分布模式)【转】

[转自:]http://blog.csdn.net/hitwengqi/article/details/8008203 最近一直在自学Hadoop,今天花点时间搭建一个开发环境,并整理成文. 首先要了解一下Hadoop的运行模式: 单机模式(standalone)       单机模式是Hadoop的默认模式.当首次解压Hadoop的源码包时,Hadoop无法了解硬件安装环境,便保守地选择了最小配置.在这种默认模式下所有3个XML文件均为空.当配置文件为空时,Hadoop会完全运行在本地.因为不

Ubuntu上安装QQ2015

先不卖关子直接上图:Ubuntu 14.04.5 LTS Deb包下载地址: http://www.longene.org/download/WineQQ7.8-20151109-Longene.deb http://pan.baidu.com/s/1kTu9ZUZ 下载完成后双击会跳转到Ubuntu Software Center中安装,如果提示未经认证的deb包源请忽略继续安装:32位依赖库的问题请自行解决,可以百度或者谷歌关键字ubuntu 安装32 bit依赖库: 导语 本文的目的不在于

Ubuntu上搭建Hadoop环境(单机模式+伪分布模式)

Hadoop在处理海量数据分析方面具有独天优势.今天花时间在自己的Linux上搭建了伪分布模式,期间经历很多曲折,现在将经验总结如下. 首先,了解Hadoop的三种安装模式: 1. 单机模式. 单机模式是Hadoop的默认模.当配置文件为空时,Hadoop完全运行在本地.因为不需要与其他节点交互,单机模式就不使用HDFS,也不加载任何Hadoop的守护进程.该模式主要用于开发调试MapReduce程序的应用逻辑. 2. 伪分布模式. Hadoop守护进程运行在本地机器上,模拟一个小规模的的集群.

Ubuntu 上 hi3531 交叉编译环境 arm-hisiv100nptl-linux 搭建过程

; font-family:Arial,Console,Verdana,'Courier New'"> ubuntu12.04arm-linux-gcc 安装环境 Linux版本:Ubuntu 12.04    内核版本:Linux 3.5.0   交叉编译器版本:arm-linux-gcc-4.4.3 这个版本的交叉编译器我已经上传到了资源上,可以随便下载,点此下载 安装前的絮叨 首先简单介绍一下,所谓的搭建交叉编译环境,即安装.配置交叉编译工具链.在该环境下编译出嵌入式Linux系统所

[水煮 ASP.NET Web API2 方法论](1-4)从 MVC Controller 链接到 API Controller 以及反向链接

问题 想创建一个从 ASP.NET MVC controller 到 ASP.NET Web API controller 的直接链接,或者反向链接. 解决方案 可以使用 System.Web.Http.Routing.UrlHelp 的实例来创建一个指向 Controller的链接,来暴露ApiController(作为 Url 属性).着和在 RequestContext 上一样,会被附加到 HttpRequestMessage 实例.为了达到这个目的,我们需要调用链接方法或路由方法,然后传