Troubleshooting “shopt: not found” Errors in Ubuntu .bashrc: Shell Compatibility Issues with rbenv Setup


28 views

When working with Ubuntu systems (particularly older versions like 12.04), you might encounter shell compatibility issues when sourcing your .bashrc file. The errors typically manifest as:

$ . ~/.bashrc
sh: 18: /home/deployer/.bashrc: shopt: not found
sh: 26: /home/deployer/.bashrc: shopt: not found
sh: 28: /etc/bash_completion: [[: not found

The root cause becomes clear when checking your current shell:

$ echo $SHELL
/bin/sh
$ cat /proc/$$/cmdline
sh

Ubuntu systems use dash as the default system shell (/bin/sh), while .bashrc is specifically designed for bash. The shopt command and double bracket syntax ([[ ]]) are bash-specific features not available in dash.

Solution 1: Force bash as the default shell

The most robust solution is to change your default shell to bash:

$ chsh -s /bin/bash
# Then log out and log back in

Solution 2: Modify .bashrc for POSIX compatibility

If you must use sh, modify your .bashrc to be POSIX-compliant:

# Replace shopt commands with POSIX equivalents
# Original:
# shopt -s histappend
# Modified:
set -o history

# Replace [[ ]] with [ ]
# Original:
# if [[ -f /etc/bash_completion ]]
# Modified:
if [ -f /etc/bash_completion ]

Solution 3: Conditional bash-specific features

Make your .bashrc work in both environments:

# Only execute bash-specific code if running in bash
if [ -n "$BASH_VERSION" ]; then
    shopt -s histappend
    shopt -s checkwinsize
    # Other bash-specific settings
fi

For your rbenv setup, ensure it's shell-agnostic:

# Modified rbenv initialization
if [ -d "${RBENV_ROOT}" ]; then
    export PATH="${RBENV_ROOT}/bin:${PATH}"
    if [ -n "$BASH_VERSION" ]; then
        eval "$(rbenv init -)"
    else
        export PATH="${RBENV_ROOT}/shims:${PATH}"
    fi
fi

After making changes, test with:

$ . ~/.bashrc
$ echo $PATH  # Verify rbenv paths exist
$ which ruby  # Should point to rbenv shim

When you encounter the "shopt: not found" error while sourcing your .bashrc file, it's typically because your system is using /bin/sh (which is often a symlink to dash on Ubuntu) instead of bash. Here's how to diagnose and fix this issue.

First, let's verify your current shell environment:

# Check current shell
echo $SHELL

# Verify the shell of current process
cat /proc/$$/cmdline

# List available shells
cat /etc/shells

On Ubuntu systems, /bin/sh is often symlinked to dash (Debian Almquist Shell) for better performance during system boot. However, dash doesn't support many bash-specific features like shopt.

You have two main approaches to resolve this:

# Option 1: Explicitly use bash when sourcing
bash -c "source ~/.bashrc"

# Option 2: Change your default shell to bash
chsh -s /bin/bash

To make your .bashrc work across different shells, you can add protective checks:

# At the top of your .bashrc
if [ -n "$BASH_VERSION" ]; then
    # Bash-specific commands
    shopt -s histappend
    shopt -s checkwinsize
    # Other bash-specific settings
fi

The bash_completion script also needs special handling:

# Replace this in your .bashrc
if [ -n "$BASH_VERSION" ] && [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
fi

For your rbenv setup, consider this more robust approach:

# rbenv initialization
if [ -d "$HOME/.rbenv" ]; then
    export RBENV_ROOT="$HOME/.rbenv"
    export PATH="$RBENV_ROOT/bin:$PATH"
    if command -v rbenv >/dev/null; then
        eval "$(rbenv init -)"
    fi
fi

After making these changes, test your configuration:

# Start a new shell session
exec bash

# Verify no errors when sourcing
source ~/.bashrc

# Check shell options
shopt

For complex setups, you might want to detect the shell type:

case "$(ps -p $$ -o comm=)" in
    bash)
        # Bash-specific commands
        ;;
    zsh)
        # Zsh-specific commands
        ;;
    *)
        # Default behavior
        ;;
esac