Yang perlu dijelaskan adalah bahwa perintah itu tampaknya berfungsi, bukan kode keluarnya
'\n'adalah dua karakter: garis miring terbalik \dan satu huruf n. Apa yang Anda pikir Anda butuhkan adalah $'\n', yang merupakan linefeed (tetapi itu juga tidak benar, lihat di bawah).
The -dopsi melakukan hal ini:
-d delim continue until the first character of DELIM is read, rather
than newline
Jadi tanpa opsi itu, readakan membaca hingga baris baru, membagi garis menjadi kata-kata menggunakan karakter $IFSsebagai pemisah, dan memasukkan kata-kata ke dalam array. Jika Anda menentukan -d $'\n', mengatur pembatas garis ke baris baru, itu akan melakukan hal yang persis sama . Pengaturan -d '\n'berarti bahwa ia akan membaca hingga backslash pertama (tetapi, sekali lagi, lihat di bawah), yang merupakan karakter pertama di delim. Karena tidak ada garis miring terbalik di file Anda, maka readakan berakhir pada akhir file, dan:
Exit Status:
The return code is zero, unless end-of-file is encountered, read times out,
or an invalid file descriptor is supplied as the argument to -u.
Jadi itu sebabnya kode keluar adalah 1.
Dari fakta bahwa Anda percaya bahwa perintah itu berfungsi, kita dapat menyimpulkan bahwa tidak ada spasi di file, sehingga read, setelah membaca seluruh file dengan harapan sia-sia menemukan backslash, akan membaginya dengan spasi putih (nilai default dari $IFS), termasuk baris baru. Jadi setiap baris (atau setiap kata, jika satu baris berisi lebih dari satu kata) disimpan ke dalam array.
Kasus misterius backslash purloined
Sekarang, bagaimana saya tahu file tersebut tidak mengandung garis miring terbalik? Karena Anda tidak memasok -rbendera ke read:
-r do not allow backslashes to escape any characters
Jadi, jika Anda memiliki garis miring terbalik di file, mereka akan dilucuti, kecuali jika Anda memiliki dua dari mereka berturut-turut. Dan, tentu saja, ada bukti yang readmemiliki kode keluar 1, yang menunjukkan bahwa itu tidak menemukan backslash, jadi tidak ada dua dari mereka berturut-turut.
Takeaways
Bash tidak akan menjadi bash jika tidak ada gotchas bersembunyi di balik setiap perintah, dan readtidak terkecuali. Berikut adalah pasangannya:
Kecuali Anda tentukan -r, readakan menafsirkan urutan melarikan diri backslash. Kecuali jika memang itu yang Anda inginkan (yang memang sesekali, tetapi hanya sesekali), Anda harus ingat untuk menentukan -ragar karakter tidak hilang dalam kasus yang jarang ada backslash pada input.
Fakta yang readmengembalikan kode keluar 1 tidak berarti gagal. Mungkin berhasil, kecuali untuk menemukan terminator garis. Jadi hati-hati dengan loop seperti ini: while read -r LINE; do something with LINE; done
karena akan gagal do somethingdengan baris terakhir dalam kasus yang jarang terjadi bahwa baris terakhir tidak memiliki baris baru di akhir.
read -r LINE mempertahankan garis miring terbalik, tetapi itu tidak mempertahankan spasi spasial memimpin atau tertinggal.