On 18/11/2023 15:04, Max Nikulin wrote:
On 17/11/2023 17:17, Ihor Radchenko wrote:

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).

I expect the following couple of lines simulates ssh behavior fairly well (besides maybe macOS with its old GPLv2 bash).

bash -c 'read -t 0.5 -r line; printf "read: %s\n" "$line"'
printf 'printf\n'

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

bash <ssh-script.sh
# no output

I have not expected this difference.
[...]
I am unsure if POSIX specifies exact behavior of shell when commands are read from stdin.

It is a bug in dash that should be fixed in next version. Behavior of bash is correct despite some users may expect "done" printed.

<https://lore.kernel.org/dash/20221213221732.6mvv22u7ktdoz...@tarta.nabijaczleweli.xyz/t/>
наб <nabijaczlew...@nabijaczleweli.xyz> to d...@vger.kernel.org
[PATCH] input: preadfd: read standard input byte-wise
Tue, 13 Dec 2022 23:17:32 +0100

<https://bugs.debian.org/862907>
"dash: Incorrectly slurps script from stdin (POSIX compliance issue)"

And curiously ssh command was involved as well
<https://michael-prokop.at/blog/2017/05/18/debugging-a-mystery-ssh-causing-strange-exit-codes/>
"Debugging a mystery: ssh causing strange exit codes?"

A citation from POSIX (XCU):

<https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html#tag_20_117_06>
STDIN in /sh - shell, the standard command language interpreter/
When the shell is using standard input and it invokes a command that
also uses standard input, the shell shall ensure that the standard
input file pointer points directly after the command it has read when
the command begins execution. It shall not read ahead in such a manner
that any characters intended to be read by the invoked command are
consumed by the shell (whether interpreted by the shell or not) or
that characters that are not read by the invoked command are not seen
by the shell. When the command expecting to read standard input is
started asynchronously by an interactive shell, it is unspecified
whether characters are read by the command or interpreted by the
shell.

I do not think any script should rely on this behavior, it is better to explicitly use "here documents"

cat <<EOF
$PATH
EOF

or to prevent various kinds of expansion

cat <<"EOF"
$PATH
EOF

Just a reminder: reading from stdin in shell scripts may interfere with various commands

<https://mywiki.wooledge.org/BashFAQ/089>
"I'm reading a file line by line and running ssh or ffmpeg, only the first line gets processed!"

So either "ssh -n" or "ssh </dev/null" should be used to avoid the pitfall.

I agree with Ihor that ob-shell should not feed scripts to shell stdin (maybe besides the case when it is explicitly requested by the user through some header arguments).

It seems, shell sessions
<https://debbugs.gnu.org/cgi/bugreport.cgi?bug=67259>
is a different case unrelated to script files.


Reply via email to