如何使函数可用于命令“parallel”(GNU)?

如何使函数可用于命令“parallel”(GNU)?

在 Bash 中,让我们考虑一个函数,它除了echo参数后跟“是一个整数”之外什么都不做。

f () { num="${!1}"; echo $num is an integer; }
number=12
f number
# 12 is an integer

我想在一个文件上写入一些使用该函数的命令,然后使用该函数(GNU)f并行运行这些命令。parallel

# Write Commands to the file `Commands.txt`
rm Commands.txt
touch Commands.txt
for i in $(seq 1 5)
do
   echo "number=$i; f number" >> Commands.txt
done

一切source正常

source Commands.txt
1 is an integer
2 is an integer
3 is an integer
4 is an integer
5 is an integer

但是,当我尝试并行运行命令时,它返回f找不到该函数

parallel :::: Commands.txt
/bin/bash: f: command not found
/bin/bash: f: command not found
/bin/bash: f: command not found
/bin/bash: f: command not found
/bin/bash: f: command not found

有没有一种方法可以使我的函数f可用,parallel而不必在文件的每一行定义函数Commands.txt

答案1

您基本上有三个选择:

  1. export -f(这是一个非 POSIX bash 功能)
  2. 在每次调用时执行定义函数的 shell
  3. 将函数移至 shell 脚本并运行

选项 1 可能是最容易演示的,因此我将展示该选项:

$ f() { num=$1; echo "$num is an integer"; }
$ export -f f
$ cat Commands.txt 
number=1; f "$number" 
number=2; f "$number" 
number=3; f "$number" 
number=4; f "$number" 
number=5; f "$number" 
$ parallel :::: Commands.txt
1 is an integer
2 is an integer
3 is an integer
4 is an integer
5 is an integer

请注意,您的人口数量Commands.txt可能有误,您需要f "$number"传递Commands.txt数字,而不是f number传递文字字符串“数字”。生成它的脚本应该这样做echo "number=$i; f \"\$number\""(注意转义符,这对于避免$number在时间上被解释很重要echo,或者"s 终止字符串)。

答案2

Bash 可以通过环境变量导出函数。

export -f f

请注意,这是一个 bash 功能,在 sh 系列的其他 shell 中不可用。

或者,将该函数设为脚本。除了函数定义行之外,脚本和函数具有相同的语法。

#!/bin/bash
num="${!1}"; echo $num is an integer;

如果这样做,您需要导出传递给脚本的变量:其中的行Command.txt需要看起来像

export number=1; f number

或者

number=1 f number

相关内容