
foo
バックグラウンドで実行すると()BASHPID
はコマンド置換関数を介して呼び出されるため、vi本体内では使用できません。foo
bashpid_of_foo
bar_1
bar_n
$BASHPID
bash
function foo() {
local bashpid_of_foo=$BASHPID
local output
# desired to be shared by all Command Substitutions
# in the body of this function.
local log=/path/to/log.$BASHPID
... >> $log
output=$(bar_1 ...)
...
output=$(bar_n ...)
}
function bar_1() {
# log only specific (and NOT all) messages
# to the shared log file of the invoking thread.
... >> /path/to/log.$BASHPID
}
foo &
foo &
質問:bashpid_of_foo
一時的な環境変数や外部ディスクファイルを介して渡さずに上記の制限を解決するエレガントな方法はありますか?
渡すエレガントbar_*
私の言葉は、bashが提供する機能にのみ依存して、関数のインタフェースと本文をきれいに保つことができるということです。 (たとえば、関数BASHPID
ですbash
。)
BASHPID
このような値をオーバーライドしようとすると
out_1=$(BASHPID=$BASHPID bar_1 ...)
BASHPID
...読み取り専用変数について(正確に)文句を言います。
編集する:(1)上記の定義を追加しましたbar_1
。 (2)foo
バックグラウンドで2番目の通貨を追加しました。foo
共通ファイルに書き込むと内容が壊れる可能性があるため、各呼び出しごとに独自のログファイルを保持する必要があります。
メモ:ランタイムコンテキストでどのログが発生しても、特定のログファイルfoo
に移動したいと思います。foo
/path/to/log.$BASHPID
いいえそのログファイルの名前を渡すことも、バックグラウンドで複数のインスタンスを実行することもできますfoo
。foo
答え1
#!/bin/bash
bar () {
# bashpid is set in our environment from the calling function
printf 'bar BASHPID = %d, bar bashpid = %d\n' "$BASHPID" "$bashpid"
# in your case, you would have...
local logfile="/some/path/to/log.$bashpid"
# etc.
}
foo () {
local bashpid="$BASHPID"
local message
local logfile="/some/path/to/log.$BASHPID"
message=$( bashpid="$bashpid" bar ); printf 'Message from bar: %s\n' "$message"
message=$( bashpid="$bashpid" bar ); printf 'Message from bar: %s\n' "$message"
message=$( bashpid="$bashpid" bar ); printf 'Message from bar: %s\n' "$message"
message=$( bashpid="$bashpid" bar ); printf 'Message from bar: %s\n' "$message"
}
foo &
foo &
foo &
wait
例を実行してください:
$ bash script.sh
Message from bar: bar BASHPID = 71979, bar bashpid = 18461
Message from bar: bar BASHPID = 7420, bar bashpid = 71036
Message from bar: bar BASHPID = 6109, bar bashpid = 18461
Message from bar: bar BASHPID = 27868, bar bashpid = 71036
Message from bar: bar BASHPID = 44547, bar bashpid = 60086
Message from bar: bar BASHPID = 69310, bar bashpid = 71036
Message from bar: bar BASHPID = 37649, bar bashpid = 60086
Message from bar: bar BASHPID = 15999, bar bashpid = 71036
Message from bar: bar BASHPID = 81520, bar bashpid = 18461
Message from bar: bar BASHPID = 92568, bar bashpid = 60086
Message from bar: bar BASHPID = 72438, bar bashpid = 18461
Message from bar: bar BASHPID = 15094, bar bashpid = 60086
foo
スクリプトの主要部分の各呼び出しに対してbar
4回の呼び出しが行われ、4行の出力が生成されます。ご覧のとおり、bashpid
それぞれ単一のfoo
通貨からの固有番号は3つだけです。
from toを渡すもう一つの方法は$bashpid
明らかにコマンドライン引数として渡してinなどを使って受け取ることですが、そうしたくないと言われました。foo
bar
local bashpid="$1"
bar
答え2
メモ: 一般的な質問に関しては、$BASHPID
これは読み取り専用なので操作できません。これは意図的に設計されています。
私の一般的なアドバイスは、このようなBashスクリプトがある程度複雑になったら、Python、Rubyなどに移動する必要があるということです。
あなたの模範
私はあなたの問題が何であるかを理解していないようです。これは私にとって効果的でした。
$ cat subby.bash
#!/bin/bash
function foo() {
local bashpid_of_foo=$BASHPID
local output=blipblop
echo "foo: $bashpid_of_foo"
echo "foo: $output"
out_1=$(echo $bashpid_of_foo)
out_n=$(echo $output)
echo "out_1: $out_1"
echo "out_n: $out_n"
}
foo &
$ ./subby.bash
foo: 4900
foo: blipblop
out_1: 4900
out_n: blipblop
輸出を増やす
bar_1
シェルスクリプトを作成してそれを変更した場合:
$ cat bar_1
#!/bin/bash
echo "from bar_1: $bashpid_of_foo"
元のスクリプトを次のように変更します。
#!/bin/bash
function foo() {
export bashpid_of_foo=$BASHPID
local output=blipblop
echo "foo: $bashpid_of_foo"
echo "foo: $output"
out_1=$(echo $bashpid_of_foo)
out_2=$(./bar_1)
out_n=$(echo $output)
echo "out_1: $out_1"
echo "out_2: $out_2"
echo "out_n: $out_n"
}
foo &
$bashpid_of_foo
サブシェルに正しくエクスポートされたことを確認できます。
$ ./subby.bash
foo: 5014
foo: blipblop
out_1: 5014
out_2: from bar_1: 5014
out_n: blipblop
export
aではなくここを使用する必要があります。local
そうしないと、環境変数が子としてエクスポートされないためです。ここで、サブシェルはサブシェルです。
$ help export
...
Marks each NAME for automatic export to the environment of subsequently
executed commands. If VALUE is supplied, assign VALUE before exporting.