2009-08-25 18 views
1

以下では、エコー出力は正しいが、pgmがフラグを正しく受信していない。任意の洞察力を感謝します。シェルの問題:複数のフラグを持つ変数をcmdに送信

script file: 
flags="-umc -v -v " 
r="";for d in `ls -d /tmp/passenger*`; do r="$r -x $d"; done 
flags="$flags $r" 
echo $flags 
/usr/sbin/tmpwatch "$flags" -x /tmp/.X11-unix -x /tmp/.XIM-unix \ 
    -x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix 240 /tmp 

のsh -x

sh -x < ./tmpwatch 
+ flags='-umc -v -v ' 
+ r= 
++ ls -d /tmp/passenger.15264 
+ for d in '`ls -d /tmp/passenger*`' 
+ r=' -x /tmp/passenger.15264' 
+ flags='-umc -v -v -x /tmp/passenger.15264' 
+ echo -umc -v -v -x /tmp/passenger.15264 
-umc -v -v -x /tmp/passenger.15264 
+ /usr/sbin/tmpwatch '-umc -v -v -x /tmp/passenger.15264' \ 
    -x /tmp/.X11-unix -x /tmp/.XIM-unix -x /tmp/.font-unix \ 
    -x /tmp/.ICE-unix -x /tmp/.Test-unix 240 /tmp 
/usr/sbin/tmpwatch: invalid option -- 
tmpwatch 2.9.7 - (c) 1997-2006 Red Hat, Inc. All rights reserved. 
This program may be freely redistributed under the terms of the 
GNU General Public License. 

は私が別の方法でコマンドに$フラグを供給する必要があると思う<スクリプトの出力...

ラリー

答えて

2

ドン」変数内の単語をコマンドの別の引数として解釈する場合は、変数の前後に引用符を入れてください。これに代えて

/usr/sbin/tmpwatch "$flags" 

使用この:あなたのコメントを再

/usr/sbin/tmpwatch $flags 

は:スクリプトをcronで実行された場合

それは違いはありません。スクリプトはshで解釈され、cronではありません。

シェルのシングルクォート可変拡張を防止します。さもなければ、変数は二重引用符で囲まれていても、引用符で囲まれていなくても展開されます。それを試してみてください。

$ food=banana 
$ echo $food  # echoes banana 
$ echo "$food" # echoes banana 
$ echo '$food' # echoes $food literally 

引用符の他の効果は、単一または二重のかどうか、文字列ではなく、拡張変数の値にあった空白で区切って複数の単語の単一ワードとしてコマンドに渡されるようにすることです。

+0

ありがとうございました。元のスクリプト(RedHatから)には引用符が付きました(旅客ディレクトリの行が追加される前)。とにかく、私は変数の補間をトリガするために引用符が必要だと思った。今私はよく知っている。 crontabで使用するためにスクリプトが/etc/cron.dailyにあることに違いはありますか?再びありがとう、ラリー –

1

ビルは言った。 bashのmanページから

#!/bin/bash  

# Store file names in an array variable. Same as (`ls -d /tmp/passenger*`), 
# by the way, but the ls is unnecessary. 
files=(/tmp/passenger*) 

# Add each file name to $flags, adding -x in front of each. 
# "/#/-x " means search for an empty string at the beginning of 
# each array item, and replace it with "-x ". Effectively, that 
# just prepends "-x " to each. 
flags="-umc -v -v ${files[*]/#/-x }" 

# No quotes around $flags, so each word is passed as a separate 
# command-line argument to tmpwatch. 
/usr/sbin/tmpwatch $flags -x /tmp/.X11-unix -x /tmp/.XIM-unix \ 
    -x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix 240 /tmp 

:ここでは、bashのを使用している場合は、この方法で、これを書くためにスゴだ

${parameter/pattern/string}

パターンは、パターンを生成するために展開され

パス名展開と同様です。 Parameterが展開され、その値に対するpatternの最長一致がstringに置き換えられます。 pattern/で始まる場合、patternのすべての一致がstringに置き換えられます。通常、最初のマッチだけが置き換えられます。 pattern#で始まる場合は、パラメータの展開された値の先頭に一致する必要があります。パターンが%で始まる場合は、パラメータの展開された値の最後に一致する必要があります。 stringがヌルの場合、patternの一致は削除され、次のパターンは省略される場合があります。パラメータが@または*の場合、置換操作が各位置パラメータに順番に適用され、展開が結果リストになります。 parameter@または*に添字付けされた配列変数の場合、置換操作が配列の各メンバーに順番に適用され、展開が結果リストになります。

+0

ありがとうジョン。 RH提供システムのcronファイルを変更しているので、/ bin/shが使用されていると仮定しています。 –

+0

'sh'はRed Hat上では本当に' bash'ですが、上部に '#!/ bin/bash'を追加して明示的にシェルを選ぶことができます。 –

+0

はいつもですか?彼らはそれのための別の設定を持っていないのですか? – SamB

関連する問題