Ivan Pozdeev
2022-May-21 22:52 UTC
Provide a way to source shell-specific startup files for noninteractive commands
(searched through the list archives and elsewhere and didn't find any prior relevant discussions.) I'm one of Pyenv project maintainers. Just now, we've had a critical bug (https://github.com/pyenv/pyenv/issues/2367) that was happening with some shell setups under SSH with Bash compiled with SSH_SOURCE_BASHRC which is enabled in some Linux distributions (notably, Debian-based). (Basically, a recently-added nested `bash -c` call was misbehaving, only under those specific circumstances.) Now, the behavior of that compilation option is rather questionable and I'm not defending it. However, the distro maintainers' decision to enable it looks like a workaround for the fact that sshd does not provide a way to run the standard shell startup files when running noninteractive commands. This makes `ssh user at host <command>` rather useless because the <command> would run in an incomplete -- and most importantly, different -- environment than a usual shell command, leading to all sorts of surprising breakage and counterintuitive behavior. Sshd does provide `~/.ssh/rc` as a replacement -- but it's run with `sh` and separately from the main shell -- which disallows using shell-specific functionality like installing shell functions. (That is important. E.g. Pyenv requires a shell function installed to use some subcommands.) Having to prepend every <command> with `source ~/.bash_profile;` (that some suggest at e.g. StackOverflow) is horrible UX. In this light, SSH_SOURCE_BASHRC does begin to look like a lesser evil... I see two ways to fix this underlying problem and hopefully eliminate the need for workarounds like that. 1) Run noninteractive shells as login shells just like interactive ones (e.g. `bash -lc` instead of `bash -c`). This seems to be the most logical and straightforward way. In fact, I don't quite see why there had to be a difference in the first place. (My guess is that this was a compatibility measure because at the time, existing shell startup files weren't written with noninteractive login shells in mind, e.g. printing stuff like motd unconditionally.) 2) In addition to `~/.ssh/rc`, source `~/.ssh/<shell>rc`, and do that in the main shell. This would allow distro maintainers to provide a stock file as part of a shell installation that could call standard startup files or anything else as needed. -- Regards, Ivan
Thorsten Glaser
2022-May-21 23:00 UTC
Provide a way to source shell-specific startup files for noninteractive commands
On Sun, 22 May 2022, Ivan Pozdeev wrote:> 2) In addition to `~/.ssh/rc`, source `~/.ssh/<shell>rc`, and do that in theAs shell maintainer, I?d be very cross if this happened. The shell manpages clearly document in which circumstances their various startup files are sourced. If you need to have them sourced, fulfill the respective requirements; usually, this means use the ssh(1) -t option. bye, //mirabilos -- 15:41?<Lo-lan-do:#fusionforge> Somebody write a testsuite for helloworld :-)
Jochen Bern
2022-May-23 09:52 UTC
Provide a way to source shell-specific startup files for noninteractive commands
On 22.05.22 00:52, Ivan Pozdeev wrote:> However, the distro maintainers' decision to enable it looks like a > workaround for the fact that sshd does not provide a way to run the > standard shell startup files when running noninteractive commands. This > makes `ssh user at host <command>` rather useless because the <command> > would run in an incomplete -- and most importantly, different -- > environment than a usual shell command, leading to all sorts of > surprising breakage and counterintuitive behavior.And simultaneously makes it a useful simulation of having said command executed by cron (where the shell is a non-interactive one, the environment different, stdin "not a tty", yadda yadda, too) for debugging.> I see two ways to fix this underlying problem and hopefully eliminate > the need for workarounds like that. > > 1) Run noninteractive shells as login shells just like interactive ones > (e.g. `bash -lc` instead of `bash -c`).Let's see, what does this server here do all day in terms of SSH ... ?> # grep Accepted /var/log/secure | awk '{ print $9; }' | sort | uniq -c > 403 accounting > 21813 nagios > 3 rootI wonder what /var/log/wtmp and the output of "last" would look like if all the Nagios checks were to be forced to use an interactive shell? On 22.05.22 01:00, Thorsten Glaser wrote:> usually, this means use the ssh(1) -t option.Hmm, are you sure about that? From (my) bash manpage:> INVOCATION > A login shell is one whose first character of argument zero is > a -, or one started with the --login option. > > An interactive shell is one started without non-option arguments > and without the -c option whose standard input and error are both > connected to terminals (as determined by isatty(3)), or one > started with the -i option. PS1 is set and $- includes i if bash > is interactive[...]> When bash is invoked as an interactive login shell, or as a > non-interactive shell with the --login option, it first [...] > After [...], it looks for ~/.bash_profile, ~/.bash_login, and > ~/.profile, in that order, and reads and executes commands from > the first one that exists and is readable.[...]> When an interactive shell that is not a login shell is started, > bash reads and executes commands from ~/.bashrc, if that file exists.Let's try that ... :> $ ssh SameServer 'echo $-' > hBc > $ ssh -t SameServer 'echo $-' > hBcHowever, note that with bash and forwarded env vars, at least, one could work around SSH not providing a means to manually set --login or -i options for the remote shell:> When bash is started non-interactively, to run a shell script, for > example, it looks for the variable BASH_ENV in the environment, > expands its value if it appears there, and uses the expanded value > as the name of a file to read and execute.Regards, -- Jochen Bern Systemingenieur Binect GmbH -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 3449 bytes Desc: S/MIME Cryptographic Signature URL: <http://lists.mindrot.org/pipermail/openssh-unix-dev/attachments/20220523/ee865f44/attachment-0001.p7s>