GNU Parallel 与多个文件的 shellcheck

Posted

技术标签:

【中文标题】GNU Parallel 与多个文件的 shellcheck【英文标题】:GNU Parallel with shellcheck on multiple files 【发布时间】:2018-12-04 18:07:15 【问题描述】:

如何使用 GNU Parallel 对所有带有包装函数的 *.sh 运行 shellcheck?

此尝试具有正确的目标文件,但 Parallel 似乎与 subshel​​l 斗争。

lint:sh() 
  local output
  targets=$(find . -name '*.sh' -exec echo  \;)
  output=$(parallel --no-notice shellcheck ::: "$targets")
  results $? "$output"

【问题讨论】:

我认为您希望 targets 成为一个数组。 targets=($(find ...)) 然后将 ”$targets[@] 传递给 GNU Parallel find ... -exec echo \; 似乎过于冗长 - 尝试省略 -exec 以及之后的所有内容。 当使用数组时(详细不是他当前的问题)mapfile -t targets < <(find . -name '*.sh' -exec echo \;) output=$(parallel --no-notice shellcheck ::: "$targets[@]") 我得到一个非零退出但在子shell 中没有,lint:sh - 结果未被调用 它是在调用目标而不是将它们传递给 shellcheck 我认为函数名中不允许使用冒号,顺便说一句。 【参考方案1】:

使用以下方法:

lint:sh() 
  local output
  output=$(find . -name "*.sh" -print0 | parallel -q0 --no-notice shellcheck)
  ...

【讨论】:

谢谢,但这会同时解决吃掉错误代码和输出的问题。 @Tom,我们的目标是向您展示一种可行的 GNU 并行方法。但是results 是您的自定义“功能”。考虑我对这一行的处理方法output=$(find . -name "*.sh" -print0 | parallel -q0 --no-notice shellcheck) 该行退出 1 并终止包装脚本 - 因此永远不会调用结果。我也不能echo $output 而不是`结果...` 使用std in vs redirect with ::: 似乎不是问题。【参考方案2】:

由于 bash 的不同缺陷,最安全的方法可能是

targets=()
while read -r -d '' file; [[ $file ]]; do
    targets+=("$file");
done < <(find . -name '*.sh' -print0)

也因为targets类型被改为数组

output=$(parallel --no-notice shellcheck ::: "$targets[@]")

【讨论】:

使用 bash 的 globstar **/*.sh 会更容易。 @Socowi,但会带来一个严重的缺点,因为** 会在内存中扩展并且会慢得多。 慢一点,是的(在我的系统上,/**/*.so 是 3.5 倍),但这里的内存参数不计算在内。在这两种情况下,所有文件都存储在一个数组中,该数组存储在内存中。

以上是关于GNU Parallel 与多个文件的 shellcheck的主要内容,如果未能解决你的问题,请参考以下文章

gnu parallel --pipe 产生空输出文件

并行执行shell进程

GNU Parallel使用管道并行执行命令?

GNU Parallel:如何从gnu并行管道接收stdin,就像它来自文件一样?

gnu 并行:结合使用 --pipe 和 args

gnu parallel + sed 编辑 csv 标题和内容