Pertimbangkan yang berikut ini:
$ ksh -c '1(){ echo hi;};1'
ksh: 1: invalid function name
$ dash -c '1(){ echo hi;};1'
dash: 1: Syntax error: Bad function name
$ bash -c '1(){ echo hi;};1'
bash: `1': not a valid identifier
bash: 1: command not found
$ mksh -c '1(){ echo hi;};1'
hi
Pada dasarnya, saya mencoba untuk mendeklarasikan fungsi 1
dan 0
yang akan menjadi singkatan untuk true
dan false
, tetapi seperti yang Anda lihat saya mengalami masalah dengan menggunakan nama numerik dalam fungsi. Perilaku yang sama terjadi dengan alias dan nama dua digit.
Pertanyaannya adalah "mengapa"? Apakah itu diamanatkan oleh POSIX? atau hanya kekhasan cangkang mirip bourne?
Lihat juga pertanyaan terkait dengan yang ini.
command-line
bash
dash-shell
ksh
Sergiy Kolodyazhnyy
sumber
sumber
0
adalahtrue
di scripting shell dan1
adalahfalse
(benar-benar, setiap non-nol diperlakukan sebagai palsu), dalam kasus orang membaca ini tidak menyadari. Ini mundur dari sebagian besar bahasa pemrograman lainnya.true
dalam shell. Namun, dalam ekspansi aritmatika,$((...))
status pengembalian dibalik - 1 adalahtrue
dan 0false
untuk konsistensi dengan sintaks C-language. Coba misalnyabash -c 'echo $((1==1));echo $((1==2))'
Apa yang saya coba lakukan di luar pertanyaan ini sebenarnya "membalikkan" perilaku. Lihat contoh terakhir pada jawaban saya di sini untuk melihat apa sebenarnya yang saya coba lakukan. Gagasan konyol, tapi tetap berhasilJawaban:
POSIX mengatakan:
Dan:
Jadi kata yang dimulai dengan digit tidak boleh berupa nama fungsi.
sumber
1L
artinya? Nama fungsi? Ataulong int
literal?()
, mungkin dengan argumen di dalamnya, yang menunjukkan panggilan ke fungsi yang bersangkutan (dan mengambil nilai yang dikembalikan oleh fungsi yang dipanggil). Jadi jika Anda memiliki fungsiint f() { return 42; }
dalam C,f
valid dalam konteks pointer, danf()
valid dalam konteks integer non-pointer.Itu adalah standar dalam banyak bahasa untuk mencegah kebingungan antara operasi matematika dan variabel atau fungsi atau metode.
Mempertimbangkan:
Seperti yang Anda lihat, jika angka dibolehkan sebagai nama variabel atau fungsi, mengerjakan matematika di kemudian hari dalam program mungkin akan sangat membingungkan dan Anda harus membuat solusi kreatif jika Anda perlu benar-benar melakukan matematika dengan angka-angka itu nanti. Itu juga dapat menghasilkan hasil yang tidak terduga dalam beberapa bahasa. Bayangkan Anda menambah angka untuk satu lingkaran tetapi salah satu digit sudah menjadi variabel yang menyamai string. Itu akan segera melempar kesalahan. Jika Anda bukan pembuat kode asli, kesalahan itu bisa memakan waktu cukup lama untuk ditemukan.
Singkatnya, inilah mengapa sebagian besar bahasa tidak memungkinkan Anda untuk menggunakan angka sebagai nama variabel atau fungsi atau metode atau lainnya.
sumber
$
untuk diperluas" tetapi sekali lagi jika shell terinspirasi oleh bahasa lain, tidak apa-apa saya kira, ditambah dalam((
variabel ekspansi aritmatika, variabel tidak diharuskan untuk memimpin$
. OK, saya bisa mengerti itu$
, jadi begitulah. Tapi itu mungkin sekunder untuk alasan lain "hanya mengikuti konvensi umum"0
untuk shell atau script nama,1
,2
, ..., untuk parameter posisi,*
bagi mereka bergabung,-
untuk pilihan diaktifkan,?
untuk status keluar terakhir, dan!
untuk PID pekerjaan asinkron terbaru. (Jadi, bahkan dalam$((
))
,$
sering diperlukan.) Kode yang ditunjukkan di sini untuk menunjukkan alasan yang disarankan bukanlah skrip untuk shell gaya Bourne, karena tidak ada cara untuk menunjukkannya seperti itu, karena tidak berlaku untuk mereka.Dalam C, pertimbangkan ungkapan seperti:
Apakah
1000l
variabel atau konstanta? Karena nama variabel tidak dapat dimulai dengan angka, itu harus berupa konstanta. Ini membuat penguraian lebih mudah dan lebih ketat (kesalahan ketik seperti1000k
dapat dengan mudah ditangkap). Lebih mudah memiliki aturan tunggal untuk variabel dan nama fungsi, karena fungsi juga dapat diperlakukan sebagai variabel. Sekarang tentu saja, parser jauh lebih kompleks dan kuat, dan kami memiliki hal-hal seperti literal khusus di C ++. Namun di masa prasejarah kuno, mengorbankan sedikit fleksibilitas yang tidak perlu bisa membuat kompilasi Anda (atau interpretasi) kali lebih singkat (dan orang-orang masih mengeluh tentang waktu kompilasi C ++).Dan Anda dapat melihat efek dari pengaruh C di seluruh bahasa shell, jadi tidak mengherankan bahwa shell Bourne (atau C shell) dan karenanya, POSIX, telah membatasi kelas nama yang diizinkan untuk sama dengan yang dari C.
sumber
&&
dan||
, kurangnya dukungan untuk string ASCII nul dalam string,