for i in $(xrandr); do echo "$i" ; done
for i in "$(xrandr)"; do echo "$i"; done
for i in "$(xrandr)"; do echo $i; done
Saya mengerti mengapa 1 berbeda dari 2. Tetapi mengapa 3 memberikan output yang berbeda dari 2? Tolong jelaskan juga hasilnya. Bagaimana cara kerja kutipan di baris baru?
Jawaban:
Variabel yang tidak dikutip (seperti dalam
$var
) atau substitusi perintah (seperti dalam$(cmd)
atau`cmd`
) adalah operator split + glob dalam shell yang mirip Bourne.Artinya, konten mereka dibagi sesuai dengan nilai saat ini dari
$IFS
variabel khusus (yang secara default berisi spasi, tab, dan karakter baris baru)Dan kemudian setiap kata yang dihasilkan dari pemisahan itu tunduk pada generasi nama file (juga dikenal sebagai globbing atau ekspansi nama file ), yaitu, mereka dianggap sebagai pola dan diperluas ke daftar file yang cocok dengan pola itu.
Jadi
for i in $(xrandr)
, dalam$(xrandr)
, karena tidak ada dalam tanda kutip, dibagi pada urutan spasi, tab, dan karakter baris baru. Dan setiap kata yang dihasilkan dari pemisahan tersebut diperiksa untuk mencocokkan nama file (atau dibiarkan seolah-olah tidak cocok dengan file apa pun), danfor
mengulanginya semua.Dalam
for i in "$(xrandr)"
, kami tidak menggunakan operator split + glob seperti yang dikutip oleh substitusi , jadi ada satu pass dalam loop pada satu nilai: output darixrandr
(tanpa karakter baris tambahan yang memerintahkan strip pengganti ).Namun dalam
echo $i
,$i
tidak dikutip lagi, sehingga konten$i
split dan tunduk pada generasi nama file dan mereka dilewatkan sebagai argumen terpisah untukecho
perintah (danecho
output argumennya dipisahkan oleh spasi).Jadi pelajaran yang didapat:
$IFS
sesuai dan / atau aktifkan atau nonaktifkan pembuatan nama file jika diperlukan (set -f
,set +f
).Biasanya, dalam contoh Anda di atas, jika Anda ingin mengulang daftar kata-kata yang dipisahkan kosong di output dari
xrandr
, Anda harus:$IFS
pada nilai default-nya (atau tidak disetel) untuk dibagi menjadi kosongset -f
untuk menonaktifkan generasi nama file kecuali Anda yakin bahwaxrandr
tidak pernah output setiap*
atau?
atau[
karakter (yang wildcard digunakan dalam pola generasi nama file)Dan kemudian hanya menggunakan operator split + glob (hanya biarkan substitusi perintah atau ekspansi variabel tidak dikutip) di
in
bagianfor
loop:Jika Anda ingin loop atas (non-kosong) baris dari
xrandr
output, Anda akan perlu untuk set$IFS
untuk karakter baris baru:sumber
Baris baru yang dikutip adalah baris baru. Jadi
echo "$1"
memberikan argumen baris perintah tunggal untuk bergema, yang kemudian mencetak baris baru secara langsung.Baris baru tanpa tanda kutip adalah spasi. Jadi
echo $1
memberikan banyak argumen baris perintah untuk echo, yang mencetaknya satu demi satu dipisahkan dengan spasi.sumber