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.

1
  • 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.
    – Sebastian
    Oct 5, 2009 at 14:36

7 Answers 7

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
2
  • 2
    There are two types of users: those that use screen, and those that ought to be. Oct 5, 2009 at 15:13
  • removed dead link
    – Sven
    Aug 1, 2017 at 15:04
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.

2
  • That suggests that the way to do this is to ssh without a tty; can't remember the option for that.
    – pjc50
    Oct 5, 2009 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 5, 2009 at 15:10
0
ssh myhost "nohup bin/run1.sh"

Should do the trick.

1
  • It doesn't. It still leaves my hanging in the shell, from where i can only escape through Ctrl+C.
    – Sebastian
    Oct 5, 2009 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 &
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.

1
  • 1
    You can use -n instead of < /dev/null.
    – Teddy
    Nov 18, 2009 at 17:37
0

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

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

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

You must log in to answer this question.