2009-08-25 82 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