4

At the top of my .bashrc, it contains this command:

# If not running interactively, don't do anything
case $- in
   *i*) ;;
    *) return;;
esac

I never added this to my .bash.rc, because my .bashrc template was created by Ubuntu.

From what I have read, this command is to prevent the sourcing of the .bashrc file on a remote shell (rsh) or secure shell (ssh). If I were to have something like: alias rm='rename' in my .bashrc, the alias above wouldn't work in the remote shell. However, if I didn't have that command, the alias would work. If "rename" was not installed on the remote shell, running rm would throw an error. So the ultimate purpose is preventing unexpected behaviour, by blocking the sourcing of the .bashrc file.

So here is where I am confused. I completely removed this command and see no difference on a remote shell. I sourced my .bashrc before testing and even rebooted my system, but I see no unexpected behaviour (my 2 servers in this case) with ssh.

I tried simple tests like making an echo function in my .bashrc and trying to call it on the server. All I get is command not found: foo.

The only conclusion that I can come to is that because one of my servers has its own .bashrc and the other has a .zshrc, they take precedence over my local .bashrc, so it's never sourced. If that is the case, why do I need the above command at all? Is the above command archaic and no longer serving a purpose in 2022? Or maybe it does serve a purpose, but only for sysadmins who ssh into servers that don't have a .bashrc, .zshrc, or similar file.

TLDR: Do I need this in my .bashrc file If I only ssh into my own servers that have their own .bashrc or .zshrc file already?

1
  • "because one of my servers has its own .bashrc and the other has a .zshrc, they take precedence over my local .bashrc, so it's never sourced" – There is no room for precedence. The local file matters for the local shell, the remote file may matter for respective shell on the remote side. A remote shell has no means to read your local .bashrc. When you say "at the top of my .bashrc" or "removed this command [from .bashrc]", or "do I need this in my .bashrc?", do you mean your local .bashrc? The code in question in the local file matters when you ssh to your local computer. Commented Sep 1, 2022 at 20:07

4 Answers 4

5

An interactive shell is where the shell displays a prompt and you enter a command.

A non-interactive shell is where you launch a script.

Read 6.2 Bash Startup Files in the manual to see what files are sourced when the shell starts.

Typically, you put stuff in

  • ~/.profile or ~/.bash_profile that you want to happen when you log in (set environment variables, start an ssh agent; stuff that affects an interactive shell but also other programs that you might run)
  • ~/.bashrc that you want to set up just for interactive use (aliases, functions; stuff that makes typing commands simpler)

It's the difference between

$ echo "$-"
himBCHs

and running a script

$ cat > myscript.sh
#!/usr/bin/env bash
echo "$-"

$ bash ./myscript.sh
hB

If you need stuff from your ~/.bashrc in a script, you can source ~/.bashrc, but that can get defeated by the case statement in your question. The better option is to tell bash you want it to act like an interactive shell

$ bash -i ./myscript.sh
himBCH
0

man bash says

An interactive shell is one started without non-option 
arguments (unless -s is specified) 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.

The code you just show is a test to check if your shell is interactive or not, in that case it will execute the rest of the .bashrc otherwise it will just ignore the remaining part of the init-shell file.

0

TLDR: Do I need this in my .bashrc file If I only ssh into my own servers that have their own .bashrc or .zshrc file already?

Yes and No.

YES. You will need it to make sure file transferring command like scp would be working fine. Please refer to this bug: https://bugzilla.redhat.com/show_bug.cgi?id=20527

If there is anything echo in .bashrc, the scp would be failed.

NO. In case you may make sure the file transferring working and never run command via noninteractive shell, you dont need that in your .bashrc

0

This is the clearest image that I ever found:

enter image description here

(Sorry I had lost the origin of the image. Please let me know if you find it)


If you use ssh remote to connect to the remote server, it will be a login interactive shell.

If you use ssh remote echo 1 to connect to the remote server, it will run a login non-interactive shell, and use this shell to run echo 1

If you use the trick like running exec /bin/zsh inside the ~/.bash_profile, and use the ssh remote to connect to that server, the zsh will be run as a non-login interactive.

If you use the trick like running exec /bin/zsh inside the ~/.bash_profile, and use the ssh remote echo 1 to connect to that server, the zsh will be run as a non-login non-interactive.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .