エイリアスの~./bashrc
内で、このようにグロビングを無効にしました。
alias x='set -f;. any.sh'
しかし、どのコマンドが再度グロビングを有効にするか、このオプションをany.sh
に設定する必要がありますか?
どんな反応でも大歓迎です。
シェルがany.sh
のコードをbash4.4+
またはash
ベースのシェルで解釈しているときにのみグロブを無効にする場合は、次のようにできます。
x() {
local -
set -o noglob
. any.sh
}
またはzsh
内:
x() {
set -o localoptions -o noglob
. any.sh
}
つまり、エイリアスの代わりに関数を使用します(たとえば、cmd | x
またはcmd && x
を実行するときに、エイリアスが必要な機能を実行しないため、いくつかのコマンドにエイリアスを使用したくない)。オプションへの変更(それを見る1つの方法として$-
変数への変更)は関数に対してローカルであり、グロブを無効にしてファイルをソースします。
古いバージョンのbash
では、次のことができます。
x() {
local ret restore
[[ $- = *f* ]] || restore='set +o noglob'
set -o noglob
. any.sh
ret=$?
eval "$restore"
return "$ret"
}
または、次のようなより一般的なヘルパー関数:
withopt() {
local ret option
local -a restore
option=$1; shift
[[ -o $option ]] || restore=(set +o "$option")
set -o "$option"
"$@"
ret=$?
"${restore[@]}"
return "$ret"
}
次に、必要に応じてエイリアスを使用できます。
alias x='withopt noglob . any.sh'
次の場合、*
の展開が妨げられることはありません。
x *
noglob
オプションは、コマンドが評価されてからかなり後に有効になるため、それについては、 他の答え (別の質問に対する答え)を参照してください。
これは、質問が明確になる前に投稿され、現在は別のニーズに対応しています。他の人に役立つので、私はまだここに残しています。
あなたができるようになりたいと思います:
_x *.txt
_
_*.txt
_は展開されずに_any.sh
_に渡され、グロブは後で再度有効になります。
bash
ではそれはできません。代わりにzsh
を使用できます。
_alias x='noglob any.sh`
_
noglob
は、そのコマンドのエイリアスのみを無効にします。
_$ echo /etc/p*d
/etc/pam.d /etc/passwd /etc/profile.d
$ noglob echo /etc/p*d
/etc/p*d
_
これは、そのecho
コマンドの引数のグロブの展開にのみ影響することに注意してください。 _*
_は引き続きnoglob echo $(echo *)
または_noglob 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'
_
DEBUGトラップを使用して、_set +f
_の後に1つのコマンドが実行された後、_set -f
_を復元します。
現在、複数のコマンドを含むすべてのエイリアスがあるため、いくつかの注意点があります。
_echo foo | x
_
になる:
_echo foo | oneshort_noglob; any.sh
_
したがって、echo
の出力は_oneshort_noglob
_にのみ送られます。
同じようなもの:
_cmd && x
_
cmd
が成功したかどうかに関係なく、_any.sh
_が実行される場所。
また、メインシェルプロセスで2番目のコマンドが実行される直前まで、サブシェルのすべてのレベルのすべてのグロブに影響することにも注意してください。
たとえば、x $(echo *; echo *) *
では、extdebug
オプションを設定しない限りDEBUGトラップが継承されないため、これらの_*
_は拡張されません。