diff --git a/bin/bfa b/bin/bfa index d8043a976be0397f7753c4ba375b8a3803bc0c51..8ce26ba5dabcab46f8f13275cdd327385c210c9c 100755 --- a/bin/bfa +++ b/bin/bfa @@ -2,7 +2,8 @@ # Robert Martin-Legene <robert@nic.ar> if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi -source ${BFAHOME}/bin/libbfa.sh || exit 1 +# shellcheck disable=SC1090 +source "${BFAHOME}/bin/libbfa.sh" || exit 1 declare -A commands help @@ -15,13 +16,14 @@ function register_subcommand function _usage() { - local after='' - for c in $( echo ${!commands[*]} | sort ) + local after c + after='' + for c in $(echo "${!commands[@]}" | sort) do after="${after}|$c" done - echo "Usage: $(basename $0) {${after:1}}" >&2 - for c in $( echo ${!commands[*]} | sort ) + echo "Usage: $(basename "$0") {${after:1}}" >&2 + for c in $(echo "${!commands[@]}" | sort) do printf '%-15s %s\n' "$c" "${help[$c]}" >&2 done @@ -37,18 +39,18 @@ function _max function pidsfromsigfiles { - local pids= - local file + local pids pid file + pids= for file in \ - ${BFANETWORKDIR}/bootnode.pid \ - ${BFANETWORKDIR}/start-bootnode-loop.pid \ - ${BFANODEDIR}/monitor.pid \ - ${BFANODEDIR}/start-monitor-loop.pid \ - ${BFANODEDIR}/geth.pid \ - ${BFANODEDIR}/start-geth-loop.pid + "${BFANETWORKDIR}/bootnode.pid" \ + "${BFANETWORKDIR}/start-bootnode-loop.pid"\ + "${BFANODEDIR}/monitor.pid" \ + "${BFANODEDIR}/start-monitor-loop.pid" \ + "${BFANODEDIR}/geth.pid" \ + "${BFANODEDIR}/start-geth-loop.pid" do test -r "$file" || continue - local pid=$(< "$file") + pid=$(< "$file") if ! [[ "$pid" =~ ^[0-9]+$ ]] then rm -f "$file" @@ -66,71 +68,84 @@ function pidsfromsigfiles function sendsig { - local signal=$1 + local signal pids + signal=$1 shift - local pids="$*" - test -n "$pids" || return + pids="$*" + if [ -z "$pids" ] + then + return + fi + # shellcheck disable=SC2086 ps -p ${pids// /,} echo "Sending ${signal} signal to pid $pids." - kill "$signal" $pids || true + kill "$signal" "$pids" || true } register_subcommand 'kill' 'killbfastuff' 'Kill BFA background processes (no questions asked).' function killbfastuff { - local pids=$(pidsfromsigfiles) + local pids + pids=$(pidsfromsigfiles) if [ -z "$pids" ] then echo "Nothing to send signals to." >&2 exit 2 fi - sendsig -KILL $pids + sendsig -KILL "$pids" } register_subcommand 'stop' 'graceful' 'Ask the BFA background processes to end gracefully.' function graceful { - local max=10 - local pids=$(pidsfromsigfiles) + local max pids + max=30 + pids=$(pidsfromsigfiles) + if [ -z "$pids" ] + then + echo "Nothing to send signals to." >&2 + exit 1 + fi + sendsig -TERM "$pids" + sleep 1 while : do - max=$((max - 1)) - test "$max" -eq 0 && break - if [ -z "$pids" ] - then - echo "Nothing to send signals to." >&2 - break - fi - sendsig -TERM $pids - sleep 0.4 pids=$(pidsfromsigfiles) + max=$((max - 1)) + test "$max" -gt 0 || break + test -n "$pids" || break + printf '\rThese are still alive: %s\x1b[J' "$pids" + sleep 0.5 done - test -z "$pids" || echo "This/these pids is/are still running: $f" + printf '\r\x1b[J' + if [ -n "$pids" ] + then + printf 'This/these pids is/are still running: %s\n' "$pids" + fi } register_subcommand 'initdb' 'initdb' 'Stop geth and reset the node to block zero (genesis).' function initdb { killbfastuff - yes | geth --cache 0 --datadir ${BFANODEDIR} removedb - geth --networkid ${BFANETWORKID} --cache 0 --datadir ${BFANODEDIR} init ${BFANETWORKDIR}/genesis.json + yes | geth --cache 0 --datadir "${BFANODEDIR}" removedb + geth --networkid "${BFANETWORKID}" --cache 0 --datadir "${BFANODEDIR}" init "${BFANETWORKDIR}/genesis.json" } register_subcommand 'exportdb' 'exportdb' 'Export blockchain in chunks of 1 million blocks per file.' function exportdb { - local delta=1000000 + local delta maxblocks blockstart toblock filename + delta=1000000 graceful - local maxblocks=$(bfageth --exec 'eth.blockNumber' console 2> /dev/null) + maxblocks=$(bfageth --exec 'eth.blockNumber' console 2> /dev/null) # 0 is genesis.. shouldn't dump that - local toblock - local blockstart=1 + blockstart=1 while [ "$blockstart" -lt "$maxblocks" ] do toblock=$(( blockstart + delta - 1 )) test "$toblock" -gt "$maxblocks" && toblock=$maxblocks - local filename printf -v filename 'bfa2018.blocks.%09d-%09d.export.gz' "$blockstart" "$toblock" if [ ! -e "$filename" ] then @@ -144,11 +159,11 @@ function exportdb register_subcommand 'importdb' 'importdb' 'Import blocks safely from previous block exports.' function importdb { - local dumpurl="https://s3.wasabisys.com/bfa/blockdumps" - local delta=1000000 + local dumpurl delta blockstart toblock + dumpurl="https://s3.wasabisys.com/bfa/blockdumps" + delta=1000000 graceful - local toblock - local blockstart=1 + blockstart=1 while : do toblock=$(( blockstart + delta - 1 )) @@ -156,7 +171,7 @@ function importdb curl --fail "${dumpurl}/${filename}" || break blockstart=$(( toblock + 1 )) done - geth --networkid ${BFANETWORKID} --datadir "${BFANODEDIR}" --syncmode "full" --gcmode "archive" import <( + geth --networkid "${BFANETWORKID}" --datadir "${BFANODEDIR}" --syncmode "full" --gcmode "archive" import <( n=1 while gzip -dc "bfa2018-1Mblocksstartingat${n}.block.export.gz" 2>/dev/null do @@ -184,7 +199,7 @@ function admin_syncmode echo "between speed and paranoia. You can change the setting, according to" echo "your needs." - mode=$( cat ${BFANODEDIR}/syncmode 2>/dev/null || true ) + mode=$(cat "${BFANODEDIR}/syncmode" 2>/dev/null || true) mode=${mode:-fast} echo "Your current mode is set to ${mode}" killed=0 @@ -194,7 +209,7 @@ function admin_syncmode echo while [ -z "${mode}" ] do - read -p "Which mode do you wish? : " mode + read -rp "Which mode do you wish? : " mode modefilter "$mode" if [[ "$mode" =~ ^full$|^fast$|^light$ ]] then @@ -205,7 +220,7 @@ function admin_syncmode fi done echo "Remembering your choice." - echo $mode > ${BFANODEDIR}/syncmode + echo "$mode" > "${BFANODEDIR}/syncmode" if [ "$orgmode" = "fast" ] && [ "$mode" = "full" ] then echo "You increased your paranoia level. The proper thing to do now," @@ -218,17 +233,17 @@ function admin_syncmode then if [ -r "${BFANODEDIR}/geth.pid" ] then - pid=$( cat ${BFANODEDIR}/geth.pid ) - kill -0 $pid 2>/dev/null && + pid=$(< "${BFANODEDIR}/geth.pid") + kill -0 "$pid" 2>/dev/null && echo "Killing running geth." && killed=1 - while ! kill $pid 2>/dev/null + while ! kill "$pid" 2>/dev/null do sleep 1 done fi initdb - test $killed -eq 1 && + test "$killed" -eq 1 && echo && echo "The startup.sh should restart your geth shortly." fi @@ -240,34 +255,35 @@ function admin_syncmode register_subcommand 'bootnode' 'admin_bootnode' 'Enable/disable the local bootnode.' function admin_bootnode { - keyfile=${BFANETWORKDIR}/bootnode/key + keyfile="${BFANETWORKDIR}/bootnode/key" echo "Only very few wants to actually run a boot node." echo "If you have a keyfile for a bootnode, then you will" echo "automatically start one, when restarting your system." - if [ -f $keyfile ] + if [ -f "$keyfile" ] then echo "You are set up to run a boot node." echo "Deleting your bootnode keyfile disables your bootnode." yesno n "Do you want to delete your bootnode keyfile?" if [ "$REPLY" = "y" ] then - rm $keyfile + rm "$keyfile" fi - pidfile=${BFANETWORKDIR}/bootnode/pid - if [ -r $pidfile ] + pidfile="${BFANETWORKDIR}/bootnode/pid" + if [ -r "$pidfile" ] then - pid=`cat $pidfile` - kill -0 $pid && - echo "Terminating your bootnode." && - kill `cat $pidfile` || - true + pid=$(< "$pidfile") + if kill -0 "$pid" + then + echo "Terminating your bootnode." + kill "$(< "$pidfile")" || true + fi fi else echo "You are not set up to run a boot node." yesno n "Do you want to create a keyfile for a bootnode?" if [ "$REPLY" = "y" ] then - bootnode -genkey $keyfile + bootnode -genkey "$keyfile" fi echo "You can now start your bootnode by running start.sh" fi @@ -290,16 +306,16 @@ function bfaaccount function create_account { - local num=0 - local filename - for filename in ${BFANODEDIR}/keystore/* + local num filename plural + num=0 + for filename in "${BFANODEDIR}"/keystore/* do test -f "$filename" && num=$(( num + 1 )) done if [ "$num" -gt 0 ] then - local plural="" + plural="" if [ "$num" -ne 1 ] then plural="s" @@ -310,20 +326,20 @@ function create_account return fi fi - geth --cache 0 --datadir ${BFANODEDIR} --password /dev/null account new + geth --cache 0 --datadir "${BFANODEDIR}" --password /dev/null account new } register_subcommand 'truncatelog' 'truncatelog' \ 'Truncate the log file. You may want to stop the background processes first.' function truncatelog { - true > ${BFANODEDIR}/log + true > "${BFANODEDIR}/log" } register_subcommand 'bfageth' 'bfageth' 'Start geth for BFA.' function bfageth { - exec geth --config ${BFANETWORKDIR}/conf.bfa2018.local+full+archive "$@" + exec geth --config "${BFANETWORKDIR}/conf.bfa2018.local+full+archive" "$@" } function bfaadmin @@ -339,7 +355,7 @@ function bfaadmin create_account ;; *) - echo Usage: `basename $0` "{bootnode|syncmode|account}" + echo "Usage: $(basename "$0") {bootnode|syncmode|account}" trap '' ERR exit 1 esac @@ -348,25 +364,27 @@ function bfaadmin register_subcommand 'tail' 'bfatail' 'tail -f on the logfile.' function bfatail { - exec tail -n 100 -F ${BFANODEDIR}/log + exec tail -n 100 -F "${BFANODEDIR}/log" exit 1 } register_subcommand 'log' 'bfalog' 'Open the logfile with less(1).' function bfalog { - exec less ${BFANODEDIR}/log + exec less "${BFANODEDIR}/log" exit 1 } function main { - case "$(basename $0)" in + case "$(basename "$0")" in 'bfa') local cmd cmd=$1 shift || _usage - test -n "$cmd" && test -n "${commands[$cmd]}" || _usage + test -n "$cmd" || _usage + test -n "${commands[$cmd]}" || _usage + # shellcheck disable=SC2086 eval ${commands[$cmd]} "$*" ;; 'admin.sh')