0

スクリプトnerfはスクリプトherdを呼び出し、スクリプトはスクリプトを呼び出しますer。 に渡す必要のある引数を明示的に受け取るnerfon フラグを使用します。herder

これは以前は問題ではありませんでした。 がコマンド ラインから呼び出されたばかりのnerfときherdは、 -p フラグの引数を単一引用符で囲むことができ、 's によって解釈されることはありませんでしherdgetoptsが、代わりにer'sによって解釈されましたgetopts

しかし、最終的に に移動する必要があるフラグで値を生成したerので、 で変数を展開する必要があります$file_contentsが、に到達するまではnerfによって解釈されないようにします。getoptser

これら 3 つのスクリプトはいずれも変更できます。

$ cat nerf
#!/bin/bash
file_contents="`cat one_liner_file`"
er_args="-jkl -m $file_contents"
./herd -p "$er_args"              # <-- the problem


$ cat herd
#!/bin/bash
passthru_args=""
while getopts "p:a:b:cde" opt
do
  case $opt in
    p) passthru_args="$OPTARGS" ;;
    ...
  esac
done
./er "$passthru_args"


$ cat er
#!/bin/bash
while getopts "jklm:" opt
do
  case $opt in
    ...
  esac
done

上記のマークされた行で単一引用符を使用すると、リテラル文字列 "$er_args" が渡されます。二重引用符を使用すると、フラグは によって直接解釈されherdます。二重引用符の中に一重引用符を使用すると、フラグは getopts によって解釈されません。

ここにはエレガントな解決策はないと思いますが、間違っている場合はお知らせください。私が考えることができる唯一の解決策はくだらないです:

  1. を通じてすべてerのフラグを明示的に公開しherdます。
  2. erからコールを削除し、herd直接 に配置しnerfます。
  3. ???
4

1 に答える 1

3

多くのツールが行うことは、渡されたときに-p "-jkl -m something"、疑似シェル構文を使用して文字列を分割することです。スペースと引用符の処理が予測不能になるため、これは悪い考えです。

代わりに、個々の単語をコマンドに渡す方法を用意することをお勧めします。これが何をするかです-- or以降までfind -execのすべての引数は文字通り別々の引数として渡されます。-exec+;

herd同じセマンティクスを持つa の簡単な例を次に示します。

#!/bin/bash
passthru_args=()
while getopts "pa:b:cde" opt
do
  case $opt in
    p)
      while [[ ${!OPTIND} != ';' ]]
      do
        passthru_args+=("${!OPTIND}")
        let OPTIND++
      done
      let OPTIND++
    ;;
    *) echo "herd: $opt is $OPTARG"
    ;;
  esac
done
./er "${passthru_args[@]}"

実行できるようになりました./herd -p -jkl -m "some stuff" \; -a foo

これは./er -jkl -m "some stuff"、スペースの問題なく安全に実行されます (ただし;、引数ターミネータとして使用する複数の呼び出しをネストするのは困難です)。

于 2014-05-13T21:15:30.043 に答える