1

私は、次のような行を使用して、変数が null 以外の値を持っている (またはメッセージを表示して保釈する) ことをテストすることに慣れています。

test $variable || (echo "Value of \$variable cannot be null."; exit 1)

スクリプトで関数を使用するのは初めてですが、null 以外の値が渡されていることを確認する必要があるか、関数から抜け出す必要がある場合があります。ただし、「または」の場合のコマンドのグループ化は、関数内で同じように機能していません。実証するために、この小さなテスト スクリプトを作成しました。

 $ cat -n bubu.sh
 1  #!/bin/bash
 2
 3  read -p "give a value for variable \$foo: " -e -i "bar" foo
 4
 5  function firstfunc {
 6          test $1 || (echo "no value"; return 1)
 7          echo it looks like \"$1\" is  the first value of \$foo
 8          return 0
 9  }
10
11  function secondfunc {
12          test $1 || return 1
13          echo it looks like \"$1\" is the second value of \$foo
14          return 0
15  }
16  echo "first function:"
17  firstfunc $foo
18  echo returned $?
19
20  echo "second function:"
21  secondfunc $foo
22  echo returned $?

変数に値がある場合の出力は次のようになります。

$ ./bubu.sh
give a value for variable $foo: bar
first function:
it looks like "bar" is the first value of $foo
returned 0
second function:
it looks like "bar" is the second value of $foo
returned 0

そして、値がない場合の出力

$ ./bubu.sh
give a value for variable $foo:
first function:
no value
it looks like "" is the first value of $foo
returned 0
second function:
returned 1

値がない最初の関数では、「or」コマンド グループの最初のコマンドを取得し、「値なし」がエコーされますが、return コマンドが渡され、return までの残りの関数が実行されます。 .

関数内でコマンドのグループ化の括弧が異なる動作をするのはなぜですか、または他に何が欠けていますか?

4

3 に答える 3

4

他の人が述べたように、括弧はサブシェルを作成し、 exit または return コマンドは bash にサブシェルから終了するように指示します。中括弧を使用する必要があります。より簡単な方法で同じ効果を得るために、bash パラメーター置換を使用できることに注意してください。下記参照。

あなたの行test $variable || (echo "Value of \$variable cannot be null."; exit 1)は、関数のコンテキストの「外側」でも機能しないはずです。例えば:

$ cat t.sh 
#!/bin/bash

a="hello"
test $a || (echo "Value of \$variable cannot be null."; exit 1)
echo First test passed

a=
test $a || (echo "Value of \$variable cannot be null."; exit 1)
echo Second test passed

与えます:

$ ./t.sh 
First test passed
Value of $variable cannot be null.
Second test passed
$ 

echo実行されるべきではないにもかかわらず、2 番目が実行されていることがわかります。中括弧を使用する方法です。

$ cat t.sh 
#!/bin/bash

a="hello"
test $a || { echo "Value of \$variable cannot be null."; exit 1 ; }
echo First test passed

a=
test $a || { echo "Value of \$variable cannot be null."; exit 1 ; }
echo Second test passed
$ ./t.sh 
First test passed
Value of $variable cannot be null.
$

${parameter:?err_msg}パラメータ置換に bash 構造を使用できることに注意してください。

$ cat t.sh 
#!/bin/bash

a="hello"
: ${a:?'a is null or undefined! Exiting..'}
echo First test passed

a=
: ${a:?'a is null or undefined! Exiting..'}
echo Second test passed

$ ./t.sh 
First test passed
./t.sh: line 9: a: a is null or undefined! Exiting..
$
于 2013-10-31T22:16:07.117 に答える
1

()aroundは、echo "no value"; return 1これらのコマンドをサブシェルで実行します。はreturn、関数から完全にではなく、サブシェルからあなたを返すだけです。代わりに使用{}して、サブシェルなしでコマンドのグループ化を実現できます。また、終了前にreturna が続くことを確認してください:;}

 6          test $1 || { echo "no value"; return 1; }

詳細については、Bash マニュアル コマンドのグループ化セクションを参照してください。

于 2013-10-31T21:26:17.067 に答える
1

括弧内のreturnと はexit、リストを実行したシェルではなく、括弧によって作成されたサブシェルを終了させ... || ...ます。{...}代わりに使用したい。

function firstfunc {
    test $1 || { echo "no value"; return 1; }
    echo it looks like \"$1\" is  the first value of \$foo
    return 0
}

中括弧は括弧よりも少し扱いに​​くいことに注意してください。最後のコマンドの後にはセミコロンを付ける必要があり、中括弧と周囲の文字をスペースで区切る必要があります。

于 2013-10-31T21:26:23.737 に答える