$(<file)
(juga bekerja dengan `<file`
) adalah operator khusus dari shell Korn yang disalin oleh zsh
dan bash
. Memang terlihat sangat mirip dengan substitusi perintah tetapi sebenarnya tidak.
Dalam shell POSIX, perintah sederhana adalah:
< file var1=value1 > file2 cmd 2> file3 args 3> file4
Semua bagian adalah opsional, Anda dapat memiliki pengalihan saja, hanya perintah, hanya tugas atau kombinasi.
Jika ada pengalihan tetapi tidak ada perintah, pengalihan dilakukan (jadi a > file
akan terbuka dan memotong file
), tetapi kemudian tidak ada yang terjadi. Begitu
< file
Terbuka file
untuk membaca, tetapi tidak ada yang terjadi karena tidak ada perintah. Jadi file
kemudian ditutup dan hanya itu. Jika $(< file)
itu adalah substitusi perintah yang sederhana , maka itu tidak akan berkembang.
Dalam spesifikasi POSIX , dalam $(script)
, jika script
hanya terdiri dari pengalihan, yang menghasilkan hasil yang tidak ditentukan . Itu untuk memungkinkan perilaku khusus cangkang Korn.
Dalam ksh (di sini diuji dengan ksh93u+
), jika skrip terdiri dari satu dan hanya satu perintah sederhana (meskipun komentar diperbolehkan sebelum dan sesudah) yang hanya terdiri dari pengalihan (tidak ada perintah, tidak ada tugas) dan jika pengalihan pertama adalah stdin (fd 0) hanya input ( <
, <<
atau <<<
) redirection, jadi:
$(< file)
$(0< file)
$(<&3)
(juga $(0>&3)
sebenarnya karena itu berlaku operator yang sama)
$(< file > foo 2> $(whatever))
tapi tidak:
$(> foo < file)
- maupun
$(0<> file)
- maupun
$(< file; sleep 1)
- maupun
$(< file; < file2)
kemudian
- semua kecuali pengalihan pertama diabaikan (mereka diurai)
- dan itu berkembang ke konten file / heredoc / herestring (atau apa pun yang dapat dibaca dari deskriptor file jika menggunakan hal-hal seperti
<&3
) dikurangi karakter garis belakang yang tertinggal.
seakan menggunakan $(cat < file)
kecuali itu
- bacaan dilakukan secara internal oleh shell dan bukan oleh
cat
- tidak ada pipa atau proses tambahan yang terlibat
- sebagai konsekuensi dari hal di atas, karena kode di dalamnya tidak dijalankan dalam subkulit, modifikasi apa pun tetap setelahnya (seperti dalam
$(<${file=foo.txt})
atau $(<file$((++n)))
)
- kesalahan baca (meskipun bukan kesalahan saat membuka file atau menggandakan deskriptor file) diabaikan secara diam-diam.
Dalam zsh
, itu sama kecuali bahwa bahwa perilaku khusus yang hanya dipicu ketika hanya ada satu input redirection berkas ( <file
atau 0< file
, tidak ada <&3
, <<<here
, < a < b
...)
Namun, kecuali saat meniru shell lain, di:
< file
<&3
<<< here...
yaitu ketika hanya ada pengalihan input tanpa perintah, di luar substitusi perintah, zsh
menjalankan $READNULLCMD
(pager secara default), dan ketika ada pengalihan input dan output, $NULLCMD
( cat
secara default), bahkan jika $(<&3)
tidak diakui sebagai yang khusus operator, itu masih akan bekerja seperti di ksh
olah dengan memanggil pager untuk melakukannya (pager itu bertindak seperti cat
stdout akan menjadi pipa).
Namun sementara ksh
itu $(< a < b)
akan diperluas ke konten a
, dalam zsh
, itu berkembang ke konten a
dan b
(atau hanya b
jika multios
opsi dinonaktifkan), $(< a > b)
akan menyalin a
ke b
dan memperluas ke apa-apa, dll.
bash
memiliki operator yang sama tetapi dengan beberapa perbedaan:
komentar diperbolehkan sebelum tetapi tidak setelah:
echo "$(
# getting the content of file
< file)"
bekerja tetapi:
echo "$(< file
# getting the content of file
)"
mengembang tanpa apa-apa.
seperti di zsh
, hanya satu pengalihan stdin file, meskipun tidak ada jatuh kembali ke $READNULLCMD
, jadi $(<&3)
, $(< a < b)
lakukan pengalihan tetapi memperluas ke apa-apa.
- untuk beberapa alasan, sementara
bash
tidak meminta cat
, itu masih memalsukan proses yang memberi makan konten file melalui pipa membuatnya jauh lebih sedikit dari optimasi daripada di shell lain. Ini berlaku seperti di $(cat < file)
mana cat
akan menjadi builtin cat
.
- sebagai konsekuensi dari hal di atas, setiap perubahan yang dilakukan di dalam hilang setelah itu (dalam
$(<${file=foo.txt})
, yang disebutkan di atas misalnya, bahwa $file
penugasan hilang setelah itu).
In bash
, IFS= read -rd '' var < file
(juga berfungsi zsh
) adalah cara yang lebih efektif untuk membaca konten file teks menjadi variabel. Ini juga memiliki manfaat melestarikan karakter baris baru. Lihat juga $mapfile[file]
di zsh
(dalam zsh/mapfile
modul dan hanya untuk file biasa) yang juga berfungsi dengan file biner.
Perhatikan bahwa varian berbasis pdksh ksh
memiliki beberapa variasi dibandingkan dengan ksh93. Yang menarik, di mksh
(salah satu dari shell yang diturunkan pdksh), di
var=$(<<'EOF'
That's multi-line
test with *all* sorts of "special"
characters
EOF
)
dioptimalkan dalam hal isi dokumen di sini (tanpa karakter trailing) diperluas tanpa file atau pipa sementara yang digunakan seperti halnya kasus untuk dokumen di sini, yang menjadikannya sintaks kutipan multi-baris yang efektif.
Menjadi portabel untuk semua versi ksh
, zsh
dan bash
, yang terbaik adalah membatasi hanya dengan $(<file)
menghindari komentar dan mengingat bahwa modifikasi pada variabel yang dibuat di dalamnya mungkin atau tidak dapat dipertahankan.
bash
akan menafsirkan itu sebagaicat filename
", apakah maksud Anda perilaku ini khusus untuk memerintahkan penggantian? Karena jika saya berlari< filename
dengan sendirinya, bash tidak mengatasinya. Ini tidak akan menghasilkan apa-apa dan mengembalikan saya ke prompt.