Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running command via ssh also runs .bashrc? [closed]

Tags:

bash

ssh

In my reading of the bash manpage, .bashrc should only be executed when the shell is run interactively. The manpage defines interactive as:

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, allowing a shell script or a startup file to test this state.

Yet, executing a command with ssh also causes .bashrc to be run, contrary to what I would expect, given that the command is not run interactively. So, this behavior seems like a bug, but it also seems pervasive on all the versions of Red Hat and bash that I've tried. Can someone explain why this behavior is correct?

One additional point: even though .bashrc is run, $- and $PS are set as if the shell is non-interactive (as I would expect).

$ grep USER /etc/passwd
USER:x:UID:GID:UNAME:/home/USER:/bin/bash

$ cat ~/.bashrc
echo bashrc:$-,$PS1

$ bash -c 'echo $-'
hBc

$ ssh localhost 'echo $-' </dev/null 2>/dev/null
USER@localhost's password:
bashrc:hBc,
hBc

$ ssh localhost 'ps -ef | grep $$' </dev/null 2>/dev/null
USER@localhost's password:
bashrc:hBc,
USER 28296 28295 0 10:04 ? 00:00:00 bash -c ps -ef | grep $$
USER 28297 28296 0 10:04 ? 00:00:00 ps -ef
USER 28298 28296 0 10:04 ? 00:00:00 grep 28296

I am currently working around this by testing [[ $- = *i* ]] in .bashrc, but it seems as if I shouldn't have to do that.

One example server, containing no other files in my home directory than .bashrc (and .ssh) has this configuration:

$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.7 (Tikanga)

$ bash --version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

Versions of bash that I've tried this on: 3.00.15, 3.1.17, 3.2.25, 4.1.2 (the latter on Red Hat 6.3).

like image 868
jrw32982 Avatar asked Oct 22 '22 10:10

jrw32982


1 Answers

From the Bash manual:

Bash attempts to determine when it is being run with its standard input connected to a network connection, as when executed by the remote shell daemon, usually rshd, or the secure shell daemon sshd. If Bash determines it is being run in this fashion, it reads and executes commands from ~/.bashrc, if that file exists and is readable. It will not do this if invoked as sh. The --norc option may be used to inhibit this behavior, and the --rcfile option may be used to force another file to be read, but rshd does not generally invoke the shell with those options or allow them to be specified.

The workaround in the default Debian bashrc skeleton is to put the following at the top of .bashrc:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return
like image 99
Fred Foo Avatar answered Oct 27 '22 23:10

Fred Foo