9

このスクリプトは、括弧付きのbash関数と中括弧付きのbash関数の定義を示しています。括弧は、関数本体がサブシェルとして実行されるため、関数「ローカル」で作成された環境変数を作成するという優れた効果があります。出力は次のとおりです。

A=something
A=
B=something
B=something

問題は、これが関数を定義するための構文として許可されているかどうかです。

#!/bin/bash

foo() (
    export A=something
    echo A=$A
)

bar() {
    export B=something
    echo B=$B
}

foo
echo A=$A
bar
echo B=$B
4

2 に答える 2

11

はい、その構文は許可されています。bashman ページで説明されているように、bash 関数の定義は次のとおりです。

[ function ] name () compound-command [redirection]

いくつかの詳細な説明(これもmanページから):

関数の本体は複合コマンドcompound-commandです。そのコマンドは、通常、{との間のコマンドのリストですが、上記の複合コマンド}にリストされている任意のコマンドである場合があります。

(){}囲まれたリストは複合コマンドです。完全なリスト (これも man ページから、単純なリストに編集しただけです):

複合コマンドは、次のいずれかです。

(list)
{ list; }
((expression))
[[expression]]
for name [ in word ] ; do list ; done
for (( expr1 ; expr2 ; expr3 )) ; do list ; done
select name [ in word ] ; do list ; done
case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
if list; then list; [ elif list; then list; ] ... [ else list; ] fi
while list; do list; done
until list; do list; done
于 2013-02-01T17:44:13.807 に答える
4

どちらも有効で、Carl が述べたように、任意の複合コマンドも使用できます。

$ f() if [ "$1" = 'a' ]; then echo 'equals a'; fi
$ f a
equals a
$ f b
$

POSIX 7 2.9.5 関数定義コマンド http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_05 :

関数定義コマンドのフォーマットは次のとおりです。

fname() 複合コマンド[io-redirect ...]

[...] 引数 Compound-command は、複合コマンドで説明されているように、複合コマンドを表します。

次に、2.9.4 複合コマンド http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04 :

(複合リスト) [...] 環境に影響を与える変数の割り当てと組み込みコマンドは、リストが終了した後も有効ではありません。

{複合リスト;} 現在のプロセス環境で複合リストを実行します。

セマンティクスは、関数定義なしで使用する場合と同じ()です。新しいプロセスは作成されませんが、POSIX と Bash が「サブシェル環境」と呼ぶもので実行されます。

于 2015-07-09T11:11:36.363 に答える