I have an init script that does something like this in the start() function:

runuser -s /bin/bash - prog -c "nohup php /foo/bar.php 2>&1 >> /var/log/bar.log &"

When I SSH into the machine and call the init script:

server:~$ sudo /etc/init.d/foo restart

everything is fine—all output goes to bar.log as expected and I can logout.

However, if I call the init script directly from my SSH command:

workstation:~$ ssh server sudo /etc/init.d/foo restart

then the output comes to my local terminal, not the log, and I cannot close the SSH connection without losing all of that output (which is no longer going to the log file). Surely there's a better way to formulate the init script and any suggestions would be appreciated, but what's happening with the redirection in this example?

  • Could you paste your init script? – katriel Nov 30 '09 at 20:40
  • Perhaps your program detects that there is no tty allocated. Do you get the same behavior when running "ssh -t server sudo /etc/init.d/foo restart" ? – Kyriakos Nov 30 '09 at 21:50
  • Drew you might want to re-title your question. It seems to be more complicated than how to force the output but rather why doesn't ssh output redirection work as expected. – shank Nov 30 '09 at 22:29
  • Is /foo/bar your program? – shank Nov 30 '09 at 22:34

try this:

runuser -s /bin/bash - prog -c "nohup php /foo/bar.php >> /var/log/bar.log 2>&1 &"

it does matter when you do the redirect.

In your example you redirect stderr to stdout and then stdout to /var/log/bar.log. But that does not mean stderr is also redirected to /var/log/bar.log

The shell interprets your commands from left to right, so if you want to redirect both streams to the file you firstly need to redirect stdout to /var/log/bar.log and afterwards redirect stderr to the loaction of stdout, which is /var/log/bar.log.

Hard to explain in a foreign language. Sorry :)


I keep hacking away at this answer...

Using SSH to remotely start a process partially answers this set of questions.

Since ssh connects stdin/stdout/stderr to the local terminal, your redirection doesn't really take hold when started via the ssh invocation line.

And since the controlling tty is owned by ssh if it goes away, then so does the tty and so does any program started via the ssh invocation line. In this case, /etc/init.d/foo probably isn't started via the /etc/init.d/functions daemon(), nor does the actual program call the daemon() C function, which in both cases detaches the program from the controlling tty allowing the ssh to cleanly exit without killing the target program. And in the process allows the redirection to take over.

Not a good explanation I know. Hopefully someone else can take the above and formulate a definitive answer with it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.