2012-04-08 8 views
11

Innerhalb einer Bash-Skriptfunktion muss ich mit den Befehlszeilenargumenten des Skripts und auch mit einer anderen Liste von Argumenten arbeiten. Ich versuche also, zwei Argumentlisten an eine Funktion zu übergeben, das Problem besteht darin, dass Mehrwortargumente aufgeteilt werden.Übergeben von Mehrwortargumenten an eine Bash-Funktion

function params() 
{ 
    for PARAM in $1; do 
     echo "$PARAM" 
    done 

    echo . 

    for ITEM in $2; do 
     echo "$ITEM" 
    done 
} 

PARAMS="[email protected]" 
ITEMS="x y 'z t'" 
params "$PARAMS" "$ITEMS" 

Das Skript gibt mir

myscript.sh a b 'c d' 
a 
b 
c 
d 
. 
x 
y 
'z 
t' 

Da es zwei Listen sie als Ganzes an die Funktion übergeben werden muss, ist die Frage, wie die Elemente zu durchlaufen, während Mehrwort-Elemente zu respektieren in den Anführungszeichen "cd" und "z t" eingeschlossen?

Die Problemumgehung, die ich habe (siehe unten) nutzt BASH_ARGV, so dass ich nur eine einzige Liste an die Funktion übergeben muss. Ich würde jedoch gerne ein besseres Verständnis davon bekommen, was vor sich geht und was benötigt wird, um die obige Arbeit zu leisten.

function params() 
{ 
    for PARAM in "${BASH_ARGV[@]}"; do 
     echo "$PARAM" 
    done 

    echo . 

    for ITEM in "[email protected]"; do 
     echo "$ITEM" 
    done 
} 

params x y 'z t' 

Das Skript gibt mir

myscript.sh a b 'c d' 
c d 
b 
a 
. 
x 
y 
z t 

... das ist, wie ich es brauche (außer dass erste Liste umgekehrt wird, aber das wäre erträglich ich denke)

Antwort

7
function params() 
{ 
    arg=("[email protected]") 

    for ((i=1;i<=$1;i++)) ;do 
     echo "${arg[i]}" 
    done 

    echo . 

    for ((;i<=$#-$1+2;i++)) ;do 
     echo "${arg[i]}" 
    done 
} 

items=(w x 'z t') 
params $# "[email protected]" "${items[@]}" 

Angenommen, Sie rufen Ihr Skript mit den Argumenten a b 'c d' auf, lautet die Ausgabe:

a 
b 
c d 
. 
x 
y 
z t 
+0

Ich sehe ... so Sie Elemente einzeln an die Funktion übergeben. Scheint mir, dass die einzige Stelle, wo bash eine Zeichenfolge in Elemente unter Berücksichtigung von Anführungszeichen zerlegt, bei der Interpretation einer Befehlszeile ist. – haelix

+0

Die Art der Übergabe der Array-Elemente als "$ {items [@]}" '(in doppelten Anführungszeichen) bewirkt, dass jedes Element als' $ {items [0]} "" $ {items [1] } "" $ {items [2]} ... etc ... Wenn Sie es als '$ {items [@]}' übergeben, erhalten Sie eine Worttrennung mit Elementen, die Leerzeichen enthalten. –

1

Die obige Antwort von Peter.O funktioniert gut, und das ist eine Ergänzung zu ihr, mit einem Beispiel.

Ich brauchte eine Funktion oder ein Skript, die mehr-Wort-Argumente, die dann verwendet werden würde, um die Liste der laufenden Prozesse suchen und diejenigen, die mit einem der Argumente übereinstimmte. Das folgende Skript macht das. Die Funktion kill_processes_that_match_arguments benötigt nur eine for Schleife, weil ich nur über die Menge aller Argumente für die Funktion iterieren musste. Getestet um zu arbeiten.

#!/bin/bash 

function kill_processes_that_match_arguments() 
{ 
    arg=("[email protected]") 
    unset PIDS_TO_BE_KILLED 

    for ((i=0;i<$#;i++)) 
    do 
     unset MORE_PIDS_TO_KILL 
     MORE_PIDS_TO_KILL=$(ps gaux | grep "${arg[i]}" | grep -v 'grep' | awk '{ print $2 }') 
     if [[ $MORE_PIDS_TO_KILL ]]; then 
      PIDS_TO_BE_KILLED="$MORE_PIDS_TO_KILL $PIDS_TO_BE_KILLED" 
     fi 
    done 

    if [[ $PIDS_TO_BE_KILLED ]]; then 
     kill -SIGKILL $PIDS_TO_BE_KILLED 
     echo 'Killed processes:' $PIDS_TO_BE_KILLED 
    else 
     echo 'No processes were killed.' 
    fi 
} 

KILL_THESE_PROCESSES=('a.single.word.argument' 'a multi-word argument' '/some/other/argument' 'yet another') 
kill_processes_that_match_arguments "${KILL_THESE_PROCESSES[@]}"