Situation: Need to login to multiple remote servers with some of them having fish shell

Requirement: Default shell is bash. If I login to a server and fish is present, switch to fish shell, otherwise stay on bash.

Tried .bashrc:

# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc

# Source global definitions
if [ -f /etc/bash.bashrc ]; then
        . /etc/bash.bashrc

# Update Path
export PATH=/sbin:/usr/sbin:/usr/local/sbin:$PATH:$HOME/.bin

# Open fish shell if present, otherwise stick to bash
if hash fish 2>/dev/null; then
        # echo "Fish detected, shifting shell"
        fish "$@"; exit

However, scp doesn't seem to be working. When I try to scp a file, verbose output shows it to be stuck here.

debug1: Authentication succeeded (publickey).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending env LC_ADDRESS = en_US.UTF-8
debug1: Sending env LC_IDENTIFICATION = en_US.UTF-8
debug1: Sending env LC_MEASUREMENT = en_US.UTF-8
debug1: Sending env LC_MONETARY = en_US.UTF-8
debug1: Sending env LC_NAME = en_US.UTF-8
debug1: Sending env LC_NUMERIC = en_US.UTF-8
debug1: Sending env LC_PAPER = en_US.UTF-8
debug1: Sending env LC_TELEPHONE = en_US.UTF-8
debug1: Sending env LC_TIME = en_US.UTF-8
debug1: Sending command: scp -v -f test_file

Initially I thought the echo command was causing it to not work, but it doesn't work without it as well.

  • Hmm... .bashrc should not be sourced by Bash in a non-interactive session, right? Are you sourcing it explicitly from .bash_profile? – Kusalananda Apr 24 '17 at 14:03
  • @Kusalananda scp is a special case. – terdon Apr 24 '17 at 14:27
  • @Kusalananda I checked and there is no .bash_profile. The .bashrc is still picked up though, weird. Didn't notice this before. Any idea why this would be happening? – yamatau Apr 24 '17 at 14:29
  • Yamatau, you don't need the fish for the scp, right? If I understand you correctly, you just want to start fish when logging in manually to the remote machine and that's why you added that line to bashrc. However, this has the result of breaking your scp and that's what you want to fix. Is that correct? You don't want/need fish to be run when doing scp, right? – terdon Apr 24 '17 at 14:30
  • @terdon Yes, correct. – yamatau Apr 24 '17 at 14:40

To exit the bashrc file when the shell session that is sourcing it is not interactive, you may do the following at the top (or in a convenient location) of the file:

case "$-" in
    *i*)        ;;
    *)   return ;;

The value in $- is a string of letters denoting the currently set shell options. If the i character is present in the string, then the shell is interactive.

This may be needed since, as terdon pointed out in comments, Bash treats shell sessions that are started by sshd, the SSH daemon, as a special case.

Details: Why does bashrc check whether the current shell is interactive?

Further down in the file, you may check whether the fish shell is available and start that:

if command -v fish 2>/dev/null; then
   exec fish

Be aware that fish may be the game of "Go Fish" on some systems :-)

About the use of command -v: Why not use "which"? What to use then?


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.