0

Original version:

How to run sudo sh -c "command" in back ground

In a terminal

sudo sh -c "command" & starts in background but as soon as I press enter, the process exits

[test@localhost app]$ sudo sh -c 'app start' &                        
[3] 31725 

[test@locahost app]$

[3]+  Stopped                 sudo sh -c 'app start'

Rewrite:

I want to run some long-running command in the background, as root.  The “obvious” way to do this is

sudo some long-running command &

For unspecified reasons I also tried

sudo sh -c 'some long-running command' &

Both of these fail the same way: I get a shell prompt, but then, as soon as I hit Enter, I get an error message:

$ sudo sh -c 'some long-running command' &
 [3] 31725

$

[3]+ Stopped sudo sh -c 'some long-running command'
$ 

It’s been pointed out to me that, when I put the sudo command into the background like this, it loses access to the standard input.  Therefore, it cannot read the password, and it is stopped when it tries.

Another approach is to use the -b option to tell sudo to put the long-running command into the background, rather than putting sudo into the background:

sudo -b some long-running command

or

sudo -b sh -c 'some long-running command'

Oh!  I almost forgot to mention!  My requirements include

  • Must be able to redirect the output of the long-running command to a file.
  • Must be able to capture the exit status of the long-running command, presumably writing it to a file.
  • Must be able to get the PID of the background process in some reliable way (without needing to grep through the output of ps).

How can I do this?

2 Answers 2

1
  1. First of all, the process doesn't exit; it stops.  There is a difference.
  2. Secondly, it probably happens immediately; you just don't get notified until after you press Enter.
  3. Third, when you put a command into the background (with &), it puts the standard input into a special state so background processes can't read from the keyboard.  When you put sudo into the background, it can't read the password, and so it gets stopped.
  4. Fix this by telling sudo to put the command into the background (rather than telling your login shell to put sudo into the background):

    sudo -b sh -c 'app start'
    
  5. For a simple command like "app start", there's no obvious need for sh -c.  Try

    sudo -b 'app start'
    

P.S. This question really has nothing to do with sh -c.  You would have the same issue with something like

sudo sleep 42 &
1
  • I just provided that as an example. My goal was to run a program in background and get the process id. The command would be somewhat like this sudo-b sh -c 'app start > out.txt ; echo $? > ret.txt' & , this should ask for the sudo password and return me the process id of the sudo process. Is this possible ?
    – Srikan
    Commented Mar 31, 2015 at 17:11
0

Here are a couple of approaches:

sudo sh -c '(some long-running command > out.txt; echo $? > ret.txt)& echo $!'

and

sudo -b sh -c 'echo $$ > pid.txt; some long-running command > out.txt; echo $? > ret.txt'

A slightly trickier approach:  

sudo sleep 0
sudo sh -c 'echo $$ > pid.txt; some long-running command > out.txt; echo $? > ret.txt' &

where the sudo sleep 0 asks for your password and caches your credentials, so the next sudo command can proceed without asking for your password.

All of these give you the PID of the sh -c process rather than the long-running command process.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .