executing shell command in background from script

BashUnixShell

Bash Problem Overview


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

For example:

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

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

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

Bash Solutions


Solution 1 - Bash

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~

Solution 2 - Bash

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

cmd="google-chrome";
"${cmd}" &>/dev/null & disown;
  • &>/dev/null sets the command’s stdout and stderr to /dev/null instead of inheriting them from the parent process.
  • & makes the shell run the command in the background.
  • disown removes the “current” job, last one stopped or put in the background, from under the shell’s job control.

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

Also, when putting a command inside of a variable, it's more proper to use eval "${cmd}" rather than "${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 output will be shown.

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

Solution 3 - Bash

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 dynamically set 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.

Solution 4 - Bash

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 &

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser248237View Question on Stackoverflow
Solution 1 - BashngoozeffView Answer on Stackoverflow
Solution 2 - BashGreenRaccoon23View Answer on Stackoverflow
Solution 3 - BashjyzView Answer on Stackoverflow
Solution 4 - Bashjokermt235View Answer on Stackoverflow