はい

はい

ファイルに特定のデータが含まれていることを確認するために関数を呼び出すことができるbashスクリプトが必要です。そうしないと、基本スクリプトは失敗します。これはこれを維持するために単純化された以下のようになります。

これは機能しません(サブシェルが失敗した場合、デフォルトのスクリプトは終了しません)。

require_line以下のように1つのファイルに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"
}

ベストアンサー1

サブシェルを終了しても経験したように、デフォルトのスクリプトは終了しません。

私は3つの(半分)解決策を考えました。

  1. (「テストされていません」)失敗したコマンド(またはサブシェル)がデフォルトのスクリプトをすぐに終了するようにするには、これを使用しますset -e(過度または他の問題を引き起こす可能性があります)。
  2. 関数から信号を送るtrap
  3. || exit $?毎回使うたびにVALUEn=$(...)こんな感じですよVALUE=$(require_line "myKey") || exit $?
  4. .を使用して(3.)を(あまりエレガントな)ループと組み合わせますeval

3番目は正確に「それぞれの周りにifが必要」ではなく、まだ非常にコンパクトな構文IMHOです。


ちなみに、この行

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

おすすめ記事