/ bin / sh sumber dari stdin (dari program lain) bukan file


14

Agak rumit untuk memberi nama ini ...

Pada dasarnya saya memiliki program yang ketika menjalankan cetakan pada STDOUT satu set variabel shell:

$ ./settings
SETTING_ONE="this is setting one"
SETTING_TWO="This is the second setting"
ANOTHER_SETTING="This is another setting".

Saya ingin menjalankan ini dari dalam skrip shell seolah-olah STDOUT sedang dievaluasi dengan source.

Saya ingin melakukan sesuatu seperti ...

source `./settings`

... tapi tentu saja itu tidak berhasil.

Saya tahu saya bisa melakukannya:

./settings >/tmp/file
source /tmp/file

tetapi saya benar-benar tidak ingin melakukan itu.

Ada petunjuk?

Jawaban:


16

Anda bisa menggunakan eval:

eval "$(./settings)"

eval "`./settings`"

Maaf, seharusnya disebutkan, ini / bin / sh tidak bash. $ () tidak berfungsi. Saya telah memperbarui pertanyaan.
Majenko

@ Matt: Ya, dia bash pada kebanyakan sistem. Kecuali tentu saja yang Anda maksud adalah versi Ubuntu terbaru, di mana ia telah diganti dengan tanda hubung.
Hello71

@Matt: Dalam hal ini, backticks akan berfungsi. Tetapi Anda harus menambahkan versi persisnya shjuga - itu bisa menjadi symlink ke dash, ash, busybox ... Saya belum melihat salinan live "the 'sh'".
user1686

1
@ Matt: Jadi Anda punya ... sistem yang menarik di sana. Terutama karena hampir semua variasi "sh" mendukung $( )- dimulai dengan shell Almquist di 4.3BSD - dan juga POSIX. (Catatan: tidak berdebat, hanya ingin tahu.)
user1686

$ () ada, tidak berfungsi seperti itu dalam keadaan ini. FreeBSD 8,2 / bin / sh
Majenko

15

Pada sistem di mana /dev/fdtersedia, bash mendukung penggantian proses:

source <(./settings)

Di sini, <( )akan diperluas ke jalur yang ditetapkan secara otomatis di bawah /dev/fd/...dari mana output ./settingsdapat dibaca.


1
Dalam manual bash, ini disebut "proses substitusi".
glenn jackman

6
declare `./settings`

Atau tentu saja ...

export `./settings`

Mengujinya tentu saja ...

export `echo -e "asdf=test\nqwerty=dvorak"` ; echo $asdf $qwerty

Menangani ruang kosong:

eval export `./settings`

Aha, exporttriknya berhasil! Terima kasih
Majenko

Sekarang - bagaimana saya bisa menangani spasi dalam suatu nilai?
Majenko

@Matt: Saya tidak bisa menggunakan backtick dalam komentar, jadi silakan lihat jawaban yang diedit.
user1686

@grawity: Ya, Anda bisa ...a backtick --> ` <-- and here's another one --> ` <--
Hello71

2

source /dev/stdin < ./settings

Saya pikir / dev / stdin adalah Linux saja.


yang mencoba sumber konten pengaturan. Bahkan dengan './settings' gagal dengan './settings': Ambiguous ('= backtick)
Majenko

/dev/stdinbekerja pada BSD dan Cygwin juga.
user1686

1
Menggunakan |, bagaimanapun, tidak akan bekerja (setidaknya tidak persis), karena kedua sisi pipa yang subproses terpisah, sehingga perintah bersumber tidak akan mempengaruhi shell saat ini.
user1686

1
diedit untuk mencerminkan hal itu.
LawrenceC

1
Saya suka /dev/stdintrik ini , tapi apa jawaban Anda sebenarnya setara dengan dataran source ./settingstanpa menjalankannya. Satu bisa menggunakan di sini-dokumen untuk mengatasi hal ini: source /dev/stdin <<EOF \n $(./settings) \n EOF.
tlwhitec

0

Ingin memberikan perspektif lain di sini, karena jawaban yang lain membuat file dan tidak langsung menarik dari stdin. Saya memiliki beberapa bangunan yang perlu mengirimkan beberapa informasi lingkungan yang disiapkan ke beberapa skrip. Apa yang saya lakukan adalah menyiapkan sekelompok tugas variabel yang kompatibel dengan Bash dalam sebuah string:

Var1="Foo"
Var2="Bar"
Var3="Baz"

Ketika saya bersiap untuk menjalankan skrip, saya base64 menyandikan string multiline di atas dan pipa itu ke skrip shell saya:

echo base64EncodedParameters | build.sh

Dalam build.sh saya membaca dari stdin, base64 decode dan evaluasi hasilnya.

params=""
while read line; do params="${params}${line}"; done
eval `echo $params | base64 -D`

echo "Hello ${Var1} ${Var2}"
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.