2

bashスクリプトからコマンドを実行しようとしています。コマンド自体には一重引用符が含まれていますが、一重引用符の中に展開する必要のある変数があるため、それらを機能させることができません。これがbashスクリプトです:

#!/bin/bash

if [ "$2" == "PracSci" ];
then
    echo "Running tabulate.science.r"
    R CMD BATCH --no-save --no-restore --slave '--args $1 $2 $3' tabulate.science.r /dev/tty
else
    echo "Running tabulate.r"
    R CMD BATCH --no-save --no-restore --slave '--args $1 $2 $3' tabulate.r /dev/tty
fi

./script.sh 2 Vocab May12たとえばのように実行すると、コマンド自体は変数値なしで実行されます。

コマンドを実行しながら変数を展開するにはどうすればよいですか?

明確にするために、私が実行しようとしているコマンドは次のとおりです:( R CMD BATCH --no-save --no-restore --slave '--args $1 $2 $3' tabulate.r /dev/ttyコマンド内の一重引用符を含む)。

ありがとうございました!

4

4 に答える 4

5

簡単な答え:一重引用符の代わりに二重引用符を使用してください(@Pavelが提案したように)。疑わしい場合はset -x、シェルがコマンドをどのように解析しているかを調べるために使用します。

長い答え:引用符はコマンドに渡されません。代わりに、引数がコマンドに渡される前に、シェルによって解析(および削除)されます。彼らがすることは、シェルが引用符の中にあるものを解析する方法を変更することです(通常、一部の文字の特殊な意味を抑制することによって)。つまり、解析したい特殊文字を許可するために適切な引用符を選択し、それらを抑制する必要があります単なる文字として扱いたい。たとえば、次のコマンドについて考えてみます。

R CMD BATCH --no-save --no-restore --slave '--args 2 Vocab May12' tabulate.r /dev/tty

シェルは、コマンドの一重引用符で囲まれたセクションにあるすべての文字の特別な意味を無視します。特別な意味を持つ唯一の文字はスペースです。スペースは通常、引数間の区切り文字として機能します。この場合、一重引用符により、シェルはそれらを単一の引数の一部として扱います。これらの他のコマンド:

R CMD BATCH --no-save --no-restore --slave "--args 2 Vocab May12" tabulate.r /dev/tty
R CMD BATCH --no-save --no-restore --slave --args' '2' 'Vocab' 'May12 tabulate.r /dev/tty
R CMD BATCH --no-save --no-restore --slave --args\ 2\ Vocab\ May12 tabulate.r /dev/tty

...すべて(何らかの方法で)シェルがスペースを引数間の区切り文字ではなく引数の一部として扱うため、すべてがまったく同じことを行います。

それでは、機能していないコマンドを見てみましょう。

R CMD BATCH --no-save --no-restore --slave '--args $1 $2 $3' tabulate.r /dev/tty

問題は、一重引用符が(必要に応じて)スペースの特別な意味を抑制している一方で、(不要な)$sの特別な意味も抑制していることです。したがって、より選択的なものが必要です。$11つのオプションは、スペースを引用符で囲む/エスケープするが、その他は引用符で囲まないままにすることです。

R CMD BATCH --no-save --no-restore --slave --args' '$1' '$2' '$3 tabulate.r /dev/tty
R CMD BATCH --no-save --no-restore --slave --args\ $1\ $2\ $3 tabulate.r /dev/tty

(これらのコマンドはどちらもまったく同じことを行うことに注意してください。)これらはほとんど機能しますが、問題が発生する可能性があります。シェルは$1スクリプトの引数などを置き換えますが、追加の解析を行います。 :引数の区切り文字として使用するスペース、ファイル名の照合を行うワイルドカードなどを探します。引数には特殊文字が含まれない可能性があるため、これはおそらく含まれないでしょうが、すべてのことは必要ないと確信しています。問題になる。おそらく。

私が見る最良のオプションは、単に二重引用符を使用することです。

R CMD BATCH --no-save --no-restore --slave "--args $1 $2 $3" tabulate.r /dev/tty

二重引用符は、スペースの特別な意味を(必要に応じて)抑制し、$変数の展開を(必要に応じて)トリガーできるようにしますが、変数が展開された後(おそらく必要に応じて)それ以上の解析を防ぎます。引数のスペースやその他の面白い文字は、Rスクリプト内で問題を引き起こす可能性がありますが、少なくともこれにより、Rスクリプトが開始される前に問題が発生するのを防ぐことができます。

于 2012-05-17T21:45:01.670 に答える
2

二重引用符を使用します-または私はポイントを逃していますか?

于 2012-05-17T14:32:18.100 に答える
0

代わりに「(二重引用符)」を使用するか、「」を「」で閉じることができます。

#!/bin/bash

if [ "$2" == "PracSci" ];
then
    echo "Running tabulate.science.r"
    R CMD BATCH --no-save --no-restore --slave '--args '$1' '$2' '$3 tabulate.science.r /dev/tty
else
    echo "Running tabulate.r"
    R CMD BATCH --no-save --no-restore --slave '--args '$1' '$2' '$3 tabulate.r /dev/tty
fi

または、引数が必要な場合は、もう一度一重引用符で囲んで、次のように記述します。

#!/bin/bash

if [ "$2" == "PracSci" ];
then
    echo "Running tabulate.science.r"
    R CMD BATCH --no-save --no-restore --slave "'--args $1 $2 $3'" tabulate.science.r /dev/tty
else
    echo "Running tabulate.r"
    R CMD BATCH --no-save --no-restore --slave "'--args $1 $2 $3'" tabulate.r /dev/tty
fi
于 2012-05-17T14:32:24.210 に答える
0

私があなたを正しく理解しているなら、あなた " '--args $1 $2 $3' "は普通の代わりに欲しいです'--args $1 $2 $3'。トップレベルのトークンは二重引用符で囲まれた文字列であるため、変数は展開され、'Rがそれらを使用できるようにトークン内にとどまります。

于 2012-05-17T14:33:48.627 に答える