echo
Bashの「整数」という引数以外には何もしない関数を考えてみましょう。
f () { num="${!1}"; echo $num is an integer; }
number=12
f number
# 12 is an integer
この関数を使用してファイルにいくつかのコマンドを作成し、f
この関数(GNU)を使用してこれらのコマンドを並列に実行したいと思います。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
デフォルトでは3つのオプションがあります。
export -f
(これはPOSIXではなくbash機能です)- 各呼び出しで関数を定義するシェルを実行します。
- 関数をシェルスクリプトに移動して実行します。
オプション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
母集団が間違っている可能性があるため、リテラル文字列 "number"ではなく数字を渡すCommands.txt
必要があります。これを生成するスクリプトはこれを行う必要があります(時間の経過とともに解釈されるか、文字列を終了するのを避けるために重要なエスケープ文字に注意してください)。f "$number"
Commands.txt
f number
echo "number=$i; f \"\$number\""
$number
echo
"
答え2
Bashは環境変数を介して関数をエクスポートできます。
export -f f
これは bash 機能で、sh ファミリの他のシェルでは使用できません。
または関数をスクリプトとして作成します。スクリプトと関数は、関数定義行を除いて同じ構文を持ちます。
#!/bin/bash
num="${!1}"; echo $num is an integer;
これを行うには、スクリプトに渡された変数をエクスポートする必要があります。その中の行は次Command.txt
のようになります。
export number=1; f number
または
number=1 f number