Bagaimana seseorang dapat menulis skrip yang menerima input dari argumen nama file atau dari stdin?
misalnya, Anda bisa menggunakan less
cara ini. seseorang dapat mengeksekusi less filename
dan setara cat filename | less
.
apakah ada cara "out of the box" yang mudah untuk melakukannya? atau apakah saya perlu menemukan kembali roda dan menulis sedikit logika dalam skrip?
command-line
bash
stdin
gilad hoch
sumber
sumber
Jawaban:
Jika argumen file adalah argumen pertama untuk skrip Anda, uji bahwa ada argumen (
$1
) dan itu adalah file. Lain membaca input dari stdin -Jadi skrip Anda dapat berisi sesuatu seperti ini:
mis. maka Anda dapat memanggil skrip seperti
atau
Edit beberapa penjelasan skrip:
[ $# -ge 1 -a -f "$1" ]
- Jika setidaknya satu argumen baris perintah ($# -ge 1
) DAN (-a operator) argumen pertama adalah file (-f menguji jika "$ 1" adalah file) maka hasil tes benar.&&
adalah shell AND operator. Jika pengujian benar, maka tetapkaninput="$1"
dancat $input
akan output file.||
adalah shell OR operator. Jika tes ini salah, maka perintah berikut||
diuraikan. input ditugaskan ke "-". Perintahcat -
membaca dari keyboard.Meringkas, jika argumen skrip disediakan dan itu adalah file, maka input variabel ditugaskan ke nama file. Jika tidak ada argumen yang valid maka kucing membaca dari keyboard.
sumber
&& input="$1" || input="-"
dilakukan dan mengapa itu di luartest
operator?$@
)?read
membaca dari input standar. Mengarahkannya dari file (./script <someinput
) atau melalui pipe (dosomething | ./script
) tidak akan membuatnya bekerja secara berbeda.Yang harus Anda lakukan adalah mengulangi semua baris dalam input (dan itu tidak berbeda dari iterasi pada baris dalam file).
(kode sampel, hanya memproses satu baris)
Akan menggemakan baris pertama input standar Anda (baik melalui
<
atau|
).sumber
Anda tidak menyebutkan shell apa yang Anda rencanakan untuk digunakan, jadi saya akan menganggap bash, meskipun ini adalah hal-hal yang cukup standar di seluruh shell.
File Argumen
Argumen dapat diakses melalui variabel
$1
-$n
($0
mengembalikan perintah yang digunakan untuk menjalankan program). Katakanlah saya memiliki skrip yang baru sajacat
keluar n jumlah file dengan pembatas di antaranya:Dalam hal ini, kami memberikan nama file ke cat. Namun, jika Anda ingin mengubah data dalam file (tanpa menulis dan menulis ulang secara eksplisit), Anda juga bisa menyimpan konten file dalam variabel:
Baca dari stdin
Sejauh membaca dari stdin, kebanyakan shell memiliki
read
builtin yang cukup standar , meskipun ada perbedaan dalam cara prompt ditentukan (paling tidak).The Bash Halaman builtin pria memiliki penjelasan singkat cantik
read
, tapi aku lebih suka Bash Hacker halaman.Secara sederhana:
Beberapa variabel
Untuk mengatur beberapa variabel, cukup berikan beberapa nama parameter ke
read
:read
kemudian akan menempatkan satu kata dari stdin ke setiap variabel, membuang semua kata yang tersisa ke variabel terakhir.Jika lebih sedikit kata yang dimasukkan daripada variabel, variabel sisa akan kosong (bahkan jika ditetapkan sebelumnya):
Anjuran
Saya
-p
sering menggunakan flag untuk prompt:Catatan: ZSH dan KSH (dan mungkin yang lain) menggunakan sintaks yang berbeda untuk prompt:
Nilai dasar
Ini sebenarnya bukan
read
tipuan, tapi saya sering menggunakannya bersamaread
. Sebagai contoh:Pada dasarnya, jika variabel (balasan) ada, kembalikan sendiri, tetapi jika kosong, kembalikan parameter berikut ("N").
sumber
Cara paling sederhana adalah dengan mengarahkan ulang stdin sendiri:
Atau jika Anda lebih suka bentuk yang lebih singkat:
Sekarang sisa skrip Anda dapat dibaca dari stdin. Tentu saja Anda dapat melakukan hal yang sama dengan parsing opsi lebih maju daripada mengkodekan posisi nama file sebagai
"$1"
.sumber
exec
akan mencoba menjalankan argumen sebagai perintah yang tidak kita inginkan di sini.if [ "$1" ] ; then exec < "$1" ; fi
dalam skrip pengujian dan memberikan pesan kesalahan karena perintahnya tidak dikenal. Sama dengan bentuk singkat.gunakan (atau matikan) sesuatu yang lain yang sudah berperilaku seperti ini, dan gunakan
"$@"
katakanlah saya ingin menulis alat yang akan menggantikan run spasi dalam teks dengan tab
tr
adalah cara yang paling jelas untuk melakukan ini, tetapi hanya menerima stdin, jadi kita harus melepaskancat
:untuk contoh di mana alat yang digunakan sudah berperilaku seperti ini, kita bisa menerapkannya dengan
sed
:sumber
Anda juga dapat melakukan:
Untuk trik substitusi parameter yang lebih rapi di Bash, lihat ini .
sumber
uglifyjs < /dev/stdin
dan bekerja sangat baik!Anda juga dapat membuatnya tetap sederhana dan menggunakan kode ini
Saat Anda membuat file skrip pass_it_on.sh dengan kode ini,
Anda bisa lari
dan semua isi stdin hanya akan dimuntahkan ke layar.
Atau gunakan kode ini untuk menyimpan salinan stdin dalam sebuah file dan kemudian memuntahkannya ke layar.
dan di sini adalah contoh lain, mungkin lebih mudah dibaca, dijelaskan di sini:
http://mockingeye.com/blog/2013/01/22/reading-everything-stdin-in-a-bash-script/
Selamat bersenang-senang.
RaamEE
sumber
Cara paling sederhana dan patuh POSIX adalah:
yang setara dengan
${1:--}
.Kemudian baca file seperti biasa:
sumber