bash 从脚本在后台执行 shell 命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3683910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:39:58  来源:igfitidea点击:

executing shell command in background from script

bashunixshell

提问by

how can I execute a shell command in the background from within a bash script, if the command is in a string?

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

For example:

例如:

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

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

this does not work -- how can I do this?

这不起作用 - 我该怎么做?

采纳答案by ngoozeff

Leave off the quotes

去掉引号

$cmd &
$othercmd &

eg:

例如:

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~

回答by GreenRaccoon23

Building off of ngoozeff's answer, if you want to make a command run completelyin the background (i.e., if you want to hide its outputand prevent it from being killedwhen you close its Terminal window), you can do this instead:

基于ngoozeff的答案,如果您想让命令完全在后台运行(即,如果您想隐藏其输出并在关闭其终端窗口时防止其被杀死),您可以改为执行以下操作:

cmd="google-chrome";
"${cmd}" &>/dev/null & disown;
  • &>/dev/nullsets the command's stdoutand stderrto /dev/nullinstead of inheriting them from the parent process.
  • &makes the shell run the command in the background.
  • disownremoves the “current” job, last one stopped or put in the background, from under the shell's job control.
  • &>/dev/null将命令的stdout和设置stderr/dev/null而不是从父进程继承它们。
  • &使 shell 在后台运行命令。
  • disown从外壳的作业控制下删除“当前”作业,最后一个停止或放在后台。

In some shells you can also use &!instead of & disown; they both have the same effect. Bash doesn't support &!, though.

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

Also, when putting a command inside of a variable, it's more proper to use eval "${cmd}"rather than "${cmd}":

此外,将命令放入变量时,使用eval "${cmd}"而不是"${cmd}"

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

If you run this command directly in Terminal, it will show the PID of the process which the command starts. But inside of a shell script, no outputwill be shown.

如果直接在 Terminal 中运行此命令,它将显示该命令启动的进程的 PID。但是在 shell script 内部不会显示任何输出

Here's a function for it:

这是它的一个函数:

#!/bin/bash

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

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

Also, see: Running bash commands in the background properly

另请参阅:在后台正确运行 bash 命令

回答by jokermt235

For example you have a start program named run.sh to start it working at background do the following command line. ./run.sh &>/dev/null &

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

回答by jyz

This works because the it's a static variable. You could do something much cooler like this:

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

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

This code will create 20 files and dynamicallyset 20 variables. Of course you could use an array, but I'm just showing you the feature :). Note that you can use the variables $filename1, $filename2, $filename3... because they were created with evaluate command. In this case I'm just creating files, but you could use to create dynamically arguments to the commands, and then execute in background.

此代码将创建 20 个文件并动态设置 20 个变量。当然,您可以使用数组,但我只是向您展示该功能:)。请注意,您可以使用变量 $filename1、$filename2、$filename3... 因为它们是使用评估命令创建的。在这种情况下,我只是创建文件,但您可以使用动态创建命令的参数,然后在后台执行。