将多字参数传递给 bash 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10062420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:58:51  来源:igfitidea点击:

Pass multi-word arguments to a bash function

bashparameterswordsplit

提问by haelix

Inside a bash script function, I need to work with the command-line arguments of the script, and also with another list of arguments. So I'm trying to pass two argument lists to a function, the problem is that multi-word arguments get split.

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

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

    echo .

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

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

calling the script gives me

调用脚本给了我

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

Since there are two lists they must be passed as a whole to the function, the question is, how to iterate the elements while respecting multi-word items enclosed in single quotes 'c d' and 'z t'?

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

The workaround that I have (see below) makes use of BASH_ARGV so I need to pass just a single list to the function. However I would like to get a better understanding of what's going on and what's needed to make the above work.

我的解决方法(见下文)使用了 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'

calling the script gives me

调用脚本给了我

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

... Which is how I need it (except that first list is reversed, but that would be tolerable I guess)

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

采纳答案by Peter.O

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

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

   echo .

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

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

Assuming you call your script with args a b 'c d', the output is:

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

a
b
c d
.
x
y
z t

回答by Teemu Leisti

Peter.O's answer above works fine, and this is an addendum to it, with an example.

上面 Peter.O 的回答工作正常,这是它的一个附录,有一个例子。

I needed a function or script that would take multi-word arguments, that would then be used to search the list of running processes and kill those that matched one of the arguments. The following script does that. The function kill_processes_that_match_argumentsonly needs one forloop, because my need was only to iterate over the set of all arguments to the function. Tested to work.

我需要一个接受多字参数的函数或脚本,然后将其用于搜索正在运行的进程列表并杀死与其中一个参数匹配的进程。下面的脚本就是这样做的。该函数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  }' )
        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[@]}"