Anda membingungkan argumen dan masukan standar. Mengirimkan data ke program tidak sama dengan memberikan argumen baris perintah.
Dalam kasus pertama Anda, Anda tidak memberikan argumen ke skrip Anda, hanya memberinya data melalui aliran input standarnya. Jadi $1
tidak disetel untuk seluruh durasi skrip.
Pemanggilan pertama more
sehingga tidak memiliki parameter, dan halaman masukan standar. Ini menampilkan apa yang telah Anda salurkan ke sana (dir1
, sebagai teks). echo
berikutnya hanya mencetak baris baru karena tidak ada yang dicetak, dan more
terakhir tidak ada yang tersisa untuk dicetak - input standar telah "dikuras" oleh yang pertama.
Dalam kasus kedua, Anda memberikan argumen. Jadi $1
memiliki nilai dir2
dalam naskah. Hal yang sama terjadi, kecuali more
yang pertama keduanya:
- laman melalui kedua masukan standar
- berusaha membuka halaman file
dir2
dan kesalahan keluar karena itu direktori
Gema melakukan apa yang diharapkan dengan $1
itu berisi dir2
, dan more
terakhir hanya kesalahan pada dir2
- tidak ada yang bisa dibaca dari input standar.
Perbedaannya ada pada "Argumen " VS "Masukan Standar ".
Saat Anda menjalankan echo dir1 | bash script.sh
, $1
argumen di script.sh
Anda selalu kosong karena tidak ada argumen yang diberikan padanya (coba tambahkan set -x
di awal dan Anda akan melihatnya di keluaran debug). dir1
yang digaungkan berasal dari input standar sebagai more
perintah baca stdin jika tidak ada argumen yang diberikan (ingat $1
kosong).
Bagaimana cmd1 | cmd2
berfungsi
Saat menggunakan pipa :
cmd2
adalah subproses daricmd1
.- stdin dari
cmd2
adalah "terpasang" di stdoutcmd1
.
Karena linux stdio lib menawarkan aliran buffer melalui deskriptor file, konten stdin akan dikonsumsi (yaitu hanya dibaca sekali) hanya ketika stdin akan dibuka .
Langkah demi langkah cmd1 | cmd2
alur kerja
Contoh perintah :
echo dir1 | (echo "a" ; read stdinvalue; echo "$stdinvalue")
echo dir1 |
:tulis "dir1\n
" pada stdout dari perintah pertama yang tidak di-echo tetapi di-buffer melalui stdio dan tersedia untuk diproses melalui stdin.echo "a"
:tulis "a\n
" di stdout; tidak membaca stdin! jadi "dir1\n
" string masih tersediaread stdinvalue
:baca stdin hingga EOL (atau EOF) dan simpan string dalam variabel bashecho "$stdinvalue"
:tulis nilai variabel stdinvalue ke stdout