On 17/11/2023 17:17, Ihor Radchenko wrote:
I was only able to reproduce your problem with ssh asking a password.
We are discussing the reproduced case.

I see bash vs. dash difference with public key authorization, so no need for password prompts. I have not figured out how to construct an example without ssh since this command *may* read stdin, but does not do it in a same way as e.g. cat(1). Perhaps a small program performing single non-blocking read will allow it. The following behavior observed for a regular shell prompt, Emacs is not involved. Debian 12 bookworm.

cat ssh-script.sh
ssh -p 2222 127.0.0.1 'echo foo>/tmp/foo'
echo done

Read commands from a script file:

dash ssh-script.sh
done

bash ssh-script.sh
done

Read commands from stdin

dash <ssh-script.sh
done

bash <ssh-script.sh
# no output

I have not expected this difference.

dash reads a block from stdin (whole file in this case) and interprets commands.

BASH reads just the ssh command and executes it. SSH reads "echo done" from stdin, so when control is returned to bash, stdin is exhausted and no commands remain to execute by BASH. SSH can not "unread" part of input not consumed by the remote command despite it might be possible in the case of the regular file as stdin.

Actually bash reads the whole script file as well when called as it is shown above, but it calls lseek before executing ssh. To make difference more apparent (e.g. for strace), force creation of pipe(7) for which lseek is not supported

cat ssh-script.sh | strace -o /tmp/bash.strace bash

I am unsure if POSIX specifies exact behavior of shell when commands are read from stdin. I think, the suggested earlier "-n" ssh option (or </dev/null) should be used to make intentions clear: ssh should not read stdin. There is too much room for heuristics: interactive vs. non-interactive shell, a terminal vs. a regular file vs. a pipe as standard input. Be explicit to get reliable behavior.

ssh -n user@host 'command'

or

tar cvf - . | ssh user@host 'tar xvf -'

without "-n" when ssh needs stdin and it is explicitly specified.

I do not think it is an Org or an Emacs bug. It is rather POSIX vs. bash vs. dash issue.


Reply via email to