関数は次のように定義されます:
do_something () {
do it
}
名前「do_something」とアクションコードをカプセル化する中かっこは理解できましたが、()
Bashスクリプトには名前付きパラメーターがないため、ここでの目的はわかりません。次のように定義する方が良い場合があります。
do_something {
do it
}
これは現在の構文と競合せず、名前付きパラメーターがないことをさらに宣言します。()
ここの使い方は何ですか?
関数は次のように定義されます:
do_something () {
do it
}
名前「do_something」とアクションコードをカプセル化する中かっこは理解できましたが、()
Bashスクリプトには名前付きパラメーターがないため、ここでの目的はわかりません。次のように定義する方が良い場合があります。
do_something {
do it
}
これは現在の構文と競合せず、名前付きパラメーターがないことをさらに宣言します。()
ここの使い方は何ですか?
回答:
()
構文は本当にあいまいになります。そこにする必要があり、いくつかの機能を定義するための明確な構文、および、実質的に変更することなく、他のシェルの構文を、このことはできません。
do_something {
# one or more commands go here
}
あなたはこれを「現在の構文と混同しない」と言ったが、そうだ!最初の行を実行しようとしても、構文エラーは発生しません。エラーが発生しますが、構文に関するエラーではありません。のある2行目}
は構文エラーですが、1行目はそうではありません。代わりに、do_something {
というコマンドを実行し、そのコマンドへの引数としてdo_something
渡し{
ます:
$ do_something {
do_something: command not found
というコマンドが既にある場合はdo_something
、それを実行しています。呼び出された関数が既にある場合はdo_something
、それを呼び出しています。一般に、構文が明確であることは重要ですが、特に誤って関数を呼び出すことなく関数を再定義できることも重要です。関数の定義と呼び出しは同じように見えるべきではありません。
{
と(
。通りtype {
を教えてくれる、{
シェルキーワードです。これにより、次のようになり[[
ます。そうでなければコマンドになるような状況で使用される場合、{
特別なセマンティクスを持ちます。具体的には、コマンドのグループ化を実行します。ただし、他の状況では、エスケープせずにリテラル{
文字を示すために使用できます。これには、コマンドの2番目以降のワードとして渡す状況が含まれます。
もちろん、Bash は、{
現在とは異なる方法で処理するように設計されている可能性があります。ただし、その構文はPOSIXシェルと互換性がなくなり、Bashは実際にはBourneスタイルのシェルではなくなり、多くのシェルスクリプトを実行できなくなります。
対照的に(
、シェルのメタキャラクターです。それは、常にそれがコマンドで表示され、引用されていない場合は特別扱い(とされる'
'
、"
"
または\
)。したがって、構文にあいまいさはありません。
do_something() {
# one or more commands go here
}
それは他の何も意味することができませんでした。Bashに関数がなかった場合echo foo(bar)
、構文エラーになります。同じ理由で構文エラーになります。
()
表記が本当に嫌いな場合function
は、sudodusで言及されているように、キーワードを使用して省略できます。これは、他のほとんどのBourneスタイルのシェルで関数を定義するための構文の一部ではないことに注意してください(一部はサポートされていますが、そのように定義された関数は異なるセマンティクスを持っているため、それを使用するスクリプトは移植できません)。(この構文が明確にできる理由は、function
それ自体がBashのキーワードであり、それに続くものが関数定義の開始であることを意味するからです。)
最後に、ほとんどの関数定義{
は実際に使用されますが、複合コマンドは許可されます。本体を常にサブシェルで実行したい関数がある場合は、(
)
ではなくを使用できます{
}
。
()
トークンを使用すると、関数を宣言していることをシェルインタプリタを伝えることです。
$ do_something () { echo 'do it'; } ; do_something
do it
の代替bash
はfunction
function do_something {
echo 'do it'
}
または、ワンライナーとしてテストできます
$ bash -c "function do_something { echo 'do it'; } ; do_something"
do it
function
キーワードは、後方互換性のためのbashサポートしていることを事前にPOSIXのkshのイズムです。しかし、bashはそれをうまくサポートしていません(古いkshがその形式で宣言された関数で行ったように、変数を関数ローカルのデフォルトにしない)。したがって、新しいコードには理想的ではありません。参照してくださいwiki.bash-hackers.org/scripting/obsolete
まさに真のブレーススタイル-あなたの!
他の完全に細かいブレーススタイルを検討してください。
foo
{
...
}
foo
{
...
}
foo
while ...; do ...; done # Look, ma! No braces!
foo
( ... ) # Look, ma! No braces and a subshell to boot!
シェルは、それらが関数foo
リストであり、コマンドの後にコマンドリストが続くだけではないことをどのように判断できますか?これらのすべての場合において()
、function
キーワードまたはキーワードのような追加の曖昧さ回避要素が必要です。
()
か、それに似たものです。