从脚本在后台执行 shell 命令

如果命令是在字符串中,那么如何从 bash 脚本中在后台执行 shell 命令?

例如:

#!/bin/bash
cmd="nohup mycommand";
other_cmd="nohup othercommand";


"$cmd &";
"$othercmd &";

这样不行,我怎么能这样?

166910 次浏览

别引用了

$cmd &
$othercmd &

例如:

nicholas@nick-win7 /tmp
$ cat test
#!/bin/bash


cmd="ls -la"


$cmd &




nicholas@nick-win7 /tmp
$ ./test


nicholas@nick-win7 /tmp
$ total 6
drwxrwxrwt+ 1 nicholas root    0 2010-09-10 20:44 .
drwxr-xr-x+ 1 nicholas root 4096 2010-09-10 14:40 ..
-rwxrwxrwx  1 nicholas None   35 2010-09-10 20:44 test
-rwxr-xr-x  1 nicholas None   41 2010-09-10 20:43 test~

这是因为它是一个静态变量。 你可以做一些更酷的事情,像这样:

filename="filename"
extension="txt"
for i in {1..20}; do
eval "filename${i}=${filename}${i}.${extension}"
touch filename${i}
echo "this rox" > filename${i}
done

此代码将创建20个文件和 动态的设置20个变量。当然您可以使用数组,但是我只是向您展示一个特性:)。请注意,可以使用变量 $filename1、 $filename2、 $filename3... 因为它们是使用 value 命令创建的。在本例中,我只是创建文件,但是您可以使用它来为命令创建动态参数,然后在后台执行。

基于 ngoozeff的回答,如果你想让一个命令在后台运行 彻底的(也就是说,如果你想在关闭终端窗口时运行 隐藏它的输出防止它被杀死) ,你可以这样做:

cmd="google-chrome";
"${cmd}" &>/dev/null & disown;
  • &>/dev/null将命令的 stdoutstderr设置为 /dev/null,而不是从父进程继承它们。
  • &使 shell 在后台运行命令。
  • disown从 shell 的作业控制下移除“当前”作业,最后一个停止或放在后台。

在一些 shell 中,您还可以使用 &!而不是 & disown; 它们具有相同的效果。但是 Bash 不支持 &!

另外,当在变量中放入一个命令时,使用 eval "${cmd}"比使用 "${cmd}"更合适:

cmd="google-chrome";
eval "${cmd}" &>/dev/null & disown;

如果运行此命令 直接到终点站,它将显示命令启动的进程的 PID。但是,在 shell 脚本内部没有输出将显示。

下面是它的一个函数:

#!/bin/bash


# Run a command in the background.
_evalBg() {
eval "$@" &>/dev/null & disown;
}


cmd="google-chrome";
_evalBg "${cmd}";

另见: 正确地在后台运行 bash 命令

例如,您有一个名为 run.sh 的启动程序,可以在后台启动它,请执行以下命令行。 ./run.sh & >/dev/null &