体験版で正しい引用

体験版で正しい引用

位置引数のみを実行するスクリプトがあります。 (私はセキュリティリスクを知っており、このスクリプトは最小限の作業例なので、どの目的にも使用されません。)

$ cat script
> #!/usr/bin/env bash
>
> eval "${*}"


$ cat "docu ment"
> Lorem ipsum dolor sit amet

私がしたいのは、or./script cat "docu ment"を使ってスクリプトを呼び出すことです。./script cat docu\ mentただし、引用符またはエスケープ文字が消え、スクリプトが試みますがcat docu ment機能しません。この場合、参照をどのように変更できますか?

編集:私が本当に望むのは、成功した終了コードを返すまで、コマンドを何度も呼び出すか、n回試みることです。私のスクリプトは次のとおりです

#!/usr/bin/env bash

# Try command several times, until it reports success (exit code 0)
# or I give up (tried n times)

tryMax=10
try=1

# Do until loop in bash
while
    eval "${@}"
    exitcode="${?}"
    [[ "${exitcode}" -ne 0 && "${try}" -lt "${tryMax}" ]]
do (( try++ ))
done

if [[ "${exitcode}" -ne 0 ]]; then
    echo -n "I tried hard, but did not manage to make this work. The exit code "
    echo "of the last iteration of this command was: ${exitcode}."
    exit "${exitcode}"
fi

答え1

ここでは必要ありませんeval。以下を使用できます"$@"

while
    "${@}"
    exitcode="${?}"
    [[ "${exitcode}" -ne 0 && "${try}" -lt "${tryMax}" ]]
do ...

"$@"スクリプトのすべてのパラメータを別々の「単語」に拡張します。- ブロックされた元の参照を尊重します。噴射- それから実行を待つコマンドとして最初の引数を使用できます。cat)、残りのパラメータはcatdocu ment)のパラメータとして使用されます。

うまくいかない場合:

  • "$@"着信コマンドがパイプ、関数定義、ループなどの他のより高いレベルのシェル構成を使用するようにしたい場合は、パラメータ拡張の前に処理され、拡張後には再試行されません。
  • コマンドの戻りコードが無効になった場合! cmd!また、パラメーター拡張前処理コマンドの開始時に処理されます。
  • コマンドが複数のコマンドの場合、orまたは、x \; yor$'x\ny'x $'\n' yorと同じです。これはすべて日常的な主張です。&&||
  • コマンドの前に変数割り当てがある場合、たとえばLD_LIBRARY_PATH=/x foo変数をスクリプト名の前に置くことはできますが、パラメータコマンドの前には置くことはできません。
  • コマンドにリダイレクトがある場合は、その中にあります>foo3<barスクリプトには独自のログ出力があるため、これらの内容はスクリプトに添付されている場合と添付されない場合があります。
  • コマンドにここに文書があるか、ここに文字列がある場合。スクリプト自体に添付されている場合は一度だけ読み取ることができるため、コマンドが失敗した正確な時点に応じて問題ないかもしれません。とにかく、これらは適切に渡すのが難しいですeval
  • コマンドがサブシェル( ... )またはコマンドグループの場合{ ... ; }。これは文法設定ではなく、(andというコマンドで処理されます。{
  • コマンドに以下が含まれている場合コマンドの置き換え$(...) 繰り返し実行する必要がある。この(または他のシェル構成)を使用してネイティブ引数を生成できますが、スクリプトが実行を開始すると、すべて固定文字列になります。
  • コマンドに繰り返し評価する必要がある他の要因がある場合(例:$RANDOMまたは算術拡張$((i++))
  • コマンドがtimeいいえしたがって、組み込みコマンドもパラメータ拡張の前に処理されます。

しかし、そうでなければevalそれを完全に避けることができ、そうする必要があります。可能なセキュリティ問題を無視しても、正しく構築することは非常に脆弱です。

関連情報