将超时命令分配给脚本中的变量

将超时命令分配给脚本中的变量

我正在尝试设置 nvlc 将运行多长时间。实际上,一个 case 语句中有多个 nvlc 命令,因此我可以选择要播放的流。我已将脚本作为 gitlab 片段发布这里

我想设置一个持续时间,或者如果 $duration 未设置或设置为 0,则不会在“nvlc”之前添加“超时(持续时间)s”(s 代表秒或 m 代表分钟)

read -p "What duration in MINUTES do you want the recording to run for? :  " duration
if [ -z ${duration+x} -o $duration = 0 ]; then t=""; else t='timeout '"$duration"'m'; fi

稍后(第 47 行和其他行)nvlc 的调用方式如下:

"$t" nvlc stream-url

因此,如果持续时间未设置或设置为 0,则“$t”只是空格,但如果为持续时间设置了值,则持续时间变量将在 nvlc 命令中解释,例如: timeout 60m nvlc stream-url

我收到各种错误。使用 t='timeout '"$duration"'s' 时,错误为:第 47 行:超时 5 秒:找不到命令

使用 t='timeout $durations' 时,错误为:第 47 行:超时 $durations:找不到命令

你能指出我哪里错了吗?

答案1

这里有几个问题。第一个是你$t用双引号扩展:

"$t" nvlc stream-url

双引号变量引用几乎总是一个好主意,因为它可以防止意外的分词和/或通配符扩展,但在这种情况下需要分词。如果t设置为timeout 5s,则双引号使 shell 将整个字符串视为命令名称,而不是将其拆分为timeout(命令名称)和5s(它的参数)。另外,如果t设置为空字符串,它不仅会从命令中消失,它实际上会尝试将空字符串作为命令名称运行!要解决这个问题,只需删除双引号:

$t nvlc stream-url

(如果命令更复杂,您可能需要使用数组而不是普通变量;请参阅BashFAQ #50:我试图将命令放入变量中,但复杂的情况总是失败!

第二个问题是条件表达式[ -z ${duration+x} -o $duration = 0 ]。由于引用了duration不是此处用双引号引起来,他们duration如果设置为空字符串,则消失,因此整个内容将扩展为[ -z x -o = 0 ],这是无效的。在这里,你需要对它们进行双引号。并且还可以+x从第一个测试中删除 ,或者将其替换为:+x--+x如果设置了变量(即使它设置为空字符串),则该选项会将其扩展为“x”,但因为它只是read它'二总是展开为“x”。只需删除+x并添加适当的双引号即可:

if [ -z "${duration}" -o "$duration" = 0 ]; then ...

最后,引用t='timeout '"$duration"'m'很奇怪。其实并没有错,只是过于复杂了。单引号非变量部分是多余的,单引号整个内容将阻止变量被扩展。将整个内容用双引号引用会更简单、更清晰:

t="timeout ${duration}m"

(请注意,需要大括号,因此“m”(或某些版本中的“s”)不会被视为变量名称的一部分。)

相关内容