Another day, another bash and ssh discovery.
I’ve been working on a script which, in its most minimal state, does the following:
ssh -i key user@host 'true'
Assuming the key exists and
true will indeed run on the foreign server, what will the output be when running this script? As it turns out, it depends on how you run it:
$ bash ./test.sh
$ cat ./test.sh | bash
Huh? Why isn’t bash executing the second
In fact, it seems that the script just completely finishes after the
fun() function returns. We see this when running the script in :
cat test.sh | bash -x
+ echo before
+ ssh -i key user@host true
After some time reading the ssh manpage, I noticed:
-n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background.
Right. ssh by default reads from stdin unless disabled. Since the script is being read from stdin line by line, when the
fun() function is actually executed, stdin still contains
echo after, and as such,
ssh reads it or effectively eats it.
There are a few flags you can use to disable the reading of stdin by default, like the aforementioned
-n, but also
-f. Alternatively, you can feed
/dev/null into it, as such:
ssh -i key user@host 'true' < /dev/null