2

i want to run a shell script remotely via ssh and the ssh shell should end when the script ends. The script itself runs another script whose output is piped to a log file.

Example: I run the script run1.sh:

#!/bin/sh
function logpipe() {
    while read line;do
        echo $line >> $1
    done
}

./bin/run2.sh $JBOSS_HOSTNAME | logpipe $JBOSS_DIST/log/server.log 2>&1 &

run2.sh:

#!/bin/sh
exec "$JAVA" -DJBOSS_PID=_$$_ $JAVA_OPTS \
         -Djava.endorsed.dirs="$JBOSS_ENDORSED_DIRS" \
         -classpath "$JBOSS_CLASSPATH" \
         org.jboss.Main "$@"

Now the problem is when i run

ssh myhost "bin/run1.sh"

the shell gets "stuck" to the script and i only can get it loose by closing it via Crtl+C. I guess the trick is something between nohup and another piping trick but i just couldn't get to it by now.

  • Maybe i asked in the wrong direction. The reason i put the logpipe function to run1.sh which leaves me with this unending shell is, that the log will be rotated nightly by jboss, where the file is simply renamed. When i log directly like Guss said, the process will still log into the renamed file and not the new one and the log entries aren't chronological anymore. That's why i use this function. Without the function the script leaves the shell as wished, but has the log entries in the wrong file after one day. But i still want to log, what is going to stdout by the process runned in run2.sh. –  Oct 05 '09 at 14:36

7 Answers7

3

You should try to run your script in a "screen".

screen -D -m run1.sh

And then you can catch up the screen with:

screen -r
Oldskool
  • 2,005
  • 1
  • 16
  • 26
Matthieu
  • 106
  • 2
1

The problem is that the script actually ends, but if it leaves another program connected to the terminal (by backgrounding it), then SSH will still keep the connection attached.

using nohup simply lets the shell know that if an external entity is sending hangup signals, they should be ignored, but it does not actually disconnects the program from the console.

I do not know anyway to explicitly disconnect a program from the terminal, but one thing you can do is send a HUP signal to the SSH session that ran the script using the command

kill -HUP $PPID

this will terminate the SSH connection and will leave the program running, but the calling ssh client will get an ugly "connection closed by remote host" error message.

Guss
  • 2,520
  • 5
  • 32
  • 55
  • That suggests that the way to do this is to ssh without a tty; can't remember the option for that. – pjc50 Oct 05 '09 at 14:55
  • SSH normally runs remote commands without a TTY (unless you force it with `-t`). `-T` disables this even when running an interactive shell. So tty or no tty - a running program that is attached to the console prevents graceful shutdown of SSH. – Guss Oct 05 '09 at 15:10
0

It's most probably file descriptors fd>2 that are still open. Check with lsof.

Hans
  • 1
0
ssh myhost "nohup bin/run1.sh"

Should do the trick.

pyhimys
  • 1,267
  • 10
  • 10
  • It doesn't. It still leaves my hanging in the shell, from where i can only escape through Ctrl+C. –  Oct 05 '09 at 14:03
0

I believe you're correct about nohup. In run1.sh, try changing the last line to:

nohup ./bin/run2.sh $JBOSS_HOSTNAME | logpipe $JBOSS_DIST/log/server.log 2>&1 &
Charles Hooper
  • 1,500
  • 9
  • 8
0

In addition to ssh -t mentioned above, which I think will work, you should be sure to close all of your script's inputs & outputs:

ssh myhost "bin/run1.sh > yourlog 2>&1 < /dev/null"

All credit to the OpenSSH FAQ, where I found this years ago.

pra
  • 622
  • 1
  • 5
  • 13
0

What happens if run1.sh sources run2.sh?:

. ./bin/run2.sh $JBOSS_HOSTNAME | logpipe $JBOSS_DIST/log/server.log 2>&1 &
Dennis Williamson
  • 60,515
  • 14
  • 113
  • 148