Bash脚本和命令定义

4

我有一个类似这样的小bash脚本:

#!/bin/bash
TIME_CMD='/usr/bin/time -f "%E execution time"'

${TIME_CMD} ls

唯一的问题是:不起作用:

/usr/bin/time: cannot run execution: No such file or directory
Command exited with non-zero status 127
"0:00.00

我做错了什么?


该命令在直接运行时有效,即不通过设置变量然后执行它。问题可能出在尝试执行格式字符串中的位上,但我不知道原因。也许可以在超级用户上询问? - moinudin
我认为bash正在使用argv[] = { "/usr/bin/time", "-f", "\"%E", "execution", "time\"" }fork一个进程。但是我不知道如何正确转义语法。 - aschepler
2个回答

5

尝试将它...

#!/bin/bash
TIME_CMD='/usr/bin/time -f "%E execution time"'

eval "$TIME_CMD ls"

这将利用bash在构建命令字符串后重新解析它,以便正确识别引号括起来的参数。

与仅使用 eval $TIME_CMD ls 相比,这是一种重型执行方式。 - Jonathan Leffler
@Jonathan - 说得好。我太习惯于编写从Python调用bash -c的指令,而不是已经在bash中的情况下。 :) - Amber

5
将命令存储在变量中通常不是一个好主意(有关详细信息,请参见BashFAQ#050)。之所以它不能按照您的期望工作,是因为变量值内部的引号被忽略了(除非您通过像eval这样的东西运行它,这可能会导致其他解析异常)。
在您的情况下,我看到三种相当直接的方法来完成它。首先,您可以使用别名而不是变量:
alias TIME_CMD='/usr/bin/time -f "%E execution time"'
TIME_CMD ls

其次,您可以使用一个函数:

TIME_CMD() { /usr/bin/time -f "%E execution time" "$@"; }
TIME_CMD ls

第三,你可以使用数组而不是简单的变量:

TIME_CMD=(/usr/bin/time -f "%E execution time")
"${TIME_CMD[@]}" ls

请注意,对于数组,您需要使用"${array[@]}"这个用法扩展它以正确保留单词间的空格。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接