Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute an array of string describing shell command

Tags:

bash

I'm struggling to execute a set of command lines stored as strings in an array. My code looks like this :

arr=( "sudo apt-get update" "sudo apt-get install xxx" )
...
arr=( ${arr[@]} "ln -s /path1 /path2" )
etc...

# Then I loop on the array of command 
for (( i = 0 ; i < ${#arr[@]} ; i++ ))
do
     eval ${arr[$i]}
done

When it loops over the array, the array is larger than the number of command stored into it. As if the blank spaces in my strings split the array in more elements A typical ouput is such like

usage: sudo -h | -K | -k | -L | -V

That means only 'sudo' is taken from within the string and I don't understand why!

Thanks

like image 314
renard Avatar asked Oct 14 '11 21:10

renard


People also ask

How do you read a string into an array in shell script?

The option -a with read command stores the word read into an array in bash. In simpler words, the long string is split into several words separated by the delimiter and these words are stored in an array.

How are commands executed in shell?

The basic shell operation is as follows. The shell parses the command line and finds the program to execute. It passes any options and arguments to the program as part of a new process for the command such as ps above. While the process is running ps above the shell waits for the process to complete.

How do I echo an array in shell?

To echo an array, use the format echo ${Array[0]}. Array is your array name, and 0 is the index or the key if you are echoing an associative array. You can also use @ or * symbols instead of an index to print the entire array.


1 Answers

Use ${#arr[@]} to get the number of items in the array (${arr[@]} gives the word count). Using either eval or back-ticks (`) to execute the command works:

[ 15:20 jon@host ~ ]$ cat run_yum_test.sh
#!/bin/bash

declare -a arr=("sudo yum search zsh" "sudo yum list zsh")

for (( i = 0; i < ${#arr[@]} ; i++ )); do
    printf "\n**** Running: ${arr[$i]} *****\n\n"

    # Run each command in array 
    eval "${arr[$i]}"

    ### using back-ticks works also
    #RESULT=`${arr[$i]}`
    ### Check if the command gave any output
    #if [ -n "$RESULT" ]; then
    #    echo "$RESULT"
    #fi
done

[ 15:20 jon@host ~ ]$ ./run_yum_test.sh

**** Running: sudo yum search zsh *****

[sudo] password for jon:
Loaded plugins: presto, refresh-packagekit
=========================================================================== Matched: zsh ===========================================================================
zsh-html.i686 : Zsh shell manual in html format
autojump-zsh.noarch : Autojump for zsh
fatrat-czshare.i686 : FatRat plugin enabling CZShare.com downloads and uploads
gromacs-zsh.noarch : GROMACS zsh support
python-twisted-core-zsh.i686 : Tab completion for Zsh and Twisted Core
zsh.i686 : A powerful interactive shell
environment-modules.i686 : Provides dynamic modification of a user's environment
plowshare.noarch : CLI downloader/uploader for some of the most popular file-sharing websites

**** Running: sudo yum list zsh *****

Loaded plugins: presto, refresh-packagekit
Available Packages
zsh.i686                                                                    4.3.10-6.fc13                                                                    updates

Edit (to answer your comment):

To "extend" the array, put the original array (${arr[@]}) in quotes, like so:

arr=("sudo yum list zsh" "sudo yum search zsh")
arr=("${arr[@]}" "echo 'TEST'")

Here it is in action:

[ 16:06 jon@host ~ ]$ cat run_yum_test.sh
#!/bin/bash

arr=("sudo yum list zsh" "sudo yum search zsh")
arr=("${arr[@]}" "echo 'TEST'")

for (( i = 0; i < ${#arr[@]} ; i++ )); do
    printf "\n**** Running: ${arr[$i]} *****\n\n"
    eval "${arr[$i]}"
done


[ 16:06 jon@host ~ ]$ ./run_yum_test.sh

**** Running: sudo yum list zsh *****
[sudo] password for jon:
Loaded plugins: presto, refresh-packagekit
Available Packages
zsh.i686                                                                    4.3.10-6.fc13                                                                    updates

**** Running: sudo yum search zsh *****

Loaded plugins: presto, refresh-packagekit
=========================================================================== Matched: zsh ===========================================================================
zsh-html.i686 : Zsh shell manual in html format
autojump-zsh.noarch : Autojump for zsh
fatrat-czshare.i686 : FatRat plugin enabling CZShare.com downloads and uploads
gromacs-zsh.noarch : GROMACS zsh support
python-twisted-core-zsh.i686 : Tab completion for Zsh and Twisted Core
zsh.i686 : A powerful interactive shell
environment-modules.i686 : Provides dynamic modification of a user's environment
plowshare.noarch : CLI downloader/uploader for some of the most popular file-sharing websites

**** Running: echo 'TEST' *****

TEST
like image 174
chown Avatar answered Sep 21 '22 12:09

chown