8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

sh 和 Bash 之间的区别

Gladitor 2月前

128 0

在编写 shell 程序时,我们经常使用 /bin/sh 和 /bin/bash。我通常使用 bash,但我不知道它们之间有什么区别。Bash 和 sh 之间的主要区别是什么?我们需要什么...

在编写shell程序时,我们经常使用 /bin/sh /bin/bash 。我通常使用 bash ,但我不知道它们之间有什么区别。

Bash 和 之间的主要区别是什么 sh

在使用 Bash 进行编程时我们需要注意什么 sh

帖子版权声明 1、本帖标题:sh 和 Bash 之间的区别
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Gladitor在本站《shell》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 有关 Bourne shell 上可用的 bashism 和相应代码的有用列表,请参阅

  • 一般来说,由于 bash 与 posix 兼容,所有 sh 脚本都可以在 bash 下运行,但并非所有 bash 脚本都可以在 sh 下运行,您注意到的主要区别是使用 [[ ]] 而不是 [ ] 比较(这允许使用不带引号的空格)、使用 $(( )) 而不是 $[ ] 算术表达式,以及其他类似直接从 bash 文档中得出的 \'它太大太慢\' 的内容。但新的脚本编写者不必将自己局限于与 sh 兼容的脚本,除非他们追求某种向后兼容性,而如今情况往往并非如此,毕竟现在是(或曾经是……)2014 年,对吧??

  • < > backward presumes one dimension in which linux is the only thing still growing. i use linux but also bsd, and i won't install bash unless i need it. so, i limit my shell scripting to the posix-level bourne shell, which is fairly modern, having functions and local variables and so on. portability has more than one dimension, it's not just backward/forward.
  • 如果你被迫从 bash 切换到 POSIX,你最容易被缺少的东西所困扰:没有数组,没有内置行编辑(虽然你可以使用

  • sh 是什么?

    sh POSIX 标准 描述的编程语言 。它有许多实现( ksh88 , Dash ,...)。Bash 也可以被视为 sh (见下文)的一种实现。

    因为 sh 它是一种规范,而不是一种实现, /bin/sh 所以是大多数 POSIX 系统上实际实现的符号链接(或硬链接)。

    什么是 Bash?

    Bash 最初是一个 sh 兼容 POSIX 的实现(尽管它比 POSIX 标准早几年),但随着时间的推移,它获得了许多扩展。其中许多扩展可能会改变有效 POSIX shell 脚本的行为,因此 Bash 本身并不是一个有效的 POSIX shell。相反,它是 POSIX shell 语言的一种方言。

    Bash 支持 --posix switch,这使其更符合 POSIX 标准。如果以如下方式调用,它还会尝试模仿 POSIX sh .

    sh=bash?

    长期以来, /bin/sh 都习惯于使用 /bin/bash 。因此,几乎可以放心地忽略两者之间的差异。但最近这种情况开始发生变化。

    不指向 /bin/sh (并且其中一些 /bin/bash 甚至可能不存在) /bin/bash 的系统常见示例

    1. 现代 Debian 和 Ubuntu 系统, sh dash
    2. Busybox ,通常在 Linux 系统启动时作为 的一部分运行 initramfs 。它使用 ash shell 实现。
    3. BSD 系统,以及一般的非 Linux 系统。使用 OpenBSD 。FreeBSD pdksh 的后代 KornShell 是原始 Unix Bourne shell 的后代。, sh 有自己的 Solaris 但长期以来不符合 POSIX 标准;Heirloom 项目提供 sh 免费 实现 .

    如何才能找出 /bin/sh 你的系统上的指向?

    复杂之处在于,这 /bin/sh 可能是符号链接或硬链接。如果是符号链接,则可 移植的 解析方法是:

    % file -h /bin/sh
    /bin/sh: symbolic link to bash
    

    如果是硬链接,请尝试

    % find -L /bin -samefile /bin/sh
    /bin/sh
    /bin/bash
    

    实际上,该 -L 标志涵盖了符号链接和硬链接,但这种方法的缺点是不可移植——POSIX 不要求 find 支持该 -samefile 选项,尽管 GNU find FreeBSD find 支持它。

    舍邦线

    最终,由您来决定使用哪一个,通过将“shebang”行写为脚本的第一行。

    例如

    #!/bin/sh
    

    将使用 sh (以及指向的任何内容),

    #!/bin/bash
    

    如果可用, /bin/bash 则使用

    #!/bin/dash
    

    使用哪一个

    对于我自己的脚本,我更喜欢 sh 以下原因:

    • 它是标准化的
    • 它更简单,更容易学习
    • 它可以跨 POSIX 系统移植——即使它们没有 bash ,也必须有 sh

    bash 有优势 sh 是一种非常简约的编程语言。

  • 如果您使用 bash 运行脚本,则在出现语法错误时会显示更多有用的错误消息。使用 bash 可以节省时间。

  • @JosephHarriott 它是一个提示符:由 shell 本身打印的字符,后面跟着您的命令。有些 shell 使用 $ 而不是 % 或 # 来表示 root shell。

  • @JosephHarriott - % 通常是 C Shell 变体(例如 csh、tcsh)的用户 shell 的提示符。# 传统上被保留为超级用户(root)shell 的提示符,无论选择哪一个。但这一切都属于常见/典型用法的范围,正如历史/传统所观察到的那样。您可以使用您喜欢的和/或您的用户可以容忍的内容。:) 谷歌了解如何

  • Zsh 中的默认提示符也是 %,尽管传统上它被用来表示 Csh 系列 shell。这绝不是 Zsh 背离传统的唯一地方。

  • sh http://man.cx/sh
    Bash: http://man.cx/bash

    TL;DR :Bash 是的超集, sh 具有更优雅的语法和更多功能。在几乎所有情况下,使用 Bash shebang line 都是安全的,因为它在现代平台上非常普遍。

    注意:在某些环境中, sh Bash。检查 sh --version .

  • 如果 bash 以 sh 形式调用,其行为会略有不同。请参阅 gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files (\'Invoked with name sh\') 和 gnu.org/software/bash/manual/bashref.html#Bash-POSIX-Mode。例如,没有进程替换。

  • 由于 bash 是 sh 的超集,并且某些操作系统(例如 FreeBSD)默认未安装 bash,因此使用 sh 编写脚本将具有更高的可移植性。

  • F.O. 2月前 0 只看Ta
    引用 14

    由于没有可移植的脚本方式来获取特定脚本的 POSIX shell,因此可移植脚本不能假设比 Bourne Shell 更多的功能。

  • ...呃,如果有人没有在 PATH 中第一个不符合 POSIX 标准的 sh 之前放置一个符合 POSIX 标准的 sh,那是他们的错,他们罪有应得;#!/usr/bin/env sh 和责备用户在实际应用中已经足够接近了。:)

  • 引用 16

    在 Windows 版 Git Bash 上,sh 以 POSIX 模式运行 bash(gnu.org/software/bash/manual/html_node/...)

  • 这个问题经常被提名为那些尝试使用 sh 并惊讶于它的行为与 的人的典型问题 bash 。以下是常见误解和陷阱的简要概述。

    首先,你应该明白会发生什么。

    • 如果您使用 运行脚本 sh scriptname ,或者使用 运行脚本 scriptname #!/bin/sh shebang 行中使用 ,则应该期待 POSIX sh 行为。
    • 如果您使用 运行脚本 bash scriptname ,或者使用 scriptname #!/bin/bash 在 shebang 行中使用 (或本地等效项)运行脚本,则应该期待 Bash 行为。

    拥有正确的 shebang 并通过仅输入脚本名称(可能带有 相对路径或完整路径 )来运行脚本通常是首选解决方案。除了正确的 shebang 之外,这还要求脚本文件具有执行权限( chmod a+x scriptname )。

    那么,它们实际上有何不同?

    Bash 旨在向后兼容 Bourne shell 和 POSIX,但具有许多附加功能。Bash 参考手册有一 节试图列举差异 ,但一些常见的混淆来源包括

    • [[ 不可用 sh (仅 [ 更笨重且功能有限)。另请参阅 Bash 中单方括号和双边括号之间的区别是什么?
    • sh 没有数组。
    • 一些 Bash 关键字(例如 local , source , function , shopt , let , declare , pushd , popd 、 和 ) select 不能移植到 sh 。 (某些 sh 实现支持 例如 local 。)
    • Bash 有许多 C 风格的语法扩展,例如三参数 for((i=0;i<=3;i++)) 循环、 += 增量赋值等。该 $'string\nwith\tC\aescapes' 功能暂时被 POSIX 接受 (意味着它现在在 Bash 中有效,但尚不支持 sh 仅遵守当前 POSIX 规范的系统,并且在未来一段时间内可能也不会支持)。
    • Bash 支持 <<<'here strings' .
    • Bash 具有 *.{png,jpg} 括号 {0..12} 扩展。
    • Bash 具有扩展的通配符功能,例如 ** ( globstar ),用于递归子目录,以及 extglob 使用不同的、 更通用的通配符语法。
    • ~仅在 Bash 中指$HOME (更一般地, ~usernameusername的主目录)。实现 /bin/sh 中可能缺失
    • Bash 具有以下进程替换功能 <(cmd) >(cmd) .
    • Bash 支持带有 <> 重定向的协进程。
    • Bash 具有 Csh 风格的便捷重定向别名,例如 &| for 2>&1 | &> for > ... 2>&1
    • Bash 具有丰富的附加非标准 参数扩展, 例如 ${substring:1:2} , ${variable/pattern/replacement} ,大小写转换等。
    • Bash 扩展了 shell 算术功能(但仍然不支持浮点)。有一种过时的旧 $[expression] 语法,但应将其替换为 POSIX 算术 $((expression)) 语法。(但某些旧的 POSIX 前 sh 实现可能不支持该语法。)
    • 一些内置命令具有不可移植的选项,例如 type -a , printf -v , cd -P ,以及常年使用的 echo -e .
    • 魔法变量(例如 $RANDOM , $_ , $SECONDS , $PIPESTATUS[@] 和) $FUNCNAME 是 Bash 扩展。请参阅 参考手册。
    • Bash 将一些系统功能公开为文件句柄,例如 /dev/stdin , /dev/fd/<number> , /dev/tcp/<network address>
    • 语法差异,例如export variable=valueexport variable应该与变量赋值分开)并且 [ "x" == "y" ] 不可移植(可移植字符串比较 [ ... ] 使用单个等号)。
    • 许多仅适用于 Bash 的扩展用于启用或禁用可选行为并公开 shell 的内部状态。
    • 许多方便交互使用的功能但不会影响脚本行为。

    请记住,这是一份精简的清单。请参阅参考手册以了解完整内容,并参阅 http://mywiki.wooledge.org/Bashism 以了解许多不错的解决方法;和/或尝试 http://shellcheck.net/ ,它会警告许多仅限 Bash 的功能。

    一个常见的错误是有一个 #!/bin/bash shebang 行,但仍然使用 sh scriptname 它来实际运行脚本。这基本上禁用了任何仅限 Bash 的功能,因此您会遇到语法错误,例如尝试使用数组。(shebang 行在语法上是注释,因此在这种情况下它会被忽略。)

    不幸的是,当您尝试在以 调用时使用这些构造时,B或 不会发出警告 sh 。它也不会完全禁用 所有 仅限 Bash 的功能,因此通过以 调用来运行 Bash 并不是 sh ash ash / dash /POSIX sh Heirloom sh Heirloom sh 。如果您想检查是否严格遵守 POSIX,请尝试 posh (但似乎没有正确记录)。

    另外, POSIX 标准化工作旨在指定各种类 U*x 平台行为,包括 ) shell ( sh 。但是,这是一个不断发展的文档,因此,一些实现遵循 POSIX 规范的早期版本;此外,还有一些遗留实现甚至没有尝试遵循 POSIX。最初的 Bourne shell 有一些怪癖,后来被 POSIX 规范纠正,该规范在很大程度上基于 ksh88 。 (许多 Bash 扩展也是从 中创新而来的 ksh 。)

  • 最近我注意到,如果我浏览基于我的 wordpress 服务器目录列表的链接,例如:https://website.com/examples,它将显示禁止的错误消息。例如:https://website.com/wp-admin...

    最近我注意到,如果我浏览基于我的 WordPress 服务器目录列表的链接,

    -例如: https://website.com/examples ,它将显示禁止的错误消息。

    -例如: https://website.com/wp-admin/ ,它将显示错误消息访问被拒绝页面。

    我曾尝试将链接重定向到 .htaccess 文件中的 404 页面。

    RewriteRule ^wp-admin/* /index.php?wph-throw-404 [L]

    它可以起作用,但是这也会影响 Myfolders 中子文件夹的文件,例如 css/javascript,并导致我无法登录到我的 wordpress,并且网页丢失了图像,一切都乱了套。

    有什么方法可以防止这种情况发生并解决我遇到的问题吗?

  • raio 2月前 0 只看Ta
    引用 19

    值得一提的是,POSIX 强制要求 export variable=value:pubs.opengroup.org/onlinepubs/009695399/utilities/export.html。也许在某些古老的 shell 中没有这个功能,但它绝对不是 bashism。

  • 引用 20

    我不知道 Heirloom sh,但似乎不再活跃...我在救援模式下工作时经常使用 busybox sh...

返回
作者最近主题: