This is the weirdest thing.
In a script, I start an SSH tunnel like so:
ssh -o StrictHostkeyChecking=no -fND 8080 foo@bar
This starts an ssh instance that goes into the background, and script execution continues. Next, I save its PID (for killing it later) by using bash's $! variable. For this to work, I append & to the ssh command even though it already goes into the background by itself (otherwise $! doesn't contain anything). Thus, for example the following script:
#!/bin/bash
ssh -o StrictHostkeyChecking=no -fND 8080 foo@bar &
echo $!
pgrep -f "ssh -o StrictHostkeyChecking=no -fND 8080 foo@bar"
outputs
(some ssh output)
28062
28062
...two times the same PID, as expected. But, now, when I execute this exact sequence of commands from the terminal, the PID output by $! is wrong (in the sense that it is not the PID of the ssh instance). From the terminal:
$ ssh -o StrictHostkeyChecking=no -fND 8080 foo@bar &
[1] 28178
(some ssh output)
$ echo $!
28178
$ pgrep -f "ssh -o StrictHostkeyChecking=no -fND 8080 foo@bar"
28181
It's not always 3 numbers apart, either. I've also observed a difference of 1 or 2. But it is never the same PID, as I would have expected and as is indeed the case when this sequence of commands is run within a script.
Can someone explain why this is happening? I thought it might be due to the initial
sshcall actually forking another process, but then why does it work from within a script?This also made me doubt whether using
$!in my script to get thesshPID as described above will indeed always work (though it has so far). Is this indeed reliable? I felt it was "cleaner" than usingpgrep...
$PROMPT_COMMANDset, but only with some bash internal commands, no executables. However, I now unset$PROMPT_COMMANDto be sure and this still happens.-fmakes the command going to background after authentication itself even without&character. The original pid disapears because the command is forked and daemonized at this point.