シェル有効な関数名文字

シェル有効な関数名文字

拡張Unicode文字を使用することは、間違いなく多くのユーザーに役立ちます。

より単純なシェル(ash(busybox)、ダッシュ)とkshは失敗します。

tést() { echo 34; }

tést

しかし、許可するようです。

私はPOSIXを知っています有効な関数名この定義を使用してください名前。これは次の正規表現を意味します。

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

ただし、最初のリンクには次のようなものもあります。

実装では、関数名に拡張子として追加の文字を許可できます(MAY)。

問題は次のとおりです。

  • これは承認され文書化されましたか?
  • どこ?
  • どのシェルに適用されますか?

関連質問:
シェル関数名に特殊文字を使用できますか?
関数名にメタ文字(>)を使用することに興味はありません。

Upstart および bash 関数名には「-」が含まれます。
私は演算子(マイナス "-")が名前の一部でなければならないとは思いません。

答え1

POSIX ドキュメントではこれを拡張として許可するので、この動作が実装されるのを防ぐ方法はありません。

簡単な確認(で実行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

bash、、、(私のシステムに接続されている)とその派生語がマルチバイト文字を関数名として受け入れることを示しますzshyashksh93kshpdksh

yash マルチバイト文字をサポートするように設計されています最初からやったので、その成功は驚くべきことではありません。

参照できるその他の文書は次のとおりですksh93

スペースはタブまたはスペースです。識別子は、文字または下線で始まる一連の文字、数字、または下線です。識別子は変数名の一部として使用されます。 vnameは、で区切られた1つ以上の識別子シーケンスです。オプションで . が前に付けられます。 Vname は関数名と変数名として使用されます。言葉は一連の文字です。現在のロケールによって定義された文字セット、引用符で囲まれていないメタ文字は除外されます。

したがって、Cロケールに設定します。

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

失敗させてください。

答え2

関数は他のコマンド(ファイルシステムのコマンドを含む)と同じ名前空間を共有し、ほとんどのシステムではそのパスに存在できる文字やバイトに制限はありません。

したがって、ほとんどのシェルは機能の特性を制限しますが、実際にはそうするのに十分な理由はありません。これは、これらのシェルで一部のコマンドを関数に置き換えることができないことを意味します。

zshrc関数名にいくつかの文字列と/空の文字列を含め、何でも含めることができます。zshNULバイトも許可されます。

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

シェルの単純なコマンドは引数のリストで、最初の引数は実行するコマンドを派生させるために使用されます。したがって、これらのパラメータと関数名は同じ値を共有し、zsh組み込み関数と関数のパラメータは任意のバイトシーケンスである可能性があることが論理的です。

ここの機能にはセキュリティ上の問題はありません。あなた(スクリプト作成者)はこれを定義します。あなた移動する。

解析が環境の影響を受けると、セキュリティ上の問題が発生する可能性があります。たとえば、シェルでは、関数の有効な名前はロケールの影響を受けます。

関連情報