Catching syntax error when trying to write to and call an alias in .bashrc

I’m trying to create an alias for determining whether or not I need to reboot my server.

Here’s what I’m doing:

$ echo "alias rcr='if [ -f /var/run/reboot-required ]; then read -p "Continue? (Y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1 && reboot; else echo No reboot needed; fi'" >> ~/.bashrc
$ source ~/.bashrc
$ rcr

But this throws an error:

bash: conditional binary operator expected
bash: syntax error near `[yY]'

I’ve tried every different combination that I could think of, from escaping characters to prefixing variables. I’m a little new to bash (not Linux in general), so I’m just trying to get the hang of this.

What am I doing wrong here? Here’s what gets added to .bashrc:

alias rcr='if [ -f /var/run/reboot-required ]; then read -p "Continue? (Y/N): " confirm && [[  == [yY] ||  == [yY][eE][sS] ]] || exit 1 && reboot; else echo No reboot needed; fi'
Asked By: Mike K

||

The outer double quotes allow your interactive shell to expand $confirm – presumably to an empty value – so that what you actually write to the .bashrc file is

alias rcr='if [ -f /var/run/reboot-required ]; then read -p "Continue? (Y/N): " confirm && [[  == [yY] ||  == [yY][eE][sS] ]] || exit 1 && reboot; else echo No reboot needed; fi'

You can prevent that by escaping the $ (which is an an additional form of quoting):

$ echo "alias rcr='if [ -f /var/run/reboot-required ]; then read -p "Continue? (Y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1 && reboot; else echo No reboot needed; fi'"
alias rcr='if [ -f /var/run/reboot-required ]; then read -p "Continue? (Y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1 && reboot; else echo No reboot needed; fi'

However IMHO it would be simpler and clearer to use a quoted here document to prevent expansion altogether:

cat >> ~/.bashrc << 'EOF'

alias rcr='
  if [ -f /var/run/reboot-required ]; then 
    read -p "Continue? (Y/N): " confirm
    case $confirm in 
      ([yY]|[yY][eE][sS]) reboot ;; 
    esac
  else
    echo "No reboot needed"
  fi
'
EOF

I also took the liberty of converting your conditionals to a case statement. You could also consider using a shell function instead of an alias here.

Answered By: steeldriver
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.