我正在使用Bash库并希望确保我能够支持尽可能多的环境 - 包括旧的Bash安装。我的开发环境是Bash 4.3,但我的一些用户可能正在运行更旧的版本,目前我无法确认或否认我的库将适用于他们。特别是我希望与OSX兼容(它仍然附带Bash 3.2,AFAIK)。
我知道Bash可以在POSIX兼容模式下运行;是否有类似的设置禁用现代功能?或者在某种兼容模式下运行Bash的方法?我正在寻找任何技术,而不是实际查找和启动旧操作系统并在那里测试我的库。
更新
例如,我已经避免使用associative arrays,因为它们是在Bash 4中引入的,但如果不进行测试我很难确定我不会意外地使用其他一些Bash 4+功能。
答案 0 :(得分:5)
最后回到这个问题,编译(不安装)您感兴趣的bash version(s)非常容易。以下是我测试的方法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.
现在你有一个bash 3.2.57二进制文件,你可以运行,而不是实际上#34;安装"它或修改你的正常环境。
针对此版本运行shell脚本:
$ ./bash your_script.sh
$ 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$
使用env -i
而不是直接调用./bash
会让您处于一个大部分空白的环境中(从shell内部运行env
以查看仍然设置的内容)。更新PATH
允许调用bash
(例如bash -version
)来调用本地bash shell,而不是系统范围的安装(但请注意这会引入整个PATH)。添加--noprofile --norc
可以避免加载.bashrc
及相关脚本。
如果您不想接受任何PATH
修改,只需在子shell内执行export PATH="$PWD:$PATH"
,而不是env
命令的一部分。
这些安装步骤现在是Docker image的一部分,如果这对人们参考有帮助的话。我不一定建议直接使用此图像,但欢迎您从Dockerfile复制。麻省理工学院许可。
答案 1 :(得分:1)
看看shenv:https://github.com/shenv/shenv。就像rbenv,pyenv,goenv和其他人一样,但对于shell,它可以让你在其他版本中安装不同版本的Bash(zsh,fish,yash等)。
(免责声明:我是将pyenv分成shenv的人!)
答案 2 :(得分:0)
您可以使用Bash自己的工具来模拟旧版本的Bash。查找" compat" shopt
上的选项。
请注意,虽然它确实更改了手册页中每个compatNN
条目下描述的行为,但它不会删除当前版本中存在的功能。例如,这不会导致任何错误:
shopt -s compat31
shopt -s globstar
即使{4}仅在Bash 4.0上引入globstar
。
答案 3 :(得分:0)
虽然很高兴知道可以在本地编译bash的任意版本(正如我在other answer中所讨论的),但是现在有一个更简单的选择-official Docker bash
images。
针对多个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