Saya mencoba untuk mendapatkan bash untuk memproses data dari stdin yang disalurkan ke, tetapi 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 hasilnya test=hello world
. Saya sudah mencoba menempatkan "" tanda kutip di sekitar "$test"
yang tidak berhasil.
shopt -s lastpipe
- tldp.org/LDP/abs/html/bashver4.html#LASTPIPEOPTJawaban:
Menggunakan
Anda bisa mengelabui
read
penerimaan dari pipa seperti ini:atau bahkan menulis fungsi seperti ini:
Tapi tidak ada gunanya - tugas variabel Anda mungkin tidak bertahan! Sebuah pipa dapat menelurkan subkulit, di mana lingkungan diwarisi oleh nilai, bukan dengan referensi. Ini sebabnya
read
tidak repot dengan input dari pipa - itu tidak terdefinisi.FYI, http://www.etalabs.net/sh_tricks.html adalah koleksi bagus dari cruft yang diperlukan untuk melawan keanehan dan ketidakcocokan shell bourne, sh.
sumber
test=`echo "hello world" | { read test; echo $test; }`
{}
alih-alih()
mengelompokkan dua perintah itu?read
mengambil input dari pipa, tetapi menggunakan variabel dalam shell yang sama yang mengeksekusiread
.bash permission denied
ketika mencoba menggunakan solusi ini. Kasus saya sangat berbeda, tapi aku tidak bisa menemukan jawaban untuk itu di mana saja, apa yang bekerja untuk saya adalah (contoh yang berbeda namun penggunaan serupa):pip install -U echo $(ls -t *.py | head -1)
. Dalam hal, seseorang pernah memiliki masalah yang sama dan menemukan jawaban ini seperti saya.jika Anda ingin membaca banyak data dan mengerjakan setiap baris secara terpisah, Anda dapat menggunakan sesuatu seperti ini:
jika Anda ingin membagi baris menjadi beberapa kata, Anda dapat menggunakan beberapa variabel sebagai ganti x seperti ini:
kalau tidak:
Tetapi segera setelah Anda mulai ingin melakukan sesuatu yang benar-benar pandai dengan hal-hal semacam ini, Anda lebih baik menggunakan bahasa scripting seperti perl di mana Anda dapat mencoba sesuatu seperti ini:
Ada kurva belajar yang cukup curam dengan perl (atau saya kira salah satu dari bahasa-bahasa ini) tetapi Anda akan merasa jauh lebih mudah dalam jangka panjang jika Anda ingin melakukan apa pun kecuali skrip yang paling sederhana. Saya akan merekomendasikan Perl Cookbook dan, tentu saja, The Perl Programming Language oleh Larry Wall et al.
sumber
read
tidak akan membaca dari pipa (atau mungkin hasilnya hilang karena pipa membuat subkulit). Namun, Anda dapat menggunakan string di sini di Bash:Tetapi lihat jawaban @ chepner untuk informasi tentang
lastpipe
.sumber
Ini adalah pilihan lain
sumber
<(..)
telah berakhir$(..)
adalah<(..)
mengembalikan setiap baris ke pemanggil segera setelah perintah yang dijalankan membuatnya tersedia.$(..)
Namun, menunggu perintah untuk menyelesaikan dan menghasilkan semua outputnya sebelum membuat output tersedia untuk pemanggil.Saya bukan ahli dalam Bash, tapi saya ingin tahu mengapa ini belum diusulkan:
Satu bukti liner yang berfungsi untuk saya:
sumber
bash
4.2 memperkenalkanlastpipe
opsi, yang memungkinkan kode Anda bekerja seperti yang tertulis, dengan mengeksekusi perintah terakhir dalam pipeline di shell saat ini, bukan subshell.sumber
Sintaks untuk pipa implisit dari perintah shell ke variabel bash adalah
atau
Dalam contoh Anda, Anda mengirim data ke pernyataan tugas, yang tidak mengharapkan input apa pun.
sumber
Upaya pertama cukup dekat. Variasi ini seharusnya bekerja:
dan hasilnya adalah:
Anda perlu kawat gigi setelah pipa untuk melampirkan tugas untuk menguji dan gema.
Tanpa kawat gigi, tugas untuk menguji (setelah pipa) dalam satu shell, dan gema "test = $ test" berada di shell yang terpisah yang tidak tahu tentang tugas itu. Itu sebabnya Anda mendapatkan "test =" di output daripada "test = hello world".
sumber
Di mata saya cara terbaik untuk membaca dari stdin di bash adalah yang berikut, yang juga memungkinkan Anda bekerja pada baris sebelum input berakhir:
sumber
Karena aku jatuh cinta padanya, aku ingin menjatuhkan catatan. Saya menemukan utas ini, karena saya harus menulis ulang skrip sh lama agar kompatibel dengan POSIX. Ini pada dasarnya berarti untuk menghindari masalah pipa / subkulit yang diperkenalkan oleh POSIX dengan menulis ulang kode seperti ini:
ke:
Dan kode seperti ini:
ke:
Tetapi yang terakhir tidak berlaku sama pada input kosong. Dengan notasi lama loop sementara tidak dimasukkan pada input kosong, tetapi dalam notasi POSIX itu! Saya pikir itu karena baris baru sebelum EOF, yang tidak dapat dibatalkan. Kode POSIX yang berperilaku lebih seperti notasi lama terlihat seperti ini:
Dalam kebanyakan kasus ini harus cukup baik. Namun sayangnya ini masih berperilaku tidak persis seperti notasi lama jika some_command mencetak baris kosong. Dalam notasi lama tubuh sementara dieksekusi dan dalam notasi POSIX kita istirahat di depan tubuh.
Pendekatan untuk memperbaiki ini mungkin terlihat seperti ini:
sumber
Skrip cerdas yang dapat membaca data dari argumen PIPE dan perintah:
Keluaran:
Penjelasan: Ketika sebuah skrip menerima data apa pun melalui pipa, maka stdin / proc / self / fd / 0 akan menjadi symlink ke sebuah pipa.
Jika tidak, itu akan mengarah ke terminal saat ini:
[[ -p
Opsi bash dapat memeriksanya apakah itu pipa atau bukan.cat -
membaca daristdin
.Jika kita gunakan
cat -
ketika tidak adastdin
, itu akan menunggu selamanya, itu sebabnya kita memasukkannya ke dalamif
kondisi.sumber
/dev/stdin
tautan ke/proc/self/fd/0
Memipiskan sesuatu ke ekspresi yang melibatkan tugas tidak berlaku seperti itu.
Sebagai gantinya, cobalah:
sumber
Kode berikut:
akan bekerja juga, tetapi itu akan membuka sub-shell baru setelah pipa, di mana
biasa.
Saya harus menonaktifkan kontrol pekerjaan untuk menggunakan metode chepnars (saya menjalankan perintah ini dari terminal):
Bash Manual mengatakan :
Catatan: kontrol pekerjaan dimatikan secara default di shell non-interaktif dan karenanya Anda tidak memerlukan
set +m
skrip di dalamnya.sumber
Saya pikir Anda mencoba untuk menulis skrip shell yang dapat mengambil input dari stdin. tetapi ketika Anda mencoba untuk melakukannya inline, Anda tersesat mencoba membuat tes itu = variabel. Saya pikir itu tidak masuk akal untuk melakukannya sebaris, dan itu sebabnya tidak bekerja seperti yang Anda harapkan.
Saya berusaha mengurangi
untuk mendapatkan jalur tertentu dari berbagai input. jadi saya bisa mengetik ...
jadi saya perlu program shell kecil yang bisa membaca dari stdin. seperti kamu.
ini dia.
sumber
Bagaimana dengan ini:
sumber