6

During the course of my learning about the non-interactive login shell, I have come across 2 ways to remotely execute the commands via SSH. For me, they both look to be the same. But unfortunately, they aren't.

With the command echo "shopt login_shell; echo \$-" | ssh -l poweruser 192.168.1.67, I get the following output.

Pseudo-terminal will not be allocated because stdin is not a terminal.
poweruser@192.168.1.67's password:
login_shell     on 
hBs

But with the command ssh -l poweruser 192.168.1.67 "shopt login_shell; echo \$-", I get a different output.

poweruser@192.168.1.67's password:
login_shell     off
hBc

Could you please tell why the shell is not a login shell in the second case even though it prompts for the password.

JayTheKay
  • 103
Karthik
  • 155
  • As a side note, ssh -t server cmd is a better equivalent to echo cmd|ssh server as without -t, the default for no explicit command (ssh server) is to open a pseudo-terminal whereas the default for with a command (ssh server cmd) is NOT to open one. The -t forces it to open one anyway. – Dessa Simpson Jul 30 '18 at 17:23

2 Answers2

10

man ssh documents that:

If a command is specified, it is executed on the remote host instead of a login shell.

The reason is then that in one case you specified a command, and in the other you didn't, and ssh deliberately (by design) behaves differently in those cases.

In the one where you didn't provide a command, a login shell was launched and it read the piped input and executed it. In the one where you did provide a command, it was launched instead.

Prompting for the password is unrelated. That is authenticating you to the server, before the shell or command is launched.

Michael Homer
  • 76,565
0

This is imprecise, but it may be a useful way to look at it:

  • echo … | ssh … “looks like” an interactive session — ssh is reading shell commands from its standard input after it starts.  Now, of course, ssh can distinguish between its stdin being a pipe or a tty (or a file), but it might not bother to do so.  Treating a pipe differently from a tty might make it harder to use something like expect (man page).

    echo … | ssh … feels like calling somebody on the phone and asking them to do something.  Potentially, you want them to do it immediately (while you’re still on the phone), and so a login shell feels more appropriate.

  • With ssh … command, you’re specifying the command(s) to run before ssh even makes the connection.  You can’t possibly do something conditionally, based on responses you see (except maybe hit Ctrl+C if something goes wrong).  So it can’t be interactive; it’s more like batch processing.

    It feels like sending somebody an email and asking them to do something.  You don’t expect an immediate response, and so a login shell feels less appropriate.

For background, see Why a "login" shell over a "non-login" shell? (where — disclosure — the only answer was written by me) and Difference between Login Shell and Non-Login Shell? — although, after a very quick glance, I don’t see anything there that’s directly relevant to this question.