为xargs添加额外的参数

时间:2018-03-07 23:53:42

标签: shell xargs

我正试图启动多个流程来完成一些测试套件。在我的bash脚本中,我有以下

printf "%s\0" "${SUITE_ARRAY[@]}" | xargs -P 2 -0 bash -c 'run_test_suite "$@" ${EXTRA_ARG}'

下面是已定义的脚本,它是基本的。

SUITE_ARRAY将是可能包含1个或更多套件的套件列表,{Suite 1,Suite 2,...,Suite n} EXTRA_ARG将类似于在另一个脚本中存储值的特定名称

#!/bin/bash

run_test_suite(){
    suite=$1
    someArg=$2
    someSaveDir=someArg"/"suite
    # some preprocess work happens here, but isn't relevant to running
    runSomeScript.sh suite someSaveDir
}

export -f run_test_suite

SUITES=$1
EXTRA_ARG=$2

IFS=','
SUITECOUNT=0
for csuite in ${SUITES}; do
    SUITE_ARRAY[$SUITECOUNT]=$csuite
    SUITECOUNT=$(($SUITECOUNT+1))
done
unset IFS

printf "%s\0" "${SUITE_ARRAY[@]}" | xargs -P 2 -0 bash -c 'run_test_suite "$@" ${EXTRA_ARG}'

我遇到的问题是如何将${EXTRA_ARG}传递给xargs。从我如何理解它,xargs将采取任何管道输入它,所以我拥有它的方式似乎不正确。

有关如何正确传递值的任何建议?提前致谢

3 个答案:

答案 0 :(得分:1)

如果您希望子shell可以使用EXTRA_ARG,则需要export它。您可以使用export关键字明确地执行此操作,也可以将var=value赋值放在与xargs本身相同的简单命令中:

#!/bin/bash

run_test_suite(){
    suite=$1
    someArg=$2
    someSaveDir=someArg"/"suite
    # some preprocess work happens here, but isn't relevant to running
    runSomeScript.sh suite someSaveDir
}
export -f run_test_suite

# assuming that the "array" in $1 is comma-separated:
IFS=, read -r -a suite_array <<<"$1"

# see the EXTRA_ARG="$2" just before xargs on the same line; this exports the variable
printf "%s\0" "${suite_array[@]}" | \
  EXTRA_ARG="$2" xargs -P 2 -0 bash -c 'run_test_suite "$@" "${EXTRA_ARG}"' _

_阻止从xargs传递到bash的第一个参数变为$0,因此不会包含在"$@"中。

另请注意,我通过在逗号上拆分"${suite_array[@]}"来更改$1。这个或类似的东西(例如,您可以使用IFS=$'\n'来分隔新行),因为$1 不能包含文字数组;每个shell命令行参数只是一个字符串。

答案 1 :(得分:0)

这是一个猜测:

#!/bin/bash

run_test_suite(){
    suite="$1"
    someArg="$2"
    someSaveDir="${someArg}/${suite}"
    # some preprocess work happens here, but isn't relevant to running
    runSomeScript.sh "${suite}" "${someSaveDir}"
}

export -f run_test_suite

SUITE_ARRAY="$1"
EXTRA_ARG="$2"

printf "%s\0" "${SUITE_ARRAY[@]}" | 
xargs -n 1 -I '{}' -P 2 -0 bash -c 'run_test_suite {} '"${EXTRA_ARG}"

答案 2 :(得分:0)

使用GNU Parallel看起来像这样:

#!/bin/bash

run_test_suite(){
    suite="$1"
    someArg="$2"
    someSaveDir="$someArg"/"$suite"
    # some preprocess work happens here, but isn't relevant to running                        
    echo runSomeScript.sh "$suite" "$someSaveDir"
}
export -f run_test_suite

EXTRA_ARG="$2"
parallel -d, -q run_test_suite {} "$EXTRA_ARG" ::: "$1"

被称为:

mytester 'suite 1,suite  2,suite "three"' 'extra "quoted" args here'

如果你有一个数组的套件:

parallel -q run_test_suite {} "$EXTRA_ARG" ::: "${SUITE_ARRAY[@]}"

额外奖励:作业的任何输出都不会混合,因此您无需处理http://mywiki.wooledge.org/BashPitfalls#Using_output_from_xargs_-P