间接bash命令执行与coproc没有按预期工作



我对linux shell脚本很陌生,有一个问题:

1.)为什么命令

test1="leafpad" && coproc exec "$test1"

在bash中工作(命令行,debian衍生linux上的GNUbash 4.4.12),但命令

test1="coproc" && exec "$test1" leafpad

不是吗?错误消息:bash:exec:corproc:未找到。

coproc leafpad确实按预期工作。

必须如何正确计算此命令才能使其工作?我已经试过了

test1=`coproc` && exec "$test1" leafpad

test1='coproc' && exec "$test1" leafpad

test1="'coproc'" && exec "$test1" leafpad

test1=`coproc` && exec '$test1' leafpad

test1=`coproc` && exec `$test1` leafpad

test1="coproc" && exec $test1 leafpad

test1=`coproc` && exec $test1 leafpad

还有一些变体,但都不起作用。

2.)这只是在命令行上进行的测试。但我更需要的是在剧本中做到这一点:所以我相信需要做一些额外的引用或伪装特殊角色。

背景:我必须执行一个包含许多参数的命令,其中一些参数被变量替换。想象一下yad这样的东西,它的所有可能的参数都在几行中,但让我们创建一个更简单的例子:

my_codeset="437"
my_line="20"
my_filename="somthing.txt"
if [ $value == 0 ]; then my_tabwidth='--tab-width=10'; else my_tabwidth=""; fi   # set tabs or not
leafpad --codeset="$my_codeset" "$my_tabwidth" --jump="$my_line" "$my_filename"

其中给定的变量作为之前的用户交互的函数而变化。

现在,这个完整的命令(原始版本中大约有6行代码)需要以两种变体执行:作为条件分支的函数,一次由协处理器引导,另一次不是。

所以我想要的是:

if [ $something == 1 ]; then copr_this="coproc"; else copr_this=""; fi
exec '$copr_this' <mycommand, with all its quoted arguments>

而不是

if [ something == 0]; then
lengthy command here
else
coproc lengthy command here, exactly repeated.
fi

我已经试着用另一种方式来管理它了,那就是把完整的长命令放在一个变量中,并在一个条件分支中执行:

my_command=`lengthy command with some arguments $arg1 $arg2 ...`
if...
exec "$my_command"
else
coproc exec "$my_command"
fi

其以错误消息"停止;未找到";而且不同的引用方式并不能解决问题,但只会产生不同的错误消息。我没能找到这项任务的正确引用。如何正确阅读此qouting?

当然,我可以重复代码中的6行命令,但我确信这样做会更方便。

如开头所述:只要不涉及协处理,间接命令执行就可以在命令行上执行(也可以在脚本中执行)。我不能让它和粪菌一起工作。

感谢任何帮助和提示。


@Socowi:第一次回答后更新

谢谢你全面而迅速的回答,索科维。你显然是对的,coproc没有发出命令。所以我现在明白了为什么我的尝试失败了。exec命令只是在我的实验过程中添加的。我一开始没有这个,但在没有成功之后,我认为它会有所帮助。这只是一种绝望的行为。my_command=`lengthy command with some arguments $arg1 $arg2 ...`行中的后向引号是一个拼写错误,正如您所指出的,应该有正常的引号,因为我当然打算在if中执行该命令。我可能会按照您指示的方式,在脚本中使用function {...}。但在此期间,我对这个问题进行了实验,得出了一个惊人的解决方案:这让我感到惊讶,因为coproc不包含命令,而leafpad包含二进制命令。因此,应该清楚的是,test1='coproc' && test2='leafpad' && "$test1 $test2"将失败,并返回错误消息bash: coproc leafpad: command not found.,这是真的。但现在:为什么test1='coproc' && test2='leafpad' && /bin/bash -c "$test1 $test2"要做这项工作,启动leafpad,允许以bash并行方式输入更多命令,就像我只输入leafpad &一样?但这一次从变量同时执行内建(或关键字?)和命令,当试图直接在第一个bash实例中输入时被拒绝。bash的第一个实例是真的,第二个实例也是真的,或者我有一个错误的视角?为什么它是这样工作的?-c选项除了执行命令之外还有其他功能吗?

这里的问题不是报价。还有另外两个问题:

execcoproc的顺序以及内置与二进制的比较

CCD_ 25与CCD_
test1="coproc" && exec "$test1" leafpadexec coproc leafpad相同。

顺序不同:coproc execexec coproc。后者不起作用,因为exec用指定的程序替换了当前shell。但是,coproc是一个内置命令。您的系统上没有coproc二进制文件。您只能从bash内部运行它。因此exec失效。

命令替换与字符串

在你的脚本中。。。

my_command=`lengthy command`
if ...; then
exec "$my_command"
else
coproc exec "$my_command"
fi

您没有将lengthy command存储在变量中,但您运行了该命令并将其输出(v=`cmd`v=$(cmd)相同)存储在if之前。然后在if中,您尝试将该命令的输出作为另一个命令执行。

要将命令存储为字符串并在以后执行,可以使用my_command="lengthy command"; $my_command(注意故意缺失的引号)。然而,bash提供了更好的存储命令的方法。使用数组或函数代替字符串。这里我们使用一个函数:

my_command() {
exec lengthy command
}
if ...; then
coproc my_command
else
my_command
fi

coproc exec

话虽如此,我真的很想知道coprocexec的组合。在我看来,coproc exec cmd忽略了exec部分,与coproc cmd相同。如果exec在此正常工作,则当前外壳将被替换,您将丢失COPROC阵列,因此不需要coproc。无论哪种方式,同时使用两者似乎都很奇怪。你真的确定你需要exec吗?如果是这样的话,我很乐意听到原因。

相关内容

  • 没有找到相关文章