![bash 스크립트가 main을 실행하지 않는 이유를 이해하십니까?](https://linux55.com/image/98248/bash%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EA%B0%80%20main%EC%9D%84%20%EC%8B%A4%ED%96%89%ED%95%98%EC%A7%80%20%EC%95%8A%EB%8A%94%20%EC%9D%B4%EC%9C%A0%EB%A5%BC%20%EC%9D%B4%ED%95%B4%ED%95%98%EC%8B%AD%EB%8B%88%EA%B9%8C%3F.png)
클론을 수행했습니다.제로코인:
$ git clone https://github.com/zcash/zcash.git
$ cd zcash/
$ git checkout v1.0.1
$ ./zcutil/fetch-params.sh
나는 달리려고 노력하고있다.fetch-params.sh
OS 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.53
Solaris 11에서 사용 가능합니다 GNU bash, version 4.1.17
.
저의 무지함을 용서해주세요... 테스트로 인해 스크립트가 죽는 IS_DARWIN
이유 는 무엇입니까? IS_SOLARIS
왜 main이 실행되지 않습니까?
완전히 수정된 스크립트
#!/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$
답변2
$ man grep
/EXIT
EXIT STATUS
Normally the exit status is 0 if a line is selected, 1 if no lines were
selected, and 2 if an error occurred. However, if the -q or --quiet or
--silent is used and a line is selected, the exit status is 0 even if
an error occurred.
편집: 이것이 요점을 명확하게 해주기를 바랍니다. 이 동작을 찾고 있지 않다면 놀라운 일이라는 것을 알고 있습니다.
이는 비밀 POSIX 표준을 참조하여 확인할 수 있습니다(심각하게는 더 많은 사람들이 인쇄된 버전을 구매할 것이라는 희망으로 웹 페이지를 약간 모호하게 했습니다).
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html#tag_20_55_14
종료 상태
The following exit values shall be returned: 0 One or more lines were selected. 1 No lines were selected. >1 An error occurred.
샘플 솔루션
"오류가 발생했습니다"를 감지하려는 시도는 이루어지지 않습니다.
if (uname -s | grep -i darwin >/dev/null); then
IS_DARWIN=1
fi