2009-08-25 65 views
1

在下面的回聲輸出是正確的,但是pgm沒有正確接收標誌。欣賞任何見解。shell問題:向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)具有引號(在添加乘客目錄行之前)。無論如何,我認爲引號需要觸發變量插值。現在我知道更好。腳本位於/etc/cron.daily中以供crontab使用,它有什麼不同嗎?再次感謝,拉里 – 2009-08-25 12:13:03

1

比爾說什麼。這是一個瘋狂,寫這個,順便說一下,如果你正在使用bash:

#!/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的所有匹配項將替換爲字符串。通常只有第一場比賽被取代。如果pattern#開頭,則它必須在參數的擴展值的開頭匹配。如果模式以%開頭,則它必須在參數擴展值的末尾匹配。如果string爲空,則刪除pattern的匹配項,並且可以省略/以下模式。如果參數是@*,則將替換操作依次應用於每個位置參數,並且擴展是結果列表。如果parameter是以@*爲下標的數組變量,則將替換操作依次應用於數組的每個成員,並且擴展是結果列表。

+0

謝謝約翰。我正在修改RH提供的系統cron文件,所以我的假設是/ bin/sh正在被使用。 – 2009-08-25 12:16:23

+0

'sh'確實是Red Hat上的'bash',但是您可以在頂部添加'#!/ bin/bash'來明確地選擇您的shell。 – 2009-08-25 15:57:39

+0

總是?他們沒有替代方案? – SamB 2010-11-23 13:30:00