シェルの有効な関数名の文字


13

拡張Unicode文字を使用すると、多くのユーザーにとって便利です(疑いの余地はありません)。

単純なシェル(ash(busybox)、dash)およびkshは次のように失敗します:

tést() { echo 34; }

tést

しかし、、およびはそれを許可しているようです。

POSIXの有効な関数名はこのNamesの定義を使用することを認識しています。つまり、この正規表現:

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

ただし、最初のリンクでは次のようにも言われています。

実装では、関数名に他の文字を拡張として使用できます。

質問は次のとおりです。

  • これは受け入れられ、文書化されていますか?
  • どこ?
  • どのシェル用か(もしあれば)?

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

「-」
含むUpstartおよびbashの関数名演算子(減算「-」)が名前の一部であるべきだとは思わない。


alias少し寛大に感じるかもしれません。そのため、適切なボタンダウンされた名前で関数を記述し、よりスタイリッシュな名前のエイリアスを定義して関数を呼び出すことができます。また、dashでできることも$PATHあり%funcます。
mikeserv

回答:


16

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

ことを示しbashzshyashksh93ksh私のシステムににリンクされている)、pdkshおよびその派生は、関数名として文字をマルチバイト許します。

yash マルチバイト文字をサポートするように設計されています、最初から、機能することは驚くことではありません。

参照できる他のドキュメントはksh93次のとおりです。

空白はタブまたはスペースです。識別子は、文字またはアンダースコアで始まる文字、数字、またはアンダースコアのシーケンスです。識別子は変数名のコンポーネントとして使用されます。vnameは、で区切られた1つ以上の識別子のシーケンスです。オプションで..が前に付きます。Vnamesは関数名と変数名として使用されます。単語とは、現在のロケール定義されている文字セットの文字のシーケンスで、引用符で囲まれていないメタ文字は除きます

Cロケールへの設定:

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

失敗させます。


poshそのようなリストに記載する価値はありません。Linux固有のバグに依存してlibcおり、他のプラットフォームでは動作しません。
気味悪い

ksh93オリジナルのソースから自己コンパイルされたksh93を使用することについてあなたの主張を繰り返すことはできません。一方でksh88、関数名の非7ビットASCII文字を受け入れるように思われる、唯一ksh93のUbuntuからのバイナリは、それらを受け入れているようです。
気味悪い

このテストで使用した@schily kshはDebianのバイナリです(Ubuntuのバイナリと同じである可能性があります)
-cuonglm

9

関数は、ファイルシステムのコマンドを含む他のコマンドと同じ名前空間を共有することに注意してください。ほとんどのシステムでは、パスに含まれる文字やバイトに制限はありません。

そのため、ほとんどのシェルでは機能の文字が制限されていますが、そうする理由はありません。つまり、これらのシェルには、関数で置き換えることができないコマンドがあります。

zshまたrc、with /や空の文字列を含む関数名には何でも許可します。zshNULバイトも許可します。

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

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

セキュリティ上の問題は、機能として、ここではありませんあなた(スクリプト作成者が)なもので定義するあなたが起動します。

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


一つは始まる、あまりにもbashでゲームをプレイしてもよいfunction /bin/sh { echo "$0: $FUNCNAME: Permission denied"; return 126; }し、潜在的に有用なものをあまりにも名前の関数で--//@または%など
mr.spuratic

しかし、dont shellsは/、名前で見つかったときにハッシュテーブル検索をバイパスする傾向がありますか?そして、関数は単なる実行可能な名前ではなく、そのコードです。格納された関数名にメタキャラクターが含まれている場合、単純な実装では多くの解析問題が発生する可能性があると思います。
mikeserv

はい、bashが変数にnullを含むことができないことを知っています。nullは関数名に合理的に拡張できます。具体的な例はありませんが、名前にほとんど何でも許可するこのゲームは、「簡単な働き方」というよりも潜在的なセキュリティ違反だと感じています。私が間違っていることを願っています。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.