コンパイルされたコマンドラインプログラムが、bashまたはcshに、パラメータ内のワイルドカード文字を展開したくないことを伝える方法はありますか?
たとえば、次のようなシェルコマンドが必要な場合があります。
foo *
単にその文字の数値ASCII値を返します。
いいえ。コマンドが実際に実行される前に展開が行われます。
コマンドを実行する前、または星を引用することによってのみ、globを無効にできます。
$ # quote it
$ foo '*'
$ # or escape it
$ foo \*
$ # or disable the glob (noglob)
$ set -f
$ foo *
$ # alternative to set -f
$ set -o noglob
$ # undo it by
$ set +o noglob
コマンド自体はグロビングをオフにすることはできませんが、ユーザーは特定のコマンドをグロブしないようにUnixシェルに指示することができます。これは通常、シェルの構成ファイルを編集することで実現されます。コマンドfoo
がコマンドパスに沿って見つかると仮定すると、適切な構成ファイルに以下を追加する必要があります。
Sh、bash、およびkshシェルの場合:
alias foo='set -f;foo';foo(){ command foo "$@";set +f;}
Cshおよびtcshシェルの場合:
alias foo 'set noglob;\foo \!*;unset noglob'
Zshシェルの場合:
alias foo='noglob foo'
コマンドパスを使用する必要はありません。コマンドfooがディレクトリ〜/ binに保存されているとすると、上記は次のようになります。
Sh、bash、およびkshシェルの場合:
alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}
Cshおよびtcshシェルの場合:
alias foo 'set noglob;$home/bin/foo \!*;unset noglob'
Zshシェルの場合:
alias foo='noglob ~/bin/foo'
上記のすべては、AppleのOSX 10.9.2を使用してテストされました。注:上記のコードをコピーするときは、スペースの削除に注意してください。それらは重要かもしれません。
ユーザー geira は、bashシェルの場合、
alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}
に置き換えることができます
reset_expansion(){ CMD="$1";shift;$CMD "$@";set +f;}
alias foo='set -f;reset_expansion ~/bin/foo'
これにより、関数fooが不要になります。
このドキュメントの作成に使用されたいくつかのWebサイト:
展開は、プログラムが実行される前にシェルによって実行されます。プログラムには、拡張が発生したかどうかについての手がかりがありません。
set -o noglob
呼び出しシェルで展開をオフにしますが、それを行う必要がありますbeforeプログラムを呼び出します。
別の方法は、引数を引用することです。
foo "*"
注意:マスクに一致する名前がない場合、bashは展開せずに引数をそのまま渡します!
証明(pa.pyは引数を出力するだけの非常に単純なスクリプトです):
$ ls
f1.cc f2.cc pa.py
$ ./pa.py *.cc
['./pa.py', 'f1.cc', 'f2.cc']
$ ./pa.py *.cpp
['./pa.py', '*.cpp']
いいえ。Bourneスタイルのシェルは、コマンドを実行する前に、必要に応じて常に globbing を実行します。ユーザーは、foo \*
のように、グロビングを防ぐために引数を引用またはエスケープする必要があります。実行されている実際のプログラムは設定を示すことができません。