在 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
您基本上有三个选择:
export -f
(这是一个非 POSIX bash 功能)- 在每次调用时执行定义函数的 shell
- 将函数移至 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