创建字符串时将执行字符串中的Bash命令,而不是稍后使用时


10

我对shell脚本比较陌生,但是几乎完成了一个使用lftp程序的脚本。我遇到问题的脚本部分是当我创建一长串命令(以分隔;)时。

for var in something
do
    ...
    commands_to_run+="echo Result is `tail -n 1 $somefile`;"
done

我注意到的是,tail包裹在反引号中的程序在for循环迭代时正在运行,但是稍后在脚本中调用命令字符串时却不在运行。

不幸的是,$ somefile的内容目前还无法检查。如何在需要时(而不是在创建字符串时)执行命令?

Answers:


8

这个有点棘手。Hauke提供的信息是正确的,只是将其解析为您的用例即可。

最简单的方法是$()在转义时使用语法$,以使变量定义不执行定义时的括起来的命令$()。需要注意的是,最终结果必须eval在实际执行时由shell 重新评估(通过),以使嵌套命令得以执行。

看一个例子要容易得多,因此请看一下这个例子,它应该使您走上正确的道路:

for((i=0;i<10;i++)); do 
  date +%s.%N  # Print a timestamp (in format seconds.nanoseconds)
  test="echo \$(date +%s.%N)" # Save a command to do the same
  sleep 1      # Sleep for a second
  eval "$test" # Evaluate the command saved in variable 'test'
  echo         # Print a new line before the next iteration
done

这是上面示例的示例输出(修剪为一个迭代):

1398832186.133661344
1398832187.139076728

您会注意到,每个循环的第二个时间戳大约在第一个之后。相反,如果您执行相同的测试而没有$test定义中转义并删除eval,则这两个时间戳几乎匹配。

eval在大多数情况下不要养成使用习惯,但这是我不知道避免这种情况的好方法之一。希望这会有所帮助。祝好运!


非常感谢,我确实$(...)按照Hauke的建议尝试使用,但是反斜杠是关键。
Ricky 2014年

很高兴提供了帮助-但是请记住,这里的关键实际上是eval因为您可以通过不转义$和使用单引号(')而不是双引号(")来包围命令来完成相同的操作。
daBeamer 2014年

现在,我已经意识到了,正如Huake的建议一样,一旦我在lftp程序中尝试使用此命令,echo只会打印命令,而实际上不会运行它。可能必须尝试他们的邮件列表以获取更多具体帮助。
Ricky 2014年

您要执行的命令是什么?我给您的印象是您想要echo一个包含内容的字符串,其中包括延迟执行嵌套命令的输出。
daBeamer 2014年

1
@Ricky我必须同意@HaukeLaging的所有观点。原来的代码减去echo不会起作用,因为没有命令to eval,而是一个字符串。如果您有更适合我们的示例,我们可以帮助您。
daBeamer 2014年

6

有几个级别的报价。双引号("...")保护的空白和一些特殊字符(~&|;,...),但并不妨碍参数扩展和命令替换。

您需要'在“危险”字符前面加上单引号()或反斜杠。

一般而言:您应该考虑使用$(tail ...)而不是反引号。反引号是较旧的标准,但是我们所说的太旧了,$()不会对大多数人造成问题。新版本更易于阅读并且可以嵌套。更不用说sx上的格式问题了...


感谢您的快速回复,豪克。不幸的是,用建议的反引号替换$(...)仍然会产生相同的结果-当定义了我的字符串时,shell会执行该结果。
Ricky

@Ricky那不是替代建议。您应该使用,$()但是仍然需要单引号。
Hauke Laging

因此,这些字符的任何组合都无法实现我的追求吗?
2014年

@Ricky关于“您需要单引号”有什么很难理解的?您显然甚至没有尝试。
Hauke Laging

实际上,我确实做到了,但是当我使用单引号时,echo只会将该行上的所有内容打印为普通字符串。可能提供示例有何困难?
Ricky 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.