Shell ký tự tên hàm hợp lệ


13

Sử dụng các ký tự Unicode mở rộng là (không nghi ngờ gì) hữu ích cho nhiều người dùng.

Các vỏ đơn giản hơn (tro (busybox), dash) và ksh không thành công với:

tést() { echo 34; }

tést

Nhưng , , dường như cho phép nó.

Tôi biết rằng POSIX tên hàm hợp lệ sử dụng định nghĩa Tên này . Điều đó có nghĩa là regex này:

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

Tuy nhiên, trong liên kết đầu tiên, nó cũng được nói:

Việc triển khai có thể cho phép các ký tự khác trong tên hàm dưới dạng phần mở rộng.

Các câu hỏi là:

  • Điều này có được chấp nhận và ghi nhận?
  • Ở đâu?
  • Cho vỏ nào (nếu có)?

Câu hỏi liên quan:
Có thể sử dụng các ký tự đặc biệt trong tên hàm shell?
Tôi không quan tâm đến việc sử dụng các ký tự meta (>) trong tên hàm.

Các tên hàm khởi động và bash có chứa Tên - Hồi
Tôi không tin rằng một toán tử (phép trừ "-") phải là một phần của tên.


bạn có thể thấy aliaslà một chút khoan dung hơn. và vì vậy bạn có thể viết hàm với một tên thích hợp, có nút bấm, và sau đó chỉ cần xác định một bí danh có tên sành điệu hơn để gọi hàm. trong dashđó cũng có một số thứ bạn có thể làm với $PATH%func.
mikeerv

Câu trả lời:


16

Vì tài liệu POSIX cho phép nó như một phần mở rộng, không có gì ngăn cản việc thực hiện từ hành vi đó.

Một kiểm tra đơn giản (chạy trong 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

cho thấy bash, zsh, yash, ksh93(trong đó kshliên quan đến trong hệ thống của tôi), pdkshvà nguồn gốc của nó cho phép đa byte ký tự như tên hàm.

yash được thiết kế để hỗ trợ các nhân vật đa nhân ngay từ đầu, vì vậy không có gì ngạc nhiên khi nó hoạt động.

Các tài liệu khác bạn có thể tham khảo là ksh93:

Một khoảng trống là một tab hoặc một khoảng trắng. Mã định danh là một chuỗi các chữ cái, chữ số hoặc dấu gạch dưới bắt đầu bằng một chữ cái hoặc dấu gạch dưới. Mã định danh được sử dụng như các thành phần của tên biến. Vname là một chuỗi gồm một hoặc nhiều mã định danh được phân tách bằng a. và tùy ý đi trước bởi một .. Tên được sử dụng làm tên hàm và tên biến. Một từ là một chuỗi các ký tự từ bộ ký tự được xác định bởi miền địa phương hiện tại , ngoại trừ các siêu ký tự không được trích dẫn.

Vì vậy, thiết lập để định vị C:

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

làm cho nó thất bại


poshkhông có giá trị để được liệt kê trong một danh sách như vậy. Nó phụ thuộc vào các lỗi cụ thể của Linux trong libcvà sẽ không hoạt động trên các nền tảng khác.
schily

Tôi không thể lặp lại tuyên bố của bạn về việc ksh93sử dụng ksh93 tự biên dịch từ các nguồn ban đầu. Mặc dù ksh88dường như chấp nhận các chữ cái không phải 7-Bit-ASCII cho tên hàm, nhưng chỉ có ksh93nhị phân từ Ubuntu dường như chấp nhận chúng.
schily

@schily ksh Tôi đã sử dụng trong thử nghiệm này là tệp nhị phân trong Debian (vì vậy nó có thể giống với một cái trên Ubuntu)
cuonglm

9

Lưu ý rằng các hàm chia sẻ cùng một không gian tên như các lệnh khác bao gồm các lệnh trong hệ thống tệp, mà trên hầu hết các hệ thống không có giới hạn về các ký tự hoặc thậm chí byte mà chúng có thể chứa trong đường dẫn của chúng.

Vì vậy, trong khi hầu hết các shell giới hạn các ký tự của chức năng của chúng, không có lý do thực sự tốt tại sao chúng sẽ làm điều đó. Điều đó có nghĩa là trong các shell đó, có các lệnh bạn không thể thay thế bằng một hàm.

zshrccho phép bất cứ điều gì cho tên hàm của chúng bao gồm một số với /và chuỗi rỗng. zshthậm chí cho phép NUL byte.

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

Một lệnh đơn giản trong shell là một danh sách các đối số và đối số đầu tiên được sử dụng để lấy lệnh để thực thi. Vì vậy, thật hợp lý khi các đối số và tên hàm chia sẻ cùng các giá trị có thể và trong các zshđối số cho các hàm và hàm có thể là bất kỳ chuỗi byte nào.

Không có vấn đề bảo mật ở đây vì các chức năng bạn (tác giả kịch bản) xác định là các chức năng bạn gọi.

Trường hợp có thể có vấn đề bảo mật là khi phân tích cú pháp bị ảnh hưởng bởi môi trường, ví dụ với các shell trong đó tên hợp lệ cho các chức năng bị ảnh hưởng bởi miền địa phương.


Người ta có thể chơi trò chơi trong bash quá, bắt đầu với function /bin/sh { echo "$0: $FUNCNAME: Permission denied"; return 126; }, và có khả năng điều hữu ích quá với các chức năng được đặt tên --, //, @hoặc %, vv
mr.spuratic

nhưng không shell có xu hướng bỏ qua một tra cứu bảng băm khi /được tìm thấy trong một tên? và một chức năng không chỉ là một tên thực thi - mã của nó. tôi sẽ nghĩ rằng một triển khai đơn giản có thể gặp phải nhiều vấn đề phân tích nếu tên hàm được lưu trữ của nó bao gồm các siêu ký tự.
mikeerv

Có, tôi nhận thấy sự bất lực của bash khi chứa null trong các vars, có thể được mở rộng hợp lý thành các tên hàm. Tôi không có một ví dụ cụ thể, nhưng tôi cảm thấy rằng các trò chơi cho phép hầu hết mọi thứ cho tên này có nhiều khả năng vi phạm an ninh hơn là "cách dễ dàng để làm việc". Tôi hy vọng tôi sai.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.