I have got this little python3 script test.py
:
import sys
print('test1')
test1 = sys.stdin.read()
print('test2')
test2 = sys.stdin.read()
print(test1)
print(test2)
And I would like to run this script remotely via ssh like this:
ssh srvid 'cd; python3 test.py'
I would expect that program prints test1
, then will wait for input, and then prints test2
and again wait for input.
But the behaviour is slightly different:
ssh srvid 'cd; python3 test.py'
hell
test1
test2
hell
The program first waited for input. I have entered hell
and pressed enter and then ctr+d for eof. Script did not wait for second input, and printed out test1
and test2
.
It seems, that stdin / stdout are somehow blocked.
I tried same example in bash:
#!/bin/bash
echo "Hello world";
read test;
echo "helloworld 2";
read test2;
echo $test;
echo $test2;
When I invoked this script via ssh, everything worked as I am expecting.
Can somebody help me?
Best Answer
This is due to a libc convention for stdio buffering. If stdout is a tty, it is typically line-buffered; fully buffered otherwise.
As others have suggested, passing the -t flag to ssh forces psuedo-tty allocation, and you get line-buffering as a result.
However, you could also explicitly flush stdout to get a similar result, as in:
Another option, would be to run python in totally unbuffered mode with the
-u
flag, as inAdditional workarounds can be found in this stackoverflow question.
I'm pretty sure the script didn't stop at the second input because you sent it an EOF during the first.
FWIW, I would probably write the python this way, unless you need multi-line input. It's a closer comparison to your bash example, IMO.