首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >#!/bin/sh vs #!/bin/bash,以获得最大的可移植性

#!/bin/sh vs #!/bin/bash,以获得最大的可移植性
EN

Server Fault用户
提问于 2017-07-30 05:08:01
回答 1查看 6.6K关注 0票数 38

我通常使用Ubuntu服务器,据我所理解,这些服务器可以将/bin/sh链接到/bin/dash。很多其他发行版都是通过符号链接/bin/sh/bin/bash的。

由此我了解到,如果脚本在顶部使用#!/bin/sh,那么它可能不会在所有服务器上以相同的方式运行?

当您想要在服务器之间最大限度地实现脚本的可移植性时,是否建议在脚本上使用哪个shell?

EN

回答 1

Server Fault用户

回答已采纳

发布于 2017-07-30 06:37:14

shell脚本大约有四个级别的可移植性(就shebang行而言):

  1. 最可移植的:使用#!/bin/sh shebang,并且只使用POSIX标准中指定的基本shell语法。这应该适用于几乎所有的POSIX/unix/linux系统。(好吧,除了Solaris 10和更早版本,它有真正的遗留Bourne,在POSIX之前就已经不兼容了,比如/bin/sh。)
  2. 第二大可移植性:使用#!/bin/bash (或#!/usr/bin/env bash) shebang行,并坚持bash v3特性。这将适用于任何具有bash (在预期位置)的系统。
  3. 第三大可移植性:使用#!/bin/bash (或#!/usr/bin/env bash) shebang行,并使用bash v4特性。这在任何具有bash v3的系统上都会失败(例如,由于许可原因,macOS必须使用它)。
  4. 最少可移植性:使用#!/bin/sh shebang,并使用POSIX语法的bash扩展。这在任何系统上都会失败,而不是bashfor/bin/sh(例如最近的Ubuntu版本)。永远不要这样做;这不仅仅是一个兼容性问题,它是完全错误的。不幸的是,这是很多人都会犯的错误。

我的建议是:使用前三项中最保守的一项,它提供脚本所需的所有shell功能。对于最大可移植性,请使用选项#1,但根据我的经验,一些bash特性(如数组)非常有用,因此我将使用#2。

你能做的最糟糕的事情是#4,使用错误的弹出声。如果您不确定哪些特性是基本的POSIX,哪些是bash扩展,那么要么坚持bash shebang (即选项2),要么使用非常基本的shell彻底测试脚本(比如Ubuntu服务器上的破折号)。Ubuntu有一个值得注意的好的羞耻感清单

关于unix&linux问题“与sh兼容意味着什么?”中的shell和堆栈溢出问题“sh和bash的区别”中的shell之间的历史和差异,有一些非常好的信息。

另外,要注意的是,shell并不是不同系统之间唯一不同的地方;如果您习惯了linux,那么您就习惯了GNU命令,这些命令在其他unix系统(如bsd、macOS)上可能找不到很多不标准的扩展。不幸的是,这里没有简单的规则,您只需知道所使用的命令的变化范围。

在可移植性方面,最讨厌的命令之一是最基本的命令之一:echo。任何时候,当您将它与任何选项(例如echo -necho -e)或字符串中的任何转义符(反斜杠)一起使用以打印时,不同的版本将执行不同的操作。任何时候,如果您想要在字符串后面打印没有行提要的字符串,或者在字符串中使用转义符,请使用printf (并学习它是如何工作的--它比echo更复杂)。ps命令是也是一塌糊涂

另一个常用的方法是命令选项语法的最近/GNUish扩展:旧(标准)命令格式是命令后面跟着选项(带有单个破折号,每个选项是一个字母),后面跟着命令参数。最近的(通常也是不可移植的)变体包括长选项(通常与--一起引入),允许选项在参数之后出现,并使用--将选项从参数中分离出来。

票数 69
EN
页面原文内容由Server Fault提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://serverfault.com/questions/865874

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档