2012-04-08 11 views
11

Dentro de una función de script bash, necesito trabajar con los argumentos de la línea de comandos del script, y también con otra lista de argumentos. Así que estoy tratando de pasar dos listas de argumentos a una función, el problema es que los argumentos de varias palabras se dividen.Pase argumentos de varias palabras a una función 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" 

llamar al script me da

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

Puesto que hay dos listas que deben pasar en su totalidad a la función, la pregunta es, cómo iterar los elementos respetando al mismo tiempo los elementos de varias palabras encerrado entre comillas simples 'cd' y 'z t'?

La solución que tengo (véase más adelante) hace uso de BASH_ARGV por lo que necesita para pasar sólo una única lista a la función. Sin embargo, me gustaría obtener una mejor comprensión de lo que está sucediendo y de lo que se necesita para que todo lo anterior funcione.

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' 

llamar al script me da

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

... que es la forma en que lo necesite (excepto que se invierte primera lista, pero eso sería tolerable supongo)

Respuesta

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

Suponiendo que llame a su script con argumentos a b 'c d', la salida es:

a 
b 
c d 
. 
x 
y 
z t 
+0

Veo ... por lo que está pasando elementos de forma individual a la función. Me parece que el único lugar donde bash divide una cadena en elementos respetando las comillas es cuando se interpreta una línea de comando. – haelix

+0

La naturaleza de pasar los elementos de la matriz como '" $ {items [@]} "' (entre comillas dobles) tiene el efecto de enviar cada elemento como '" $ {items [0]} "" $ {items [1] } "" $ {items [2]} ... 'etc ... si lo pasaste como' $ {items [@]} 'obtendrías división de palabras con elementos que contenían espacios en blanco. –

1

La respuesta anterior de Peter.O funciona bien, y esto es un addmendum, con un ejemplo.

necesitaba una función o un script que tomar argumentos de varias palabras, que luego se utilizan para buscar en la lista de procesos en ejecución y matar a los que acertaron una de los argumentos. La siguiente secuencia de comandos hace eso. La función kill_processes_that_match_arguments solo necesita un bucle for, porque mi necesidad era solo iterar sobre el conjunto de todos los argumentos de la función. Probado para trabajar.

#!/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[@]}" 
Cuestiones relacionadas