The*_*des 9 bash configuration shell-script shopt
我在一个相对异构的环境中工作,我可能在不同的 HPC 节点、VM 或我的个人工作站上运行不同版本的 Bash。因为我将我的登录脚本放在 Git 存储库中,所以我希望全面使用相同的(ish).bashrc
,而没有很多“如果这个主机,那么......”类型的混乱。
我喜欢Bash 的默认行为吗?4.1一个可扩展cd $SOMEPATH
到cd /the/actual/path
按下时Tab键。在bash 4.2及以上,则需要shopt -s direxpand
重新启用此行为,而这并没有变得可用,直到4.2.29。不过,这只是一个例子;另一个可能相关的shopt
选项complete_fullquote
(虽然我不知道它的确切作用)可能也改变了 v4.2 的默认行为。
但是,direxpand
早期版本的 Bash 无法识别,如果我尝试shopt -s direxpand
在我的.bashrc
.
-bash: shopt: direxpand: invalid shell option name
Run Code Online (Sandbox Code Playgroud)
我想做的是shop -s direxpand
在 Bash > 4.1 上以一种稳健的方式包装一个条件来启用该选项,而不会影响旧版本的 Bash(即,不仅仅是将错误输出重定向到/dev/null
)。
Gil*_*il' 17
我不明白将错误重定向到/dev/null
. 如果您希望您的代码健壮到set -e
,请使用常见的习惯用法… || true
:
shopt -s direxpand 2>/dev/null || true
Run Code Online (Sandbox Code Playgroud)
如果您想在该选项不存在的情况下运行一些后备代码,请使用以下返回状态shopt
:
if shopt -s direxpand 2>/dev/null; then
… # the direxpand option exists
else
… # the direxpand option does not exist
fi
Run Code Online (Sandbox Code Playgroud)
但是如果你真的不喜欢重定向错误,你可以使用完成机制来执行自省。这假设您没有带有 bash 的过时机器?2.03 没有可编程完成。
shopt_exists () {
compgen -A shopt -X \!"$1" "$1" >/dev/null
}
if shopt_exists direxpand; then
shopt -s direxpand
fi
Run Code Online (Sandbox Code Playgroud)
这种方法避免了分叉,这在某些环境(如 Cygwin)上很慢。直接的也是如此2>/dev/null
,我认为你无法在性能上击败它。
Luc*_*ini 14
检查direxpand
输出中是否存在shopt
并启用它,如果它是:
shopt | grep -q '^direxpand\b' && shopt -s direxpand
Run Code Online (Sandbox Code Playgroud)
当您确定某个特定shopt
选项在 Bash 的某个主要/次要/补丁版本中可用时,您可以检查$BASH_VERSION
变量或$BASH_VERSINFO[]
数组元素以便有条件地启用它。
这是 Bash 4.2.29 或更高版本的测试,该版本direxpand
首次引入4.2 系列:
if [[ $BASH_VERSION == 4.2.* && ${BASH_VERSINFO[2]} -ge 29 ]] ||
[[ ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -ge 3 ]] ||
[[ ${BASH_VERSINFO[0]} -ge 5 ]]; then
shopt -s direxpand
fi
Run Code Online (Sandbox Code Playgroud)
编辑:需要明确的是,这是一个荒谬的过度设计的解决方案,用于简单地忽略来自您的登录脚本的错误消息,但我确实想记录它,无论如何,为了我自己的启发。
注意周围的大括号,这是必需的,以及使用and ,它们进行整数而不是(依赖于语言环境的)词法比较。如果不带引号,则的RHS操作被视为猛砸内“extglob”模式/条件语句,如注意这里,这使得更美观的“开始使用”比较不是一个正则表达式将,IMO。${BASH_VERSINFO[index]}
-eq
-gt
==
[[
]]
该$BASH_VERSINFO
数组包含您在以下输出中看到的所有信息bash --version
:
bash --version | head -1
# result:
# GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
declare -p BASH_VERSINFO
# result:
# declare -ar BASH_VERSINFO='([0]="4" [1]="3" [2]="48" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu")'
Run Code Online (Sandbox Code Playgroud)
当它是不是从文件明确shopt
在该版本的Bash(S)成为支持或改变他们的行为,由卢西亚诺提出的方法是好的:
# note the '-q' so that the matched pattern isn't actually printed
shopt | grep -q direxpand && shopt -s direxpand
Run Code Online (Sandbox Code Playgroud)
...就像吉尔斯提出的解决方案一样,忽略错误 ( shopt -s direxpand 2>/dev/null
),$?
如果绝对必要,可能会检查。
参考文献:1,2,3
相关阅读:设置和禁用了javascript -为什么是两个?
归档时间: |
|
查看次数: |
1161 次 |
最近记录: |