Joh*_*ofy 10 bash alias shell-script wildcards bashrc
在我~./bashrc
的别名中,我已经不再像这样使用通配符了。
alias x='set -f;. any.sh'
Run Code Online (Sandbox Code Playgroud)
但是哪个命令可以再次启用通配符,还是应该在 中设置此选项any.sh
?
欢迎任何回应。
Sté*_*las 12
如果你想水珠是仅在外壳解释代码中禁用any.sh
,有bash4.4+
或ash
基于炮弹,你可以这样做:
x() {
local -
set -o noglob
. any.sh
}
Run Code Online (Sandbox Code Playgroud)
或在zsh
:
x() {
set -o localoptions -o noglob
. any.sh
}
Run Code Online (Sandbox Code Playgroud)
那是使用函数而不是别名(您不想为多个命令使用别名,因为这在您执行cmd | x
或cmd && x
例如执行时不会执行您想要的操作),确保更改选项(将$-
变量作为一种方式)查看它)是函数本地的,禁用 glob 并获取文件。
使用旧版本的bash
,您可以执行以下操作:
x() {
local ret restore
[[ $- = *f* ]] || restore='set +o noglob'
set -o noglob
. any.sh
ret=$?
eval "$restore"
return "$ret"
}
Run Code Online (Sandbox Code Playgroud)
或者可能是一个更通用的辅助函数,例如:
withopt() {
local ret option
local -a restore
option=$1; shift
[[ -o $option ]] || restore=(set +o "$option")
set -o "$option"
"$@"
ret=$?
"${restore[@]}"
return "$ret"
}
Run Code Online (Sandbox Code Playgroud)
然后,如果您愿意,可以使用别名:
alias x='withopt noglob . any.sh'
Run Code Online (Sandbox Code Playgroud)
请注意,*
如果您这样做,它不会阻止被扩展:
x *
Run Code Online (Sandbox Code Playgroud)
由于该noglob
选项在评估该命令后很长时间才被启用。为此,请参阅我的其他答案(另一个问题的答案)。
这是在问题澄清之前发布的,现在解决了不同的需求。我仍然把它留在这里,因为这对其他人可能有用。
我想你希望能够做到:
x *.txt
Run Code Online (Sandbox Code Playgroud)
以及*.txt
要传递的未展开的any.sh
和随后重新启用的 glob。
你不能用 来做到这一点bash
。zsh
在你可以做的地方使用:
alias x='noglob any.sh`
Run Code Online (Sandbox Code Playgroud)
其中noglob
仅禁用该命令的别名。
$ echo /etc/p*d
/etc/pam.d /etc/passwd /etc/profile.d
$ noglob echo /etc/p*d
/etc/p*d
Run Code Online (Sandbox Code Playgroud)
请注意,它仅影响该命令参数中的 glob 扩展echo
。*
仍会在noglob echo $(echo *)
ornoglob eval 'echo *'
或 的位置noglob . some-script
进行扩展。some-script
echo *
实际上,可能有一种方法bash
:
oneshot_noglob() {
case $- in
(*f*) ;; # globs already disabled
(*) set -f; shot=0; debug_trap=$(trap -p DEBUG)
trap '
if ((++shot == 2)); then
set +f
trap - DEBUG
'"$debug_trap"'
fi' DEBUG;;
esac
}
alias x='oneshot_noglob; any.sh'
Run Code Online (Sandbox Code Playgroud)
它使用 DEBUG 陷阱set +f
在set -f
.
现在,对于包含多个命令的所有别名,有一些注意事项。
echo foo | x
Run Code Online (Sandbox Code Playgroud)
变成:
echo foo | oneshort_noglob; any.sh
Run Code Online (Sandbox Code Playgroud)
因此 的输出echo
仅馈送到oneshort_noglob
。
对于类似的事情也是如此:
cmd && x
Run Code Online (Sandbox Code Playgroud)
any.sh
无论cmd
成功与否都会执行到哪里。
另请注意,它会影响每个级别的子 shell 中的所有 glob,直到在主 shell 进程中执行第二个命令之前。
例如,在 中x $(echo *; echo *) *
,这些都*
不会被扩展,因为除非设置该选项,否则 DEBUG 陷阱不会被继承extdebug
。