パラメータ分析を勉強するとき強く打つスクリプトの使い方選択項目のインポート、私はほとんどどこでもこの構造が使用されるのを見ました: eval set -- "$SOMETHING_PARSED"
。例えば、ここそしてここ。今後は作業スクリプトを無料で公開する予定なので、ユーザーにそのような空白を残したくありません。これを避ける方法はありますか?
説明するここバージョンによって異なります選択項目のインポート、使用する必要はありませんeval
。しかし、少なくとも私の場合はそうではありません。選択項目のインポート次の文字列が与えられた場合、. ' -j --version= '\''1'\'' --number= '\''2'\'' -- '\''2C_IA/GBCs_out/nohope_2C_IA_off. xml'\'''
&set
はそれを正確に割り当てます$1
。
答え1
getopt
非伝統的な方法で実装される、util-linux
または少なくとも非伝統的な方法で使用される全体的なポイントbusybox
は、評価するシェルコードを出力することです。シェル構文の特殊文字は実際にはオプション引数 1 で引用されるため、getopt
² を除いて Bourne と同様のシェルで使用しても安全です。yash
POSIXsh
言語では、コマンドがランダムな文字列のリストをシェルに返す最も簡単な方法です。
getopt
この作業モードをサポートしていない実装(getopt
分割+グローブ演算子の使用に依存する元の実装)は、ランダムなリストを返すことができないため、意図的に破損しています。
eval
何らかの理由で使用したくないがzsh
切り替えるオプションがある場合は、次のものを使用できます。
argv=( "${(@XQ)${(z)$(getopt...)}}" ) || exit
パラメータ拡張フラグは、シェルの引用構文(引用構文ですが、単一引用符のみを使用して引用)にz
基づいて表示され、引用符を削除し、構文エラーが発生すると文句を言います。zsh
getopt
Q
X
唯一の利点は、getopt
邪悪なコードを出力する邪悪な命令に置き換えられても実行されないことです。邪悪な奴交換中ですgetopt
。取る方が良いかもしれません。走る評価できるように出力するのではなく、邪悪なコード自体です。
NUL で区切られたコマンドを送信する場合は、出力を配列に読み込んで任意の文字列リストをbash
4.4+ に渡すことができます。sh
readarray -td '' array < <(cmd) || exit # readarray failed.
wait "$!" || exit # cmd failed
set -- "${array[@]}"
または次のようになりますzsh
。
argv=( "${(0@)$(cmd)}" ) || exit
argv[-1]=() # remove the empty trailing argument caused by the terminating NUL
getopt
したがって、理論的には、この動作モードを使用してメソッドを実装することが可能です。
このgetopt
ユーティリティは、出力を評価することが期待される唯一のユーティリティではありません。以下も参照してください。
eval "$(dbus-launch --sh-syntax)"
eval "$(dpkg-architecture -u)"
eval "set $(git rev-parse --sq --prefix "$prefix" -- "$@")"
eval "$(lesspipe)"
eval "$(xz --robot --version)"
eval "$(resize)"
eval "$(dircolors)"
シェルの環境を変更するために使用されます。
現在の状態を保存して後で復元するために使用できるすべての項目も参照してください。
aliases=$(alias -L) # zsh
aliases=$(alias -p) # ksh/bash
options=$(set +o)
locale=$(locale)
元に戻すとeval "$aliases"
...eval "$options"
getopt
使用された解析オプションを含まない代替方法は次のとおりですeval
。
- 標準
getopts
の組み込み機能(ksh93
³を除く)は単一文字オプションのみをサポートします。 zsh
zparseopts
キューブ- 私のもの
getopts_long
POSIXsh
関数
¹オプション名にはありませんが、少なくともバージョン2.38ではバグと見なすことができます。スクリプトオプションに愚かな名前を選択しない限り、大丈夫でしょう。
²現在のバージョンyash
(2022年6月現在)は有効なテキストのみを処理できるため、現在のロケールからテキストにデコードできない引数はブロックされます。
³ksh93getopts
またはzshはzparseopts
GNU(または)と同じ方法でオプションを解析しません。特に、短縮された長いオプションはサポートされていません。getopt_long()
util-linux
getopt