简体   繁体   English

如何在旧版本的 Bash 上测试我的 Bash 脚本?

[英]How can I test my Bash script on older versions of Bash?

I'm working on a Bash library and want to ensure I'm supporting as many environments as possible - including old installations of Bash.我正在开发一个 Bash 库,并希望确保我支持尽可能多的环境——包括 Bash 的旧安装。 My development environment is Bash 4.3, but some of my users may well be running much older versions and presently I have no way to confirm or deny that my library will work for them.我的开发环境是 Bash 4.3,但我的一些用户可能运行的是更旧的版本,目前我无法确认或否认我的库是否适用于他们。 In particular I'd like to be compatible with OSX (which still ships with Bash 3.2, AFAIK).特别是我想与 OSX 兼容(它仍然与 Bash 3.2,AFAIK 一起提供)。

I know Bash can run in POSIX-compliant mode;我知道 Bash 可以在 POSIX 兼容模式下运行; is there a similar setting to disable modern functionality?是否有类似的设置来禁用现代功能? Or a way to run Bash in some sort of compatibility mode?或者以某种兼容模式运行 Bash 的方法? I'm looking for any technique short of actually finding and booting up old operating systems and testing my library there.除了实际查找和启动旧操作系统并在那里测试我的库之外,我正在寻找任何技术。

Update更新

For example, I've avoided using associative arrays since they were introduced in Bash 4, but it's hard to be sure without testing that I'm not accidentally using some other Bash 4+ feature.例如,自从在 Bash 4 中引入关联数组以来,我一直避免使用它们,但是如果不进行测试就很难确定我没有不小心使用了其他一些 Bash 4+ 功能。

Finally coming back to this question, it's pretty easy to just compile (without installing) the bash version(s) you're interested in. Here's how I'm testing Bash 3.2.57:最后回到这个问题,编译(无需安装)您感兴趣的bash 版本非常容易。以下是我测试 Bash 3.2.57 的方式:

$ mkdir ~/bash
$ cd ~/bash
$ wget http://ftp.gnu.org/gnu/bash/bash-3.2.57.tar.gz
$ tar xvzf bash-3.2.57.tar.gz
$ cd bash-3.2.57
$ ./configure
$ make
# if `make` fails due to yacc, run `sudo apt-get install byacc`
# No need to run `make install`
$ ./bash -version
GNU bash, version 3.2.57(1)-release (armv7l-unknown-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.

Now you have a bash 3.2.57 binary you can run, without actually "installing" it or modifying your normal environment.现在您有一个可以运行的 bash 3.2.57 二进制文件,而无需实际“安装”它或修改您的正常环境。

To run a shell script against this version:要针对此版本运行 shell 脚本:

$ ./bash your_script.sh

To enter a clean interactive prompt :要输入干净的交互式提示

$ env -i PATH="$PWD:$PATH" ./bash --noprofile --norc
bash-3.2$ bash -version
GNU bash, version 3.2.57(1)-release (armv7l-unknown-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
bash-3.2$ 

Using env -i rather than just calling ./bash directly leaves you with a mostly-empty environment (run env from inside the shell to see what's still set).使用env -i而不是直接调用./bash您留下一个几乎是空的环境(从 shell 内部运行env以查看仍然设置的内容)。 Updating the PATH allows calls to bash (eg bash -version ) to invoke the local bash shell, not the system-wide installation (but note this pulls in your whole PATH).更新PATH允许调用bash (例如bash -version )来调用本地 bash shell,而不是系统范围的安装(但请注意,这会拉入您的整个 PATH)。 Adding --noprofile --norc avoids loading your .bashrc and associated scripts.添加--noprofile --norc可避免加载您的.bashrc和相关脚本。

If you don't want to pick up any PATH modifications, just execute export PATH="$PWD:$PATH" once inside the subshell instead of as part of the env command.如果您不想获取任何PATH修改,只需在子 shell 中执行一次export PATH="$PWD:$PATH"而不是作为env命令的一部分。


I have a Docker image ( repo ) using these installation steps, if that's helpful for folks to reference.我有一个使用这些安装步骤的Docker 映像( repo ),如果这对人们参考有帮助的话。 I wouldn't necessarily suggest using this image directly, but you're welcome to copy from the Dockerfile/install script.我不一定建议直接使用此图像,但欢迎您从 Dockerfile/install 脚本中复制。 MIT licensed.麻省理工学院许可。

Although it's nice to know that it's possible to compile arbitrary versions of bash locally (as discussed in my other answer ), these days there's a much simpler option - the official Docker bash images .虽然很高兴知道可以在本地编译任意版本的 bash(如我在其他答案中所讨论的),但现在有一个更简单的选项 -官方 Docker bash映像

To test a script against multiple bash versions is often as simple as:针对多个 bash 版本测试脚本通常很简单:

for v in 3 4 5; do # or whatever versions you're interested in
  docker run -v "$PWD:/mnt" "bash:$v" \
    bash /mnt/your_script.sh
done

Have a look at shenv: https://github.com/shenv/shenv .看看 shenv: https ://github.com/shenv/shenv。 Just like rbenv, pyenv, goenv and others, but for shells, it lets you install different versions of Bash among others (zsh, fish, yash, etc.).就像 rbenv、pyenv、goenv 等,但对于 shell,它允许您安装不同版本的 Bash 等(zsh、fish、yash 等)。

(Disclaimer: I'm the one who forked pyenv into shenv!) (免责声明:我是将 pyenv 分叉到 shenv 的人!)

You can use Bash own facilities to emulate older version of Bash.您可以使用 Bash 自己的工具来模拟旧版本的 Bash。 Look up "compat" options on shopt .shopt上查找“compat”选项。

Mind you, while it does change behavior as described under each compatNN entry in the man page, it does not remove features that are otherwise present on the current version.请注意,虽然它确实改变了手册页中每个compatNN条目下描述的行为,但它不会删除当前版本中存在的其他功能。 For example, this doesn't cause any errors:例如,这不会导致任何错误:

shopt -s compat31
shopt -s globstar

Even though globstar was only introduced on Bash 4.0.尽管globstar仅在 Bash 4.0 上引入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM