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


6 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