Membaca nilai-nilai ke sebuah variabel shell dari pipa

Saya mencoba untuk mendapatkan bash untuk memproses data dari stdin yang akan disalurkan ke dalam, tapi tidak berhasil. Yang saya maksud adalah tidak ada pekerjaan berikut:

echo "hello world" | test=($(< /dev/stdin)); echo test=$test
test=

echo "hello world" | read test; echo test=$test
test=

echo "hello world" | test=`cat`; echo test=$test
test=

di mana saya ingin output untuk menjadi test=hello world. I've mencoba menempatkan "," tanda kutip "$test" yang doesn't bekerja dengan baik.

Mengomentari pertanyaan (5)
Larutan

Gunakan


IFS= read var 
Komentar (7)

jika anda ingin membaca di banyak data dan bekerja pada setiap baris secara terpisah, anda bisa menggunakan sesuatu seperti ini:

cat myFile | while read x ; do echo $x ; done

jika anda ingin membagi garis menjadi beberapa kata, anda dapat menggunakan beberapa variabel pada x seperti ini:

cat myFile | while read x y ; do echo $y $x ; done

atau:

while read x y ; do echo $y $x ; done < myFile

Tapi segera setelah anda mulai untuk ingin melakukan sesuatu yang benar-benar pintar dengan hal semacam ini, anda're baik akan untuk beberapa bahasa script seperti perl di mana anda dapat mencoba sesuatu seperti ini:

perl -ane 'print "$F[0]\n"' < myFile

Ada's cukup kurva belajar yang curam dengan perl (atau saya kira salah satu dari bahasa-bahasa ini) tapi anda'll menemukan ini jauh lebih mudah dalam jangka panjang jika anda ingin melakukan apa-apa tapi sederhana dari script. I'd merekomendasikan Perl Masak dan, tentu saja, Bahasa Pemrograman Perl oleh Larry Wall et al.

Komentar (1)

Ini adalah pilihan lain


$ read test < 
Komentar (1)

baca tidak't baca dari sebuah pipa (atau mungkin hasilnya hilang karena pipa menciptakan subkulit). Namun, anda dapat menggunakan berikut string di Bash:


$ read a b c 
Komentar (1)

I'm tidak ahli dalam Bash, tapi aku bertanya-tanya mengapa ini tidak't telah diusulkan:

stdin=$(cat)

echo "$stdin"

Satu-liner bukti bahwa ia bekerja untuk saya:

$ fortune | eval 'stdin=$(cat); echo "$stdin"'
Komentar (9)

bash 4.2 memperkenalkan lastpipe pilihan, yang memungkinkan kode anda untuk bekerja seperti yang tertulis, dengan mengeksekusi perintah terakhir dalam pipa pada shell saat ini, daripada subkulit.

shopt -s lastpipe
echo "hello world" | read test; echo test=$test
Komentar (1)

Sintaks untuk implisit pipa dari perintah shell ke bash variabel

var=$(command)

atau

var=`command`

Dalam contoh anda, anda adalah pipa data untuk tugas pernyataan, yang tidak mengharapkan masukan apapun.

Komentar (4)

Upaya pertama adalah cukup dekat. Variasi ini harus bekerja:

echo "hello world" | { test=$(< /dev/stdin); echo "test=$test"; };

dan output adalah:

tes=halo dunia

Anda perlu kawat gigi setelah pipa untuk melampirkan tugas untuk menguji dan echo.

Tanpa kawat gigi, tugas untuk tes (setelah pipa) adalah dalam satu shell, dan echo "test=$test" di tempat terpisah shell yang doesn't tahu tentang penugasan itu. Yang's mengapa anda mendapatkan "test=" dalam output bukan "test=halo dunia".

Komentar (0)

Di mata saya cara terbaik untuk baca dari stdin di bash adalah yang berikut, yang juga memungkinkan anda bekerja pada garis sebelum input berakhir:

while read LINE; do
    echo $LINE
done < /dev/stdin
Komentar (2)

Karena aku jatuh untuk itu, saya ingin menjatuhkan catatan. Saya menemukan thread ini, karena saya harus menulis ulang tua sh script untuk menjadi POSIX compatible. Ini pada dasarnya berarti untuk menghindari pipa/subkulit masalah yang diperkenalkan oleh POSIX dengan menulis ulang kode seperti ini:

some_command | read a b c

ke:


read a b c 
Komentar (0)

Pipa sesuatu ke suatu ekspresi yang melibatkan tugas doesn't berperilaku seperti itu.

Sebaliknya, cobalah:

test=$(echo "hello world"); echo test=$test
Komentar (0)

Kode berikut:

echo "hello world" | ( test=($(< /dev/stdin)); echo test=$test )

akan bekerja juga, tapi itu akan membuka lagi baru sub-shell setelah pipa, di mana

echo "hello world" | { test=($(< /dev/stdin)); echo test=$test; }

won't.


Aku harus menonaktifkan kontrol pekerjaan untuk membuat penggunaan [chepnars][1]' metode (saya menjalankan perintah ini dari terminal):


set +m;shopt -s lastpipe
echo "hello world" | read test; echo test=$test
echo "hello world" | test="$(
Komentar (0)

Saya pikir anda mencoba untuk menulis sebuah skrip shell yang bisa mengambil input dari stdin. tapi saat anda mencoba untuk melakukannya inline, anda tersesat mencoba untuk membuat bahwa tes= variabel. Saya pikir itu tidak masuk akal untuk melakukannya inline, dan yang's mengapa hal itu tidak bekerja seperti yang anda harapkan.

Saya mencoba untuk mengurangi

$( ... | head -n $X | tail -n 1 )

untuk mendapatkan baris tertentu dari berbagai input. jadi saya bisa mengetik...

cat program_file.c | line 34

jadi saya perlu kecil program shell dapat baca dari stdin. seperti yang anda lakukan.

22:14 ~ $ cat ~/bin/line 
#!/bin/sh

if [ $# -ne 1 ]; then echo enter a line number to display; exit; fi
cat | head -n $1 | tail -n 1
22:16 ~ $ 

di sana anda pergi.

Komentar (0)

Pintar script yang dapat membaca data dari PIPA dan argumen baris perintah:

#!/bin/bash
if [[ -p /proc/self/fd/0 ]]
    then
    PIPE=$(cat -)
    echo "PIPE=$PIPE"
fi
echo "ARGS=$@"

Output:

$ bash test arg1 arg2
ARGS=arg1 arg2

$ echo pipe_data1 | bash test arg1 arg2
PIPE=pipe_data1
ARGS=arg1 arg2

Penjelasan: Ketika sebuah script menerima data melalui pipa, maka stdin /proc/self/fd/0 akan symlink ke pipa.

/proc/self/fd/0 -> pipe:[155938]

Jika tidak, hal itu akan mengarah ke terminal saat ini:

/proc/self/fd/0 -> /dev/pts/5

Bash jika -p pilihan dapat memeriksa itu adalah pipa atau tidak.

kucing membaca dari stdin.

Jika kita menggunakan kucing ketika tidak ada stdin, itu akan menunggu selamanya, itu sebabnya kami menempatkan itu di dalam jika kondisi.

Komentar (1)

Bagaimana dengan ini:

echo "hello world" | echo test=$(cat)
Komentar (2)