Provide a way to source shell-specific startup files for noninteractive commands

Ivan Pozdeev vano at
Thu May 26 21:04:57 AEST 2022

On 23.05.2022 12:52, Jochen Bern wrote:
> 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.

True. It's however not SSH's job to be a kludge due to a lack of debugging facilities in Cron (and a bad one, too, since its environment is 
still a bit different).

>> 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 root
> I 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?

We're talking about a login shell, not an interactive shell here. From what I can see in the sshd(8) manpage, whether a login journal entry 
is created rather depends on whether a terminal is being allocated. For a noninteractive login shell, there's no need to (as a reminder, a 
login shell is a shell run with `-l/--login` or with `-` at the start of argv[0] -- nothing to do with terminals).


>      When a user successfully logs in, sshd does the following:
>            1.   If the login is on a tty, and no command has been specified, prints last login time and /etc/motd (unless prevented in the
>                 configuration file or by ~/.hushlogin; see the FILES section).
>            2.   If the login is on a tty, records login time.
>            3.   Checks /etc/nologin; if it exists, prints contents and quits (unless root).
>            4.   Changes to run with normal user privileges.
>            5.   Sets up basic environment.
>            6.   Reads the file ~/.ssh/environment, if it exists, and users are allowed to change their environment.  See the
>                 PermitUserEnvironment option in sshd_config(5).
>            7.   Changes to user's home directory.
>            8.   If ~/.ssh/rc exists and the sshd_config(5) PermitUserRC option is set, runs it; else if /etc/ssh/sshrc exists, runs it;
>                 otherwise runs xauth(1).  The “rc” files are given the X11 authentication protocol and cookie in standard input.  See
>                 SSHRC, below.
>            9.   Runs user's shell or command.  All commands are run under the user's login shell as specified in the system password data‐
>                 base.

> 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:
>>        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 $-'
>> hBc
> However, 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,
> _______________________________________________
> openssh-unix-dev mailing list
> openssh-unix-dev at


More information about the openssh-unix-dev mailing list