Ubuntu dash与bash的区别

时间:2022-09-08 09:09:47

Ubuntudash Shell

 

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.

$