向 xargs 添加额外的参数

Adding extra argument to xargs

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

printf "%s[=11=]" "${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=
    someArg=
    someSaveDir=someArg"/"suite
    # some preprocess work happens here, but isn't relevant to running
    runSomeScript.sh suite someSaveDir
}

export -f run_test_suite

SUITES=
EXTRA_ARG=

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

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

我遇到的问题是如何将 ${EXTRA_ARG} 传递给 xargs。从我对它的理解来看,xargs 会接受通过管道传输到其中的任何内容,所以我的方式似乎不正确。

关于如何正确传递值有什么建议吗?提前致谢

这是一个猜测:

#!/bin/bash

run_test_suite(){
    suite=""
    someArg=""
    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=""
EXTRA_ARG=""

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

如果你想让子EXTRA_ARG可用shell,你需要export它。您可以使用 export 关键字显式地执行此操作,或者将 var=value 赋值放在与 xargs 本身相同的简单命令中:

#!/bin/bash

run_test_suite(){
    suite=
    someArg=
    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  is comma-separated:
IFS=, read -r -a suite_array <<<""

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

_ 防止从 xargs 传递到 bash 的第一个参数变成 [=19=],因此不包含在 "$@".

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

使用 GNU Parallel 看起来像这样:

#!/bin/bash

run_test_suite(){
    suite=""
    someArg=""
    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=""
parallel -d, -q run_test_suite {} "$EXTRA_ARG" ::: ""

称为:

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