Bash
bash:使用子shell分配給變數,但如果分配失敗則退出主腳本
我想要一個 bash 腳本,它允許我呼叫一個函式來查看文件中是否包含某些數據,如果它沒有使主腳本失敗,類似於以下內容,簡化為保留這一點。
這不起作用(當子 shell 失敗時不退出主腳本)。
我該如何編寫
require_line
函式,這樣我就可以像這樣在一個文件中說出其中的 20 多個VALUE1=$(require_line "myKey1") VALUE2=$(require_line "myKey2") ...
並且不需要一個 if 圍繞每個?
#!/bin/bash set -eo pipefail VALUE=$(require_line "myKey") require_line(){ local KEY=$1 local DATA=$(cat /tmp/myfile) local INFO=$(echo "$DATA" | grep "$KEY") if [ ! -z "$INFO" ] then echo "Key not found in $DATA, key: $KEY" exit 1; fi echo "$INFO" }
退出 subshell 不會像您經歷的那樣退出主腳本。
我想到了 3 個(半個)解決方案:
- 使用
set -e
這樣任何(“未經測試”)失敗的命令(或子shell)將立即退出主腳本(這可能是矯枉過正或導致其他麻煩),- 從函式發送信號並用
trap
|| exit $?
每次VALUEn=$(...)
像這樣使用VALUE=$(require_line "myKey") || exit $?
,- 使用 .將 (3.) 與(不那麼優雅的)循環結合起來
eval
。第三個並不完全“需要一個 if 圍繞每個”,並且仍然是一個相當緊湊的語法恕我直言。
順便說一句,這條線
echo "Key not found in $DATA, key: $KEY"
…如果您在此之後立即退出整個腳本,實際上是無用的,因為該句子將儲存在
$VALUEn
不會顯示的變數中。我建議列印成
stderr
這樣:echo "my error" 1>&2
例子
解決方案 1 的範例
#!/bin/sh set -e myfunc(){ echo $1 if [ "$1" != "OK" ] ; then exit 1 ; fi } VALUE1=$(myfunc "OK") echo $VALUE1 VALUE2=$(myfunc "NO WAY") echo $VALUE2 echo "main script did not exit"
$ ./test.sh OK zsh: exit 1 ./test.sh
但是,如果我
set -e
從一開始就刪除,我會得到:$ ./test.sh OK NO WAY main script did not exit
解決方案 2 的範例
#!/bin/sh trap "exit $?" USR1 myfunc(){ echo $1 if [ "$1" != "OK" ] ; then kill -USR1 $$ ; fi } VALUE1=$(myfunc "OK") echo $VALUE1 VALUE2=$(myfunc "NO WAY") echo $VALUE2 echo "main script did not exit"
$ ./test.sh OK
解決方案 3 的範例
#!/bin/sh myfunc(){ echo $1 if [ "$1" != "OK" ] ; then exit 1 ; fi } VALUE1=$(myfunc "OK") || exit $? echo $VALUE1 VALUE2=$(myfunc "NO WAY") || exit $? echo $VALUE2 echo "main script did not exit"
$ ./test.sh OK zsh: exit 1 ./test.sh
解決方案 4 的範例
#!/bin/sh myfunc(){ echo $1 if [ "$1" != "OK" ] ; then exit 1 ; fi } I=1 for key in "OK" "OK" "NO WAY": ; do eval "VALUE$I=\$(myfunc \"$key\")" || exit $? eval "echo \$VALUE$I" I=$(($I+1)) done echo "main script did not exit"
$ ./test.sh OK OK zsh: exit 1 ./test.sh