2012-04-08 36 views
11

Wewnątrz funkcji skryptu bash, potrzebuję pracować z argumentami wiersza poleceń skryptu, a także z inną listą argumentów. Tak więc próbuję przekazać dwie listy argumentów do funkcji, problem polega na tym, że argumenty z wieloma słowami zostają podzielone.Przekaż argumenty zawierające wiele słów do funkcji bash.

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" 

wywołanie skryptu daje mi

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

Ponieważ istnieją dwa wykazy muszą być przekazywane w całości do funkcji, pytanie brzmi, jak iteracyjne elementów poszanowaniem elementy wielu haseł ujęte w pojedyncze cudzysłowy "cd" i "z t"?

Ograniczenie, które mam (patrz poniżej) korzysta z BASH_ARGV, więc muszę przekazać do funkcji tylko jedną listę. Chciałbym jednak lepiej zrozumieć, co się dzieje i co jest potrzebne, aby powyższe działania zostały wykonane.

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' 

wywołanie skryptu daje mi

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

... co jest jak muszę go (z wyjątkiem tej pierwszej listy jest odwrotna, ale to byłoby tolerowane Chyba)

Odpowiedz

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[@]}" 

Zakładając, że wywołasz swój skrypt z argumentami a b 'c d', wynik to:

a 
b 
c d 
. 
x 
y 
z t 
+0

Widzę ... więc przekazujesz przedmioty indywidualnie do funkcji. Wydaje mi się, że jedynym miejscem, w którym bash dzieli ciąg znaków na elementy z zachowaniem cytatów, jest interpretacja wiersza poleceń. – haelix

+0

Charakter przekazywania elementów tablicy jako '" $ {items [@]} "' (w podwójnych cudzysłowach) skutkuje wysłaniem każdego elementu jako '" $ {items [0]} "" $ {items [1] } "" $ {items [2]} ... 'etc ... jeśli przekazałeś go jako' $ {items [@]} ', otrzymasz podział tekstu z elementami zawierającymi białe spacje. –

1

Odpowiedź Peter.O powyżej działa dobrze, a to jest dodatek do niego, z przykładem.

Potrzebowałem funkcji lub skryptu, który wymagałby argumentów zawierających wiele słów, które następnie byłyby używane do przeszukiwania listy uruchomionych procesów i zabijania tych, które pasowały do ​​jednego z argumentów. Poniższy skrypt to robi. Funkcja ta wymaga tylko jednej pętli for, ponieważ moja potrzeba była tylko powtórzeniem zestawu wszystkich argumentów funkcji. Przetestowany do pracy.

#!/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[@]}" 
Powiązane problemy