Di abu, lari dan bash, ketika saya lari
$ echo ab$
ia kembali
ab$
Apakah perilaku ini ditentukan oleh POSIX atau hanya konvensi umum di shell yang sesuai dengan POSIX? Saya tidak dapat menemukan apa pun di halaman POSIX Shell Command Language yang menyebutkan perilaku ini.
$
mendapatkan makna khusus jika itu adalah karakter terakhir dalam sebuah kata?" Tidak ada makna khusus yang diberikan untuk$
; ini digunakan untuk memperkenalkan beberapa, tetapi berbeda, ekspansi, seperti ekspansi parameter${...}
, penggantian perintah$(...)
, dan ekspresi aritmatika$((...))
. Beberapa shell memperkenalkan konteks tambahan, sepertiksh
varian substitusi-perintahx=${ echo foo; echo bar;}
(yang berbeda dari standar$(...)
dengan tidak mengeksekusi perintah dalam subkulit).ab$
, tidak ada karakter berikut$
, apakah itu "diikuti" oleh karakter null pada input string asli atau spasi dalam kasus sepertiecho ab$ foo
; spasi asli yang tidak dikutip telah dikenali dan dibuang setelah diuraikan.Jawaban:
$
tidak memiliki arti khusus dengan sendirinya (cobaecho $
), hanya ketika digabungkan dengan karakter lain setelahnya dan membentuk ekspansi, misalnya$var
(atau${var}
)$(util)
,,$((1+2))
.The
$
mendapat makna "khusus" sebagai mendefinisikan ekspansi dalam standar POSIX di bawah bagian Pengakuan Token :Jadi, jika
$
tidak membentuk ekspansi, aturan parsing lain berlaku:Itu menutupi
ab$
string Anda .Dalam kasus sendirian
$
("kata baru" akan menjadi$
dengan sendirinya):The makna dari kata yang dihasilkan mengandung
$
yang tidak ekspansi standar secara eksplisit didefinisikan sebagai tidak ditentukan oleh POSIX.Perhatikan juga bahwa
$
ini adalah karakter terakhir$$
, tetapi ini juga merupakan variabel yang menyimpan PID shell saat ini. Dibash
,!$
dapat memanggil ekspansi sejarah (argumen terakhir dari perintah sebelumnya). Jadi secara umum, tidak,$
bukan tanpa makna pada akhir kata yang tidak dikutip, tetapi pada akhir kata itu setidaknya tidak menunjukkan ekspansi standar.sumber
Bergantung pada situasi yang tepat, ini bisa secara eksplisit tidak ditentukan (sehingga implementasi dapat melakukan apa yang mereka mau) atau diharuskan untuk terjadi saat Anda mengamati. Dalam skenario persis Anda
echo ab$
, POSIX mengamanatkan keluaran "ab $" yang Anda amati dan tidak ditentukan . Ringkasan singkat dari semua kasus yang berbeda ada di akhir.Ada dua elemen: pertama mencari kata-kata, dan kemudian menafsirkan kata-kata itu.
Tokenisasi
Tokenisasi POSIX mensyaratkan bahwa a
$
yang bukan awal dari perluasan parameter yang valid , substitusi perintah , atau substitusi aritmatika untuk dianggap sebagai bagian literal dariWORD
token yang sedang dibangun. Ini karena aturan 5 ("Jika karakter saat ini adalah tanda kutip$
atau`
, shell harus mengidentifikasi awal dari setiap kandidat untuk ekspansi parameter, penggantian perintah, atau ekspansi aritmatika dari urutan karakter tanpa tanda kutip pengantar mereka:$
atau${
,$(
atau`
, dan$((
, masing-masing" ) tidak berlaku, karena tidak ada ekspansi yang layak di sana. Perluasan parameter memerlukan nama yang valid untuk muncul di sana, dan nama yang kosong tidak valid.Karena aturan ini tidak berlaku, kami terus mengikuti hingga kami menemukannya. Dua kandidat adalah # 8 ("Jika karakter sebelumnya adalah bagian dari sebuah kata, karakter saat ini akan ditambahkan ke kata itu.") Dan # 10 ("Karakter saat ini digunakan sebagai awal dari kata baru.") , yang berlaku untuk
echo a$
danecho $
masing - masing.Ada juga kasus ketiga dari formulir
echo a$+b
yang jatuh melalui celah yang sama, karena+
bukan nama parameter khusus. Yang ini akan kita bahas nanti, karena memicu berbagai bagian aturan.Dengan demikian spesifikasi mensyaratkan bahwa kata
$
tersebut dianggap sebagai bagian dari kata secara sintaksis, dan kemudian dapat diproses lebih lanjut di kemudian hari.Perluasan kata
Setelah input diuraikan dengan cara ini, dengan yang
$
termasuk dalam kata, ekspansi kata diterapkan ke setiap kata yang telah dibaca. Setiap kata diproses secara individual .Ditetapkan bahwa :
"Tidak ditentukan" adalah istilah khusus di sini yang berarti
Dalam contoh Anda,
echo ab$
, yang$
tidak diikuti oleh setiap karakter , sehingga aturan ini tidak berlaku dan hasil yang tidak ditentukan tidak dipanggil. Tidak ada ekspansi yang dipicu oleh$
, sehingga benar-benar ada dan dicetak.Di mana itu akan berlaku dalam kasus ketiga kami dari atas:
echo a$+b
. Berikut$
ini diikuti oleh+
yang bukan nomor, parameter khusus (@
,*
,#
,?
,-
,$
,!
, atau0
), mulai dari variabel nama (garis bawah atau abjad dari set karakter portable ), atau salah satu dari tanda kurung. Dalam kasus ini, perilaku tidak ditentukan: shell yang sesuai diizinkan untuk menciptakan parameter khusus yang dipanggil+
untuk memperluas , dan aplikasi yang sesuai tidak boleh berasumsi bahwa shell tidak . Shell dapat melakukan hal lain yang disukainya, termasuk melaporkan kesalahan.Sebagai contoh, zsh, termasuk dalam mode POSIX-nya, mengartikan
$+b
sebagai "b
set variabel " dan menggantikan 1 atau 0 sebagai gantinya. Ini juga memiliki ekstensi untuk~
dan=
. Ini adalah perilaku yang sesuai.Tempat lain yang bisa terjadi adalah
echo "a$ b"
. Sekali lagi, shell diizinkan untuk melakukan$
apa yang diinginkan , dan Anda sebagai penulis naskah harus melarikan diri jika Anda ingin output literal. Jika tidak, ini mungkin berhasil, tetapi Anda tidak dapat mengandalkannya. Ini adalah huruf absolut dari spesifikasi, tetapi saya tidak berpikir granularity semacam ini dimaksudkan atau dipertimbangkan.Singkatnya
echo ab$
: output literal, ditentukan sepenuhnyaecho a$ b
: output literal, ditentukan sepenuhnyaecho a$ b$
: output literal, ditentukan sepenuhnyaecho a$b
: perluasan parameterb
, ditentukan sepenuhnyaecho a$-b
: perluasan parameter khusus-
, ditentukan sepenuhnyaecho a$+b
: perilaku yang tidak ditentukanecho "a$ b"
: perilaku yang tidak ditentukanUntuk a
$
di akhir kata, Anda diizinkan untuk mengandalkan perilaku dan itu harus diperlakukan secara harfiah dan diteruskan keecho
perintah sebagai bagian dari argumennya. Itu adalah persyaratan kesesuaian pada shell.sumber
echo $
juga literal dan ditentukan sepenuhnya?echo "$"
danecho "a b$"
jatuh?