Saya memiliki fungsi rekursif berikut untuk mengatur variabel lingkungan:
function par_set {
PAR=$1
VAL=$2
if [ "" != "$1" ]
then
export ${PAR}=${VAL}
echo ${PAR}=${VAL}
shift
shift
par_set $*
fi
}
Jika saya memanggilnya dengan sendirinya, keduanya mengatur variabel dan menggema ke stdout:
$ par_set FN WORKS
FN=WORKS
$ echo "FN = "$FN
FN = WORKS
Mengarahkan stdout ke file juga berfungsi:
$ par_set REDIR WORKS > out
cat out
REDIR=WORKS
$ echo "REDIR = "$REDIR
REDIR = WORKS
Tapi, jika saya mem-pipe stdout ke perintah lain, variabel tidak disetel:
$ par_set PIPE FAILS |sed -e's/FAILS/BARFS/'
PIPE=BARFS
$ echo "PIPE = "$PIPE
PIPE =
Mengapa pipa mencegah fungsi mengekspor variabel? Apakah ada cara untuk memperbaikinya tanpa menggunakan temp file atau pipa bernama?
Terpecahkan:
Kode kerja terima kasih kepada Gilles:
par_set $(echo $*|tr '=' ' ') > >(sed -e's/^/ /' >> ${LOG})
Ini memungkinkan skrip dipanggil demikian:
$ . ./script.sh PROCESS_SUB ROCKS PIPELINES=NOGOOD
$ echo $PROCESS_SUB
ROCKS
$ echo $PIPELINES
NOGOOD
$ cat log
7:20140606155622162731431:script.sh:29581:Parse Command Line parameters. Params must be in matched pairs separated by one or more '=' or ' '.
PROCESS_SUB=ROCKS
PIPELINES=NOGOOD
Proyek dihosting di bitbucket https://bitbucket.org/adalby/monitor-bash jika tertarik dengan kode lengkap.
Ini tidak berfungsi karena setiap sisi pipa berjalan dalam subkulit masuk
bash
, dan variabel yang ditetapkan dalam subkulit lokal ke subkulit itu.Memperbarui:
Sepertinya mudah untuk meneruskan variabel dari induk ke shell anak, tetapi sangat sulit untuk melakukannya dengan cara lain. Beberapa solusi dinamai pipa, file temp, menulis ke stdout dan membaca di orangtua, dll.
Beberapa referensi:
http://mywiki.wooledge.org/BashFAQ/024
https://stackoverflow.com/q/15541321/3565972
https://stackoverflow.com/a/15383353/3565972
http://forums.opensuse.org/showthread .php / 458979-How-export-variable-in-subshell-back-out-to-parent
sumber
$$
sama untuk cangkang orangtua dan anak. Anda dapat menggunakan$BASHPID
untuk mendapatkan pid subshell. Ketika sayaecho $$ $BASHPID
berada di dalam,par_set
saya mendapatkan nomor yang berbeda.Anda menunjukkan subkulit - yang bisa diselesaikan dengan beberapa finagling di shell di luar pipa - tetapi bagian yang lebih sulit dari masalah berkaitan dengan konkurensi pipa .
Semua anggota proses dari pipa mulai sekaligus , dan masalahnya mungkin lebih mudah untuk dipahami jika Anda melihatnya seperti ini:
Proses pipa tidak bisa mewarisi nilai variabel karena sudah mati dan berjalan sebelum variabel ditetapkan.
Saya tidak bisa benar-benar mengerti apa fungsi Anda - apa tujuannya
export
belum? Atau bahkan adilvar=val
? Misalnya, inilah saluran yang hampir sama lagi:Dan dengan
export
:Jadi benda Anda bisa bekerja seperti:
Yang akan masuk ke
sed
output file dan mengirimkannya ke fungsi Anda sebagai shell-split"$@"
.Atau, sebagai alternatif:
Jika saya akan menulis fungsi Anda, mungkin akan terlihat seperti ini:
sumber
|pipeline | sh
sh
. Dia sudah menggunakanexport
.