bashスクリプトがmainを実行しない理由を理解していますか?

bashスクリプトがmainを実行しない理由を理解していますか?

クローンを実施した。ゼロコイン:

$ git clone https://github.com/zcash/zcash.git
$ cd zcash/
$ git checkout v1.0.1
$ ./zcutil/fetch-params.sh

走ろうとしています。fetch-params.shOS XとSolarisで。 Linuxスクリプトなので、いくつかのメッセージングが必要です。以下は直接的な違いです。変更を含む完全なスクリプトは質問の最後にあります。

diff --git a/zcutil/fetch-params.sh b/zcutil/fetch-params.sh
index ac5327b..e2e9807 100755
--- a/zcutil/fetch-params.sh
+++ b/zcutil/fetch-params.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash

 set -eu

@@ -12,6 +12,9 @@ SPROUT_VKEY_URL="https://z.cash/downloads/$SPROUT_VKEY_NAME"
 SHA256CMD="$(command -v sha256sum || echo shasum)"
 SHA256ARGS="$(command -v sha256sum >/dev/null || echo '-a 256')"

+IS_DARWIN=$(uname -s | grep -i -c darwin)
+IS_SOLARIS=$(uname -s | grep -i -c sunos)
+
 function fetch_params {
     local url="$1"
     local output="$2"
@@ -45,13 +48,20 @@ EOF

 # Use flock to prevent parallel execution.
 function lock() {
-    local lockfile=/tmp/fetch_params.lock
-    # create lock file
-    eval "exec 200>/$lockfile"
-    # acquire the lock
-    flock -n 200 \
-        && return 0 \
-        || return 1
+   local lockfile="/tmp/fetch_params.lock"
+    if [[ ("$IS_SOLARIS" -ne "0" || "$IS_DARWIN" -ne "0") ]]; then
+        # http://unix.stackexchange.com/a/13025
+        mkdir "$lockfile" \
+            && return 0 \
+            || return 1
+    else
+        # create lock file
+        eval "exec 200>/$lockfile"
+        # acquire the lock
+        flock -n 200 \
+           && return 0 \
+           || return 1
+    fi
 }

 function exit_locked_error {
@@ -105,5 +115,11 @@ EOF
 }

 main
-rm -f /tmp/fetch_params.lock
+
+if [[ ("$IS_SOLARIS" -ne "0" || "$IS_DARWIN" -ne "0") ]]; then
+    rm -rf /tmp/fetch_params.lock
+else
+    rm -f /tmp/fetch_params.lock
+fi
+
 exit 0

私が経験している問題はmain実行されていないということです。スクリプトは次の後に静かに終了しますIS_SOLARIS=$(uname -s | grep -i -c sunos)

riemann:zcash$  bash -x ./zcutil/fetch-params.sh 
+ set -eu
...
++ uname -s
++ grep -i -c darwin
+ IS_DARWIN=1
++ uname -s
++ grep -i -c sunos
+ IS_SOLARIS=0
riemann:zcash$ 

奇妙なことは... OS XとSolarisの両方でこれが起こるということです。 OS XでIS_SOLARIS=$(uname -s | grep -i -c sunos)変更を設定するとIS_SOLARIS=0機能します。またはコメントを付けるとうまくset -euいきます。使ったことがないset -eu以前は説明を聞きましたが、[可能な]失敗を理解していません。set -e を使用する必要がある場合

OS Xで利用可能で、GNU bash, version 3.2.53Solaris 11で利用可能ですGNU bash, version 4.1.17

私の無知を許してください...テストでスクリプトが死ぬIS_DARWINのはなぜですか?IS_SOLARISなぜメインが実行されないのですか?


完全に修正されたスクリプト

#!/usr/bin/env bash

set -eu

PARAMS_DIR="$HOME/.zcash-params"

SPROUT_PKEY_NAME='sprout-proving.key'
SPROUT_VKEY_NAME='sprout-verifying.key'
SPROUT_PKEY_URL="https://z.cash/downloads/$SPROUT_PKEY_NAME"
SPROUT_VKEY_URL="https://z.cash/downloads/$SPROUT_VKEY_NAME"

SHA256CMD="$(command -v sha256sum || echo shasum)"
SHA256ARGS="$(command -v sha256sum >/dev/null || echo '-a 256')"

IS_DARWIN=$(uname -s | grep -i -c darwin)
IS_SOLARIS=$(uname -s | grep -i -c sunos)

function fetch_params {
    local url="$1"
    local output="$2"
    local dlname="${output}.dl"
    local expectedhash="$3"

    if ! [ -f "$output" ]
    then
        echo "Retrieving: $url"
        wget \
            --progress=dot:giga \
            --output-document="$dlname" \
            --continue \
            --retry-connrefused --waitretry=3 --timeout=30 \
            "$url"

        "$SHA256CMD" $SHA256ARGS --check <<EOF
$expectedhash  $dlname
EOF

        # Check the exit code of the shasum command:
        CHECKSUM_RESULT=$?
        if [ $CHECKSUM_RESULT -eq 0 ]; then
            mv -v "$dlname" "$output"
        else
           echo "Failed to verify parameter checksums!"
           exit 1
        fi
    fi
}

# Use flock to prevent parallel execution.
function lock() {
    local lockfile="/tmp/fetch_params.lock"
    if [[ ("$IS_SOLARIS" -ne "0" || "$IS_DARWIN" -ne "0") ]]; then
        # http://unix.stackexchange.com/a/13025
        mkdir "$lockfile" \
            && return 0 \
            || return 1
    else
        # create lock file
        eval "exec 200>/$lockfile"
        # acquire the lock
        flock -n 200 \
           && return 0 \
           || return 1
    fi
}

function exit_locked_error {
    echo "Only one instance of fetch-params.sh can be run at a time." >&2
    exit 1
}

function main() {

    lock fetch-params.sh \
    || exit_locked_error

    cat <<EOF
Zcash - fetch-params.sh

This script will fetch the Zcash zkSNARK parameters and verify their
integrity with sha256sum.

If they already exist locally, it will exit now and do nothing else.
EOF

    # Now create PARAMS_DIR and insert a README if necessary:
    if ! [ -d "$PARAMS_DIR" ]
    then
        mkdir -p "$PARAMS_DIR"
        README_PATH="$PARAMS_DIR/README"
        cat >> "$README_PATH" <<EOF
This directory stores common Zcash zkSNARK parameters. Note that it is
distinct from the daemon's -datadir argument because the parameters are
large and may be shared across multiple distinct -datadir's such as when
setting up test networks.
EOF

        # This may be the first time the user's run this script, so give
        # them some info, especially about bandwidth usage:
        cat <<EOF
The parameters are currently just under 911MB in size, so plan accordingly
for your bandwidth constraints. If the files are already present and
have the correct sha256sum, no networking is used.

Creating params directory. For details about this directory, see:
$README_PATH

EOF
    fi

    cd "$PARAMS_DIR"

    fetch_params "$SPROUT_PKEY_URL" "$PARAMS_DIR/$SPROUT_PKEY_NAME" "8bc20a7f013b2b58970cddd2e7ea028975c88ae7ceb9259a5344a16bc2c0eef7"
    fetch_params "$SPROUT_VKEY_URL" "$PARAMS_DIR/$SPROUT_VKEY_NAME" "4bd498dae0aacfd8e98dc306338d017d9c08dd0918ead18172bd0aec2fc5df82"
}

main

if [[ ("$IS_SOLARIS" -ne "0" || "$IS_DARWIN" -ne "0") ]]; then
    rm -rf /tmp/fetch_params.lock
else
    rm -f /tmp/fetch_params.lock
fi

exit 0

ベストアンサー1

このように Bash パターンマッチングを使用できます。

[[ $(uname) = *[Dd]arwin* ]]; IS_DARWIN=$?
[[ $(uname) = *[Ss]un[Oo][Ss]* ]];  IS_SOLARIS=$?

これはBashに組み込まれた拡張テストです。 uname 呼び出しを減らすには、値を変数に保存します。

uname=$(uname)
[[ $uname = *[Dd]arwin* ]]; IS_DARWIN=$?
[[ $uname = *[Ss]un[Oo][Ss]* ]];  IS_SOLARIS=$?

これは次のようにさらに簡素化できます。

uname=$(uname)
[[ $uname =~ [Dd]arwin ]]; IS_DARWIN=$?
[[ $uname =~ [Ss]un[Oo][Ss] ]];  IS_SOLARIS=$?

または次のように:

uname=$(uname | tr [A-Z] [a-z])
[[ $uname =~ darwin ]]; IS_DARWIN=$?
[[ $uname =~ sunos ]];  IS_SOLARIS=$?

または最も単純な

uname=$(uname)
[[ $uname =~ Darwin ]]; IS_DARWIN=$?
[[ $uname =~ SunOS ]];  IS_SOLARIS=$?

例はSolaris(SunOS)で実行されます。

-bash-3.2$ uname
ソーラーオペレーティングシステム
-bash-3.2$ uname=$(uname | tr [AZ] [az])
-bash-3.2$ [[ $uname =~ sunos ]] IS_SOLARIS=$?;
0

-bash-3.2$ uname
ソーラーオペレーティングシステム
-bash-3.2$ uname=$(uname)
-bash-3.2$ [[ $uname =~ [Ss]un[Oo][Ss] ]] IS_SOLARIS=$?;
0

-bash-3.2$ uname
ソーラーオペレーティングシステム
-bash-3.2$ uname=$(uname)
-bash-3.2$ [[ $uname =~ SunOS ]] IS_SOLARIS=$?;
0
-bash-3.2$

-bash-3.2$ uname
ソーラーオペレーティングシステム
-bash-3.2$ [[ $(uname) =~ SunOS ]] IS_SOLARIS=$?;
0
-bash-3.2$

おすすめ記事