Передайте многословные аргументы функции bash

Внутри функции bash script мне нужно работать с аргументами командной строки script, а также с другим списком аргументов. Поэтому я пытаюсь передать два списка аргументов функции, проблема в том, что аргументы многословных разделяются.

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"

вызов script дает мне

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

Так как есть два списка, они должны быть переданы как целое функции, вопрос в том, как итерации элементов при соблюдении многословных элементов, заключенных в одинарные кавычки 'cd' и 'z t'?

Обходной путь, который у меня есть (см. ниже), использует BASH_ARGV, поэтому мне нужно передать только один список функции. Однако я хотел бы получить лучшее представление о том, что происходит, и о том, что необходимо для выполнения вышеуказанной работы.

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'

вызов script дает мне

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

... Вот как мне это нужно (за исключением того, что первый список отменен, но это было бы терпимо, я думаю)

Ответ 1

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

Предполагая, что вы вызываете свой script с помощью args a b 'c d', вывод:

a
b
c d
.
x
y
z t

Ответ 2

Ответ Peter.O выше работает отлично, и это добавочный пример к нему, пример.

Мне нужна была функция или script, которая использовала бы многословные аргументы, которые затем будут использоваться для поиска списка запущенных процессов и уничтожения тех, которые соответствуют одному из аргументов. Следующий script делает это. Для функции kill_processes_that_match_arguments нужен только один цикл for, потому что мне нужно было только перебирать все аргументы функции. Протестировано для работы.

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