当前位置: 首页 > article >正文

sh与bash的区别

sh与bash的区别

结论:对于一般开发者,没有区别;对于要使脚本兼容较老系统,或者兼容其他shell(如ksh,dash),那么意义可能很重大,要确保自己代码没有bash扩展的特性。

区别

sh是早期版本,用POSIX标准,没有bash扩展的特性;bash是后期版本,有bash扩展的特性(默认模式、bash标准模式)。

bash扩展的特性

  • 数组支持
  • [[ 条件测试,提供了比 [ (POSIX test 命令) 更强大的条件测试结构,支持模式匹配、逻辑运算等。
  • function 关键字:Bash 允许使用 function 关键字定义函数。
  • local 关键字:可以在函数中定义局部变量,而 POSIX shell 不支持此特性。
  • 进程替换:支持使用 <(command)>(command) 进行进程替换。
  • shopt 命令:Bash 允许通过 shopt 来开启或关闭 shell 的某些特性。
  • 扩展的重定向:支持 |& 语法将标准输出和标准错误重定向到同一管道。
  • ** 递归通配符:支持使用 ** 来递归匹配文件和目录。
  • 字符串操作:Bash 提供了丰富的字符串处理功能,例如 ${var#pattern}${var/pattern/replacement} 等。
  • $RANDOM$PPID 等特殊变量:这些变量是 Bash 特有的,用于生成随机数、获取父进程 ID 等。
  • 内置算术表达式:支持 (( )) 进行算术运算,比 expr 更灵活。
  • Here字符串 (<<<):将字符串作为输入传递给命令。
  • 命令历史扩展:Bash 提供强大的命令历史记录功能,例如 !! 重复上一个命令,!n 执行第 n 个命令。
  • 别名(alias)支持:Bash 支持通过 alias 定义命令的别名。
  • 数组切片:Bash 提供数组的切片操作,用来获取数组的部分元素。

据(这篇文章)说,POSIX模式下,shell遇到错误会停止;默认模式shell遇到错误仍然进行;(这里说的错误是指运行时的返回的非0值,而不是指脚本中的语法错误。)
然而,这个说法是有问题的。

理论上,POSIX模式下,不支持bash扩展特性,实际上不是

确定sh或bash的真实指向

以sh为例

  1. 确定sh的真实路径,which sh,一般是/usr/bin/sh
  2. 查看sh的指向,ll /usr/bin/sh,得到lrwxrwxrwx. ........ /usr/bin/sh -> bash。这里看到lrwx..... ->bash,所以/usr/bin/sh是一个软链接,指向bash。
    尽管sh指向bash,但通过sh执行脚本,仍然会启用POSIX模式。

脚本解释器(sh或bash)的优先级

执行脚本的命令sh 或 bash >优先于 脚本头定义的【shebang】 >优先于 系统默认的shell。

若,通过sh 或 bash调用脚本,解释器为sh 或 bash;
若,通过相对路径、绝对路径调用脚本,解释器由脚本头的【shebang】决定;
若,通过路径调用脚本,脚本头也没有【shebang】,则由系统默认的shell决定;

结论:区别不大,对于普通开发者来说

  1. 不论是不是POSIX模式,不论脚本头如何写(#!/bin/sh或 #!/bin/bash),不论用sh 或 bash 或 路径调用法,不论加不加--posix参数脚本中的数组与[[]]都支持。即,bash扩展特性都支持。
  2. shell遇到错误是否继续执行,与POSIX模式无关,但与set -e选项有关,默认set -e是关闭的,遇到错误仍然继续。这里的错误,是指脚本运行时抛出的非0返回值,而不是指脚本中的语法错误,语法错误都会造成脚本停止。
  3. 可以通过 if [ -o posix ]来区分POSIX模式,但在bash扩展特性都支持的情况下,没有太大意义;

为什么?

chatgpt给出的原因是,POSIX模式(POSIX兼容模式)与POSIX标准不一样,POSIX兼容模式会让bash尽量符合POSIX标准,但不会完全禁用所有的bash扩展。

区分还有意义吗?

有。当你需要编写一个兼容老系统的脚本,或者要在其他非bash的shell(ksh,dash)上运行的脚本,需要注意不要有bash扩展特性。

其他:执行shell的5种方式

参考

  1. 绝对路径、相对路径法,./test.sh
  2. sh、bash法,sh test.sh
  3. source或【.】法,source test.sh 或 . test.sh

如何查看sh的路径?

which - shows the full path of (shell) commands.

shell头的写法

#!/bin/bash
#!/bin/sh
名称叫做【shebang】,因为#发音是sharp,!发音是bang。它指定了shell的解释器。


http://www.kler.cn/news/361119.html

相关文章:

  • Linux 防火墙的开启、关闭、禁用命令
  • SpringMVC 中的常用注解和用法
  • 探索Web3生态系统:社区、协议与参与者的角色
  • 详解ip route
  • SpringBoot民宿预订系统:打造在线住宿新体验
  • 软件设计模式------简单工厂模式
  • vue 页面导出gif图片 img 导出gif 超简单~
  • Linux 进程终止和进程等待
  • 基于Java+springboot的流浪天使乐园管理系统
  • mlir learn
  • python的特殊方法
  • <a-table>行数据增加点击事件并获取点击行的数据+自定义button按事件
  • 比亚迪与《黑神话:悟空》的游戏全球战略合作。
  • 代码随想录算法训练营第十天|1. 两数之和,第454题.四数相加II
  • vue 报告标题时间来自 elementUI的 el-date-picker 有开始时间和结束时间
  • 【Vue】Vue3.0(十)toRefs()和toRef()的区别及使用示例
  • 【C++刷题】力扣-#243-最短单词距离
  • 期权懂|想交易科创板ETF期权需要开户账号吗?
  • 【C++ 算法进阶】算法提升三
  • Zookeeper面试整理-Zookeeper的基础概念