【问题标题】:Passing arrays as command line arguments with xargs使用 xargs 将数组作为命令行参数传递
【发布时间】:2021-11-14 14:03:29
【问题描述】:

我有以下两个脚本:

#script1.sh:
#!/bin/bash
this_chunk=(1 2 3 4)
printf "%s\n" "${this_chunk[@]}" | ./script2.sh


#script2.sh:
#!/bin/bash
while read -r arr 
do
    echo "--$arr"
done

当我执行script1.sh时,输出如预期:

--1
--2
--3
--4

这表明我能够将数组this_chunk 的元素作为参数传递给script2.sh。但是,如果我将调用script2.sh 的行更改为

printf "%s\n" "${this_chunk[@]}" | xargs ./script2.sh

没有输出。我的问题是,如何使用xargs 传递数组this_chunk,而不是简单的管道?原因是我将不得不处理大型数组和长参数列表,这将成为管道问题。

编辑: 根据答案和 cmets,这是正确的方法:

#script1.sh
#!/bin/bash
this_chunk=(1 2 3 4)
printf "%s\0" "${this_chunk[@]}" | xargs -0 ./script2.sh


#script2.sh
#!/bin/bash
for i in "${@}"; do
    echo $i
done

【问题讨论】:

  • 您似乎误解了xargs 的作用。您的脚本忽略了参数。 hus long argument lists which will be a problem with piping. ?为什么会有问题?您绝对可以通过管道传递更多信息,然后通过命令行参数传递。
  • xargs 按预期工作,但 script2.sh 忽略其参数。尝试在 script2.sh 开头添加echo "Received $# arguments:" "$@" 以查看它们。
  • @Botond:您不会将任何数组管道到另一个进程中。你调用一个命令 (printf) 通过使 shell 将单个数组元素作为参数传递给这个命令;这个命令在标准输出上产生一些文本流,然后这个流被传送到下一个进程。接收进程永远不会看到数组,因为标准输入是无类型的字符流;标准输入法中没有“数组”的概念。

标签: bash xargs


【解决方案1】:

如何使用 xargs 传递数组 this_chunk

注意xargs 默认解释' "\ 序列。要禁用解释,请预处理数据,或者更好地使用带有-d '\n' 选项的GNU xargs。 -d 选项不是 POSIX xargs 的一部分。

printf "%s\n" "${this_chunk[@]}" | xargs -d '\n' ./script2.sh

也就是说,对于 GNU,xargs 更喜欢零终止流,以保留换行符:

printf "%s\0" "${this_chunk[@]}" | xargs -0 ./script2.sh

您的脚本./script2.sh 忽略命令行参数,而您的xargs 在标准输入关闭的情况下生成进程。由于输入已关闭,read -r arr 失败,因此您的脚本不会按预期打印任何内容。 (请注意,在 POSIX xargs 中,当衍生进程尝试从标准输入读取时,结果未指定。)

【讨论】:

  • 谢谢。请问你也解释一下为什么管道工作?通过管道传递不等于通过参数传递?
  • 我猜管道引导输入,而不是参数。
  • why the piping worked? 因为您的脚本使用read 从标准输入中读取。 Passing via piping is not equivalent to passing by arguments?是的,绝对不等价,这些是很不一样的东西。
  • @Botond 有关参数和输入之间区别的更多信息,请参阅this questionthis one
猜你喜欢
  • 1970-01-01
  • 2018-02-28
  • 2016-02-07
  • 2012-03-25
  • 2020-10-03
  • 2020-03-18
  • 2013-07-15
  • 1970-01-01
  • 2015-04-11
相关资源
最近更新 更多