以下のサンプルスクリプトに関するいくつかの質問があります。
関数を呼び出し_foo
てその出力を変数としてキャプチャしたいのですが、戻り状態(ORではない可能性があります$bar
)を使用するか、失敗した場合(0以外の場合)スクリプトを停止しようとしています。0
1
exit
- このように呼び出すとin関数が機能しないのはなぜですか
exit
?_foo
(if ! bar="$(_foo)"
)。 「normal」が呼び出されると動作します。exit
ifステートメントを次のように変更すると(ただし出力が失われる)、スクリプトは停止します。if ! _foo ; then
- これはスクリプト
exit
のように動作し、停止しません。return
if ! bar="$(_foo)" ; then
- 割り当てと終了なしで関数を呼び出すだけで問題ありませんが、これを呼び出すわけでは
var="$(func)"
ありません。
_foo
関数でintoの出力をキャプチャし$bar
て戻り状態を使用するより良い方法はありますか(またはステートメント0
以外の場合は?)1
case
どういうわけか使用しなければならないような感じがしますtrap
。
簡単な例は次のとおりです。
#!/usr/bin/env bash
set -e
set -u
set -o pipefail
_foo() {
local _retval
echo "baz" && false
_retval=$?
exit ${_retval}
}
echo "start"
if ! bar="$(_foo)" ; then
echo "foo failed"
else
echo "foo passed"
fi
echo "${bar}"
echo "end"
出力は次のとおりです。
$ ./foo.sh
start
foo failed
baz
end
以下はいくつかの追加例です。
これで終了します。
#!/usr/bin/env bash
set -e
set -u
set -o pipefail
func() {
echo "func"
exit
}
var=''
func
echo "var is ${var}"
echo "did not exit"
終了しません。
#!/usr/bin/env bash
set -e
set -u
set -o pipefail
func() {
echo "func"
exit
}
var=''
var="$(func)"
echo "var is ${var}"
echo "did not exit"
答え1
exit
関数だけでなく、関数内でスクリプト全体を終了します(サブシェルにもかかわらず)。おとぎ話:
#!/bin/bash
f() {
exit 3
}
f
exit 0
上記のスクリプトは終了コード3で終了します。
#!/bin/bash
f() {
exit 3
}
(f)
exit 0
終了コード 0 で終了します。
$(command)
使用中の構文はサブシェル内で実行され、サブシェルがcommand
実行exit
されているレベルからのみ外れることがあります。以内に。
サブシェルで実行されている項目の終了コードと出力をキャプチャしたい場合は、サブシェルが開始された環境で引き続き使用できます。
#!/bin/bash
subshelloutput="$( echo "output"; exit 3 )"
returnval=$? # captures subshell's exit code
: more stuff follows
答え2
他の方法でも行うことができます。
_foo ()
{
local _retval
declare -n output="$1" # $output is local (by default with declare in a func.)
## and points to $1
output="baz" && false
_retval=$?
echo ${_retval} # change echo to exit
}
それでは_foo
、次のように呼び出します。
$ _foo bar
1
$ echo "$bar"
baz
関数定義からに変更すると、echo
スクリプトは終了します。exit
exit