rohit vyawahare rohit vyawahare - 1 year ago 58
Bash Question

Escape single quote inside double quote for executing a command in shell scripting

function install_rubygems {
#install rubygems
ruby_cmd=("sudo gpg --keyserver hkp:// --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3"
"bash -c 'curl -sSL|bash -s stable'"
"source /etc/profile.d/"
#"rvm install 1.9.2 --with-zlib-directory=/usr/local/rvm/usr --with-openssl-directory=/usr/local/rvm/usr"
#"rvm --default use 1.9.2"
#"gem install soap4r-ruby1.9 log4r net-ldap json httpclient"
for cmd in "${ruby_cmd[@]}"
if [ "$exit_status" -ne "0" ]; then
echo "Error occured while running: $cmd. Exiting..."

I want to execute commands listed in ruby_cmd array one by one and then check the exit status of each and perform some operation after that. But when I execute the above script in shell it gives the error as below:

-sSL: -c: line 0: unexpected EOF while looking for matching `''
-sSL: -c: line 1: syntax error: unexpected end of file

I am pretty new to shell scripting, could anyone please tell me what is the correct way to write above command?
PS: command is correct and it executes properly if directly run on bash

Answer Source

For a general discussion of the topic, see BashFAQ #50.

There are several approaches available:

Use a function

install_rubygems() {
  sudo gpg --keyserver hkp:// --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 && \
    curl -sSL | bash -s stable && \
    source /etc/profile.d/

install_rubygems || {
  echo "Error occured while running; exiting..." >&2
  exit "$retval"

Use an eval-able array

This is safe only if none of your strings can contain user-input. Otherwise, it opens you to shell injection attacks.

  "sudo gpg --keyserver hkp:// --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3"
  "curl -sSL | bash -s stable"
  "source /etc/profile.d/"
for cmd in "${install_rubygems[@]}"; do
  eval "$cmd" || {
    echo "Error occured while running $cmd; exiting..." >&2
    exit "$retval"

Use multiple single-command arrays

TBD (after breakfast).