这就是我想要实现的目标。
#!/bin/bash
function startBasics()
{
gnome-terminal -e "sth" &
gnome-terminal --tab -e "sth_else" &
}
function doOneThing()
{
gnome-terminal --working-directory=/myDir1/build/ -e './myExecutable1' &
}
function doAnotherThing()
{
gnome-terminal --working-directory=/myDir2/build/ -e './myExecutable2' &
}
$(startBasics)
$(doOneThing)
$(doAnotherThing)
然而,startBasics
完成后,其他函数根本不执行。所以我把它们全部放在里面的同一个地方startBasics
并再次尝试,这似乎工作正常。
那么为什么上面的代码不起作用呢?编写单独函数的正确方法是什么?
答案1
你的:
$(startBasics)
没有意义,是你的问题的原因。这就是命令替换。扩展为(删除尾随换行符并受 split+glob 约束,因为您没有引用它)$(cmd)
的输出。cmd
您要求 shell 根据 的输出组成一个命令startBasics
。
这意味着 shell 需要读取startBasics
直到文件末尾的输出来扩展它。这里的扩展将被视为执行命令,这没有什么意义。
为了实现命令替换,shell 首先startBasics
将其 stdout 重定向到管道,然后从管道的另一端读取。所有gnome-terminal
进程都将继承该标准输出。
当所有向写入端打开的文件描述符(在所有进程中)都已关闭时,shell 才会在管道的另一端看到 eof。这可能只有在所有gnome-terminals
启动的都startBasics
终止时才会发生。
在这里,您想要:
#!/bin/sh -
startBasics() {
gnome-terminal -e "sth" &
gnome-terminal --tab -e "sth_else" &
}
doOneThing() {
gnome-terminal --working-directory=/myDir1/build/ -e './myExecutable1' &
}
doAnoterThing() {
gnome-terminal --working-directory=/myDir2/build/ -e './myExecutable2' &
}
startBasics
doOneThing
doAnoterThing
wait # if you'd rather wait for all those processes to finish
# before exiting.
答案2
您&
在后台启动该命令。于是投诉
startBasics 完成后,其他函数根本不执行。
可能是由于这些其他程序正在运行的现象并完成完成之前startBasics
。
此外,没有必要将命令封装在$( ... )
.只需调用该函数即可作为命令将工作:
startBasics
doOneThing
doAnoterThing
但不知怎的,我怀疑你想做的是运行这些命令之内一个终端,一个接一个。在这种情况下,您会执行以下操作:
gnome-terminal --working-directory=/myDir2/build/ -x /bin/sh -c 'sthe; sthelse; ./myExecutable1; ./myExecutable2'