Karakter nama fungsi shell valid

13

Menggunakan karakter Unicode yang diperluas (tidak diragukan) bermanfaat bagi banyak pengguna.

Kerang yang lebih sederhana (abu (busybox), tanda hubung) dan ksh gagal dengan:

tést() { echo 34; }

tést

Tapi , , , dan tampaknya memungkinkan.

Saya sadar bahwa nama fungsi POSIX yang valid menggunakan definisi Nama - nama ini . Itu berarti regex ini:

[a-zA-Z_][a-zA-Z0-9_]*

Namun, pada tautan pertama dikatakan juga:

Implementasi dapat memungkinkan karakter lain dalam nama fungsi sebagai ekstensi.

Pertanyaannya adalah:

  • Apakah ini diterima dan didokumentasikan?
  • Dimana?
  • Untuk cangkang mana (jika ada)?

Pertanyaan terkait: Apakah
mungkin menggunakan karakter khusus dalam nama fungsi shell?
Saya tidak tertarik menggunakan meta-karakter (>) dalam nama fungsi.

Nama fungsi pemula dan bash yang mengandung "-"
Saya tidak percaya bahwa operator (pengurangan "-") harus menjadi bagian dari nama.

Komunitas
sumber
Anda mungkin merasa aliassedikit lebih toleran. dan jadi Anda dapat menulis fungsi dengan nama yang tepat, tombol-down, dan kemudian hanya mendefinisikan alias lebih bergaya bernama untuk memanggil fungsi. di dashsana juga ada beberapa hal yang dapat Anda lakukan dengan $PATHdan %func.
mikeserv

Jawaban:

16

Karena dokumentasi POSIX memungkinkannya sebagai ekstensi, tidak ada yang mencegah implementasi dari perilaku itu.

Pemeriksaan sederhana (ran zsh):

$ for shell in /bin/*sh 'busybox sh'; do
    printf '[%s]\n' $shell
    $=shell -c 'á() { :; }'
  done
[/bin/ash]
/bin/ash: 1: Syntax error: Bad function name
[/bin/bash]
[/bin/dash]
/bin/dash: 1: Syntax error: Bad function name
[/bin/ksh]
[/bin/lksh]
[/bin/mksh]
[/bin/pdksh]
[/bin/posh]
/bin/posh: á: invalid function name
[/bin/yash]
[/bin/zsh]
[busybox sh]
sh: syntax error: bad function name

menunjukkan bahwa bash, zsh, yash, ksh93(yang kshterhubung ke dalam sistem saya),pdksh dan derivasi yang memungkinkan multi-byte karakter sebagai nama fungsi.

yash dirancang untuk mendukung karakter multibyte sejak awal, jadi tidak ada kejutan itu berhasil.

Dokumentasi lain yang dapat Anda rujuk adalah ksh93 :

Kosong adalah tab atau spasi. Identifier adalah urutan huruf, angka, atau garis bawah yang dimulai dengan huruf atau garis bawah. Pengidentifikasi digunakan sebagai komponen nama variabel. Vname adalah urutan satu atau lebih pengidentifikasi yang dipisahkan oleh a. dan secara opsional didahului oleh .. Vnames digunakan sebagai nama fungsi dan variabel. Kata adalah urutan karakter dari set karakter yang ditentukan oleh lokal saat ini , tidak termasuk tidak dikutip.

Jadi pengaturan ke Clokal:

$ export LC_ALL=C
$ á() { echo 1; }
ksh: á: invalid function name

buat itu gagal.

cuonglm
sumber
poshtidak layak untuk dicantumkan dalam daftar seperti itu. Itu tergantung pada bug khusus Linux di libcdan tidak akan bekerja pada platform lain.
schily
Saya tidak dapat mengulangi klaim Anda tentang ksh93penggunaan ksh93 yang dikompilasi sendiri dari sumber asli. Meskipun ksh88tampaknya menerima huruf non-7-Bit-ASCII untuk nama fungsi, hanya ksh93biner dari Ubuntu yang menerimanya.
schily
@schily ksh yang saya gunakan dalam tes ini adalah biner di Debian (jadi mungkin sama dengan yang ada di Ubuntu)
cuonglm
9

Perhatikan bahwa fungsi berbagi namespace yang sama dengan perintah lain termasuk perintah dalam sistem file, yang pada kebanyakan sistem tidak memiliki batasan pada karakter atau bahkan byte yang mungkin ada di jalurnya.

Jadi, sementara sebagian besar shell membatasi karakter fungsi mereka, tidak ada alasan nyata mengapa mereka melakukan itu. Itu berarti di shells itu, ada perintah yang tidak bisa Anda ganti dengan fungsi.

zshdan rcmengizinkan apa pun untuk nama fungsi mereka termasuk beberapa dengan /dan string kosong. zshbahkan memungkinkan byte NUL.

$ zsh
$ $'\0'() echo nul
$ ^@
nul
$ ""() uname
$ ''
Linux
$ /bin/ls() echo test
$ /bin/ls
test

Perintah sederhana di shell adalah daftar argumen, dan argumen pertama digunakan untuk menurunkan perintah untuk dieksekusi. Jadi, logis bahwa argumen dan nama fungsi tersebut berbagi nilai yang mungkin sama dan dalam zshargumen untuk builtin dan fungsi dapat berupa urutan byte apa pun.

Tidak ada masalah keamanan di sini karena fungsi yang Anda (penulis skrip) tetapkan adalah yang Anda panggil.

Di mana mungkin ada masalah keamanan adalah ketika parsing dipengaruhi oleh lingkungan, misalnya dengan shell di mana nama yang valid untuk fungsi dipengaruhi oleh lokal.

Stéphane Chazelas
sumber
Seseorang dapat bermain game di bash juga, dimulai dengan function /bin/sh { echo "$0: $FUNCNAME: Permission denied"; return 126; }, dan hal-hal yang berpotensi bermanfaat juga dengan fungsi yang dinamai --,// , @atau %dll
mr.spuratic
tapi jangan kerang cenderung memotong pencarian tabel hash ketika /ditemukan dalam sebuah nama? dan fungsi bukan hanya nama yang dapat dieksekusi - kodenya. saya akan berpikir implementasi sederhana bisa menghadapi banyak masalah parse jika nama fungsi yang tersimpan termasuk metacharacters.
mikeserv
Ya, saya menyadari ketidakmampuan bash untuk mengandung null di vars, yang bisa diperluas ke nama fungsi. Saya tidak memiliki contoh spesifik, tetapi saya merasa bahwa permainan ini memungkinkan hampir semua hal untuk nama lebih merupakan pelanggaran keamanan potensial daripada "cara mudah untuk bekerja". Saya harap saya salah.