V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mytry
V2EX  ›  程序员

sh 和 bash 区别大吗?

  •  
  •   mytry · 2019-05-18 16:31:33 +08:00 · 8853 次点击
    这是一个创建于 2020 天前的主题,其中的信息可能已经有所发展或是发生改变。
    感觉两个都很通用,比如 node 的 nvm 安装包就是用 bash 的。 如果想写一个跨平台的通用脚本,用 sh 还是 bash 比较好?
    21 条回复    2020-05-17 22:31:30 +08:00
    hztDbFXEed73dkMf
        1
    hztDbFXEed73dkMf  
       2019-05-18 16:35:20 +08:00
    主流 linux 发行版都默认 bash
    junjieyuanxiling
        2
    junjieyuanxiling  
       2019-05-18 16:36:20 +08:00 via Android
    sh 一般是 bash 的软链接。
    judeng
        3
    judeng  
       2019-05-18 16:42:27 +08:00   ❤️ 1
    ```
    $ls -l /bin/sh
    lrwxrwxrwx 1 root root 4 Oct 20 2014 /bin/sh -> bash
    ```
    linux 平台上目前的发行版,sh 均为 bash 的软链接
    在 solaris 上 sh 和 bash 还有细小差别,比如环境变量的继承规则有点区别
    推荐 bash
    xiaket
        4
    xiaket  
       2019-05-18 16:44:24 +08:00
    推荐 bash, 不推荐使用 bash 特有语法, 造成兼容性问题你修起来头大.
    sbw
        5
    sbw  
       2019-05-18 16:55:47 +08:00
    用 /bin/sh 的话,一般要保证你的 shell 脚本满足 POSIX 语法
    iwtbauh
        6
    iwtbauh  
       2019-05-18 17:24:30 +08:00 via Android   ❤️ 2
    shell 的可移植性问题是个挺严重的问题。

    shell 语言和解释器本身是可移植的,但是 shell 中调用的其他程序 sed awk 等等却有很多陷阱。

    首先,如果特别在意可移植性,应该用 POSIX shell 而不是 bash,因为并非所有系统都预装 bash,例如 FreeBSD,但所有兼容 POSIX 标准的系统预装的默认 shell 都兼容 POSIX shell。在 debian 上,你可以使用 dash 来测试你的脚本。

    第二,GNU/Linux 上的 sed awk,以及很多很多 shell 可能用到的命令,像 tar 啊 tr 啊 dd 啊这些,都是带有“ GNU 扩展”的。它们兼容 POSIX,但在之上增加了特别多的“专有”功能。如果你的 shell 脚本是为可移植性设计的,则不应该使用这些专有功能(但很可能在你不注意时就使用了,特别是互联网上有些教程根本没有告诉你这种方法是 GNU 扩展,是非 POSIX 的)。
    neroxps
        7
    neroxps  
       2019-05-18 17:27:58 +08:00
    @iwtbauh 这个坑我踩过,在 macos 上,很疼。
    mattx
        8
    mattx  
       2019-05-18 17:46:36 +08:00
    shell 常见有几个种类, bash zsh fish, bash 最通用. 一般 /bin/sh 是当前激活的 shell 的软连接, 如果脚本写 /bin/bash 就明确用 bash 执行了. zsh fish 有一些新特性. 大概想到这么多.
    ech0x
        9
    ech0x  
       2019-05-18 17:50:47 +08:00
    @junjieyuanxiling #2 其实不是了,有些发行版已经换成 dash 了
    caliburn1994
        10
    caliburn1994  
       2019-05-18 19:25:06 +08:00
    具体是什么也不知道,之前其他人写的代码是根据 bash,然后我用 sh 去运行,报错了。后来被告知要用 bash ***去运行
    听说是语法不同,不是完全兼容之类。
    mritd
        11
    mritd  
       2019-05-18 20:10:42 +08:00 via iPhone
    你怕是没用过 busybox
    starrycat
        12
    starrycat  
       2019-05-18 20:20:49 +08:00
    bash 交互比较好,语法写起来舒服
    codehz
        13
    codehz  
       2019-05-18 21:15:06 +08:00
    @mattx #8 没有激活当前 shell 这种事情的。。除非你手动创建链接,而改 shell 是在 /etc/passwd 里做的
    wu67
        14
    wu67  
       2019-05-18 21:43:52 +08:00
    看发行版吧, 反正 sh 就指向別的... 曾经 Ubuntu 默认 dash, 然后我 sh 某脚本一堆爆炸. 所以现在我都是直接敲 bash ***.sh 要不就./***.sh
    Tink
        15
    Tink  
       2019-05-18 23:56:25 +08:00 via iPhone
    我觉得挺大的,我经常写好的 bash 在某些只有 sh 的环境里得改好多地方
    oneisall8955
        16
    oneisall8955  
       2019-05-19 01:37:00 +08:00 via Android
    有,脚本语法有点不同,具体忘记了,好似是判断语句
    ryd994
        17
    ryd994  
       2019-05-19 01:52:47 +08:00 via Android
    @wu67
    @caliburn1994
    hashbang 了解一下
    第一行写
    #!/bin/bash
    iwtbauh
        18
    iwtbauh  
       2019-05-19 02:40:24 +08:00 via Android
    @neroxps #7

    正常情况,macosx 是基于 FreeBSD 的,这些基本工具都是不太可能兼容 GNU 扩展的。它们有的是 BSD 扩展。

    如果脚本需要在多处运行,尽量避免使用这些“专有”扩展。但完全用 POSIX 可能使某些功能的实现变得复杂。
    beginor
        19
    beginor  
       2019-05-19 08:00:42 +08:00 via Android
    第一行一般写 `#!/bin/bash -e` , 这样碰到错误就会直接退出。

    但是写成 `#!/bin/sh -e` 就不行 。
    Sanko
        20
    Sanko  
       2019-05-19 12:17:19 +08:00 via Android
    sh = bash -posix
    serge001
        21
    serge001  
       2020-05-17 22:31:30 +08:00
    ls -l /bin/sh 在 wsl 上默认输出为:lrwxrwxrwx 1 root root 4 May 21 2019 /bin/sh -> dash
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1131 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 18:53 · PVG 02:53 · LAX 10:53 · JFK 13:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.