Ric*_*cky 11 bash shell-script quoting
我对 shell 脚本比较陌生,但几乎完成了一个使用lftp 程序的脚本。我遇到问题的脚本部分是当我创建一长串命令(以 分隔;)时。
for var in something
do
...
commands_to_run+="echo Result is `tail -n 1 $somefile`;"
done
Run Code Online (Sandbox Code Playgroud)
我注意到的是,该tail程序 - 用反引号包裹 - 在 for 循环迭代时正在运行,但在我稍后在脚本中调用命令字符串时不会运行。
不幸的是,$somefile 的内容在这个阶段还没有准备好进行检查。如何让命令在我需要时执行,而不是在我创建字符串时执行?
这个有点棘手。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
Run Code Online (Sandbox Code Playgroud)
以下是上述示例的示例输出(修剪为一次迭代):
1398832186.133661344
1398832187.139076728
Run Code Online (Sandbox Code Playgroud)
您会注意到每个循环的第二个时间戳在第一个之后大约一秒。相反,如果你不逃避执行相同的测试$在test定义和拆卸eval,两个时间戳将几乎一致。
不要养成eval在大多数情况下使用的习惯,但这是我不知道避免它的好方法之一。希望这会有所帮助。祝你好运!
有几个级别的引用。双引号 ( "...") 保护空格和几个特殊字符 ( ~, &, |, ;, ...) 但不阻止参数扩展和命令替换。
您需要'在“危险”字符前使用单引号 ( ) 或反斜杠。
一般来说:您应该考虑使用$(tail ...)而不是反引号。反引号是较旧的标准,但我们谈论的是太旧了,$()不会对大多数人造成问题。新版本更易于阅读并且可以嵌套。更不用说 sx 上的格式问题了...