Shell script loop over array passed as argument to multi-argument function?

333 views Asked by At

I am trying to do something like this:

function install {
  cmd=$1
  shift
  for pkg in "$@";
  do
   if $cmd $pkg; then
    echo "Installed $pkg"
   else
    echo "Failed to install $pkg"
   fi
  done
}

brews=(git node scala sbt zsh caskroom/cask/brew-cask)
casks=(dropbox google-chrome spotify)

install 'brew install' $brews
install 'brew cask install' $casks

However, this only works for the 1st element of each of the arrays. Why is not picking up rest of the array elements??

1

There are 1 answers

2
John1024 On BEST ANSWER

Revised Question

Replace:

install 'brew install' $brews
install 'brew cask install' $casks

With:

install 'brew install' "${brews[@]}"
install 'brew cask install' "${casks[@]}"

To understand why, observe:

$ brews=(git node scala sbt zsh caskroom/cask/brew-cask)
$ echo $brews
git
$ echo "${brews[@]}"
git node scala sbt zsh caskroom/cask/brew-cask

As you can see, under bash, $brews references just the first element of an array. By contrast, "${brews[@]}" will expand to all members of the array with each member a separate word.

Original Question

Replace:

if $cmd $2; then

With:

if $cmd "$pkg"; then

Similarly replace references to $2 to $pkg in the echo statements.

Aside

While you are at it, just in case any arguments contain spaces, replace:

for pkg in $@;

With

for pkg in "$@";