Mengapa $ {$ #} mengembalikan hasil yang sama dengan $$ di shell?

18

Ketika mencoba untuk mendapatkan set parameter posisi terakhir /bin/dash, saya sudah mencoba echo ${$#}. Anehnya ini tidak menghasilkan kesalahan, tetapi menjadi PID yang sama dengan $$konten variabel. Pertanyaan, mengapa sintaks itu berfungsi? Apa aturan sintaks yang diterapkan shell di sini?

Pada dasarnya, apa yang saya lakukan adalah

$ set 1 2 3 4 5
$ echo ${$#}
13819
$ echo $$
13819

Tampaknya, %karakter juga diabaikan dalam konstruksi semacam itu

$ echo ${$%}
13819

Tetapi *dan @menghasilkan kesalahan penggantian yang buruk:

$ echo ${$*}
sh: 10: Bad substitution
$ echo ${$@}
sh: 11: Bad substitution
Sergiy Kolodyazhnyy
sumber
3
Apa yang Anda harapkan ${$*}dan ${$@}hasilkan?
Kusalananda
2
@ Kusalananda Tidak ada harapan. Aku mencoba karakter lain di samping #dan %dan apa hasil perilaku dari orang-orang.
Sergiy Kolodyazhnyy
1
Untuk benar-benar melakukan tipuan di Dash, gunakan eval, mis dash -c 'set 1 2 3 4 5; eval "echo \$$#"'. Sumber: Ubuntu Wiki
wjandrea
1
@wjandrea Yap, sudah tahu itu. Sebenarnya sudah ada pertanyaan tentang hal itu: stackoverflow.com/questions/1853946/... Saya mencoba menemukan metode sendiri tanpa membaca pertanyaan pertama (dan saya sudah tahu for i; do true; doneuntuk mendapatkan item terakhir $i) tetapi mencari sesuatu yang lebih elegan. evaltentu saja dapat memiliki masalah potensial, dipikirkan sejauh mana - itu topik lain. Tapi ya, itu pilihan
Sergiy Kolodyazhnyy

Jawaban:

35

Ini $$ dengan awalan kosong yang dihapus :

${parameter#[word]}

Hapus Pola Awalan Terkecil . The Kata harus diperluas untuk menghasilkan pola. Ekspansi parameter kemudian akan menghasilkan parameter , dengan bagian terkecil dari awalan yang cocok dengan pola dihapus. Jika ada, kata tidak akan dimulai dengan tanda kutip #.

Hal yang sama berlaku untuk %(suffix). @dan *bukan pengubah ekspansi parameter, jadi itu adalah kesalahan. Itu akan terjadi untuk $?, $-atau hipotetis sebuah $=juga. ${$+}adalah ekspansi kosong.

Michael Homer
sumber
Saya seharusnya sudah mengenali substitusi parameter segera di sana. Tangkapan yang bagus.
Sergiy Kolodyazhnyy