16

在 bash 脚本函数中,我需要使用脚本的命令行参数以及另一个参数列表。所以我试图将两个参数列表传递给一个函数,问题是多字参数被拆分。

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

    echo .

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

PARAMS="$@"
ITEMS="x y 'z t'"
params "$PARAMS" "$ITEMS"

调用脚本给了我

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

由于有两个列表,它们必须作为一个整体传递给函数,问题是,如何迭代元素,同时尊重用单引号 'c d' 和 'z t' 括起来的多词项?

我拥有的解决方法(见下文)使用 BASH_ARGV,因此我只需将一个列表传递给函数。但是,我想更好地了解正在发生的事情以及完成上述工作需要什么。

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

    echo .

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

params x y 'z t'

调用脚本给了我

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

...这就是我需要的(除了第一个列表被颠倒了,但我猜这是可以容忍的)

4

2 回答 2

11
function params()
{
   arg=("$@")

   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 $# "$@" "${items[@]}"

假设您使用 args 调用脚本a b 'c d',则输出为:

a
b
c d
.
x
y
z t
于 2012-04-08T12:25:40.677 回答
3

Peter.O 上面的答案很好用,这是一个附录,有一个例子。

我需要一个可以接受多字参数的函数或脚本,然后将其用于搜索正在运行的进程列表并杀死与其中一个参数匹配的进程。下面的脚本就是这样做的。该函数kill_processes_that_match_arguments只需要一个for循环,因为我只需要遍历该函数的所有参数集。经测试可以工作。

#!/bin/bash

function kill_processes_that_match_arguments()
{
    arg=("$@")
    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[@]}"
于 2012-11-01T10:42:50.880 回答