如何将定义的函数与 xargs 一起使用

如何将定义的函数与 xargs 一起使用

这是我的代码

#!/bin/bash

showword() {
  echo $1
}

echo This is a sample message | xargs -d' ' -t -n1 -P2 showword

所以我有一个函数showword,它会回显您作为参数传递给该函数的任何字符串。

然后我xargs尝试调用该函数并一次向该函数传递一个单词,并并行运行该函数的 2 个副本。不起作用的是xargs无法识别该功能。我怎样才能实现我想要做的事情,如何使 xargs 与该函数一起工作showword

答案1

尝试导出该函数,然后在子 shell 中调用它:

showword() {
  echo $1
}

export -f showword
echo This is a sample message | xargs -d' ' -t -n1 -P2 bash -c 'showword "$@"' _

这会导致xargs执行

bash -c 'showword "$@"' _ This
bash -c 'showword "$@"' _ is
bash -c 'showword "$@"' _ a

传递给命令的参数bash被传递到 bash 环境中,但从 0 开始。因此,在函数内部,

  • $0是“ _”并且 $1是“ This
  • $0是“ _”并且 $1是“ is
  • $0是“ _”并且 $1是“ a
  •       ︙

带有位置参数的 Bash -c

请注意,export -f仅适用于 Bash,并且 ( ) 仅适用于 GNU  。-Pn--max-procs=max-procsxargs

答案2

只需添加一个替代解决方案parallel,我已经开始使用它来代替xargs.任务更容易parallel

#!/bin/bash

showword() {
  echo $1
}
export -f showword

parallel -j2 showword {} ::: This is a sample message
  • -j2确保该函数的 2 个副本并行运行
  • :::此后的任何内容都作为单独的参数传递给parallel,分隔符为空格
  • {}parallel被传递到showword函数中的参数替换

如果您使用 zsh shell,此解决方案将不起作用,因为 zsh 没有任何导出函数的功能。你将需要这样的东西:

#!/usr/bin/zsh

showword() {
  echo $1
}

# add the following to your .zshrc if you want env_parallel in your shell permanently
source /usr/bin/env_parallel.zsh

env_parallel -j2 --env showword showword {} ::: This is a sample message

答案3

让我们有一个接受参数并执行任何操作的函数(我的函数将其打印两次)

$ twice() { echo $1$1 }

$ twice "hello"
hellohello

它不适用于管道,因为它不读取任何输入

$ echo "hello" | twice
<nothing>

我们可以通过读取临时变量的输入来简单地解决这个问题

$ echo "hello" | read s; twice $s
hellohello

或者使用辅助功能

$ call() { read s; $1 $s }

$ echo "hello" | call twice
hellohello

相关内容