2 # Desc: Prints latest block from bitcoin-cli 
   3 # Usage: bkbtcblockclock 
   4 # Output: stdout: timestamped block numbers 
   5 # Depends: bitcoin-cli (from bitcoind), jq, gnu coreutils 8.30 
   8 #==BEGIN Define script parameters== 
  10 #===BEGIN Define variables=== 
  11 declare -Ag appRollCall 
# Associative array for storing app status 
  12 declare -Ag fileRollCall 
# Associative array for storing file status 
  13 declare -Ag dirRollCall 
# Associative array for storing dir status 
  14 #===END Define variables=== 
  17 #===BEGIN Declare local script functions=== 
  18 yell
() { echo "$0: $*" >&2; } # print script path and all args to stderr 
  19 die
() { yell 
"$*"; exit 111; } # same as yell() but non-zero exit status 
  20 try
() { "$@" || die 
"cannot $*"; } # runs args as command, reports args if command fails 
  22     # Desc: If arg is a command, save result in assoc array 'appRollCall' 
  23     # Usage: checkapp arg1 arg2 arg3 ... 
  25     # Input: global assoc. array 'appRollCall' 
  26     # Output: adds/updates key(value) to global assoc array 'appRollCall' 
  32         if command -v "$arg" 1>/dev
/null 
2>&1; then # Check if arg is a valid command 
  33             appRollCall
[$arg]="true"; 
  34             if ! [ "$returnState" = "false" ]; then returnState
="true"; fi; 
  36             appRollCall
[$arg]="false"; returnState
="false"; 
  40     #===Determine function return code=== 
  41     if [ "$returnState" = "true" ]; then 
  46 } # Check that app exists 
  48     # Desc: If arg is a file path, save result in assoc array 'fileRollCall' 
  49     # Usage: checkfile arg1 arg2 arg3 ... 
  51     # Input: global assoc. array 'fileRollCall' 
  52     # Output: adds/updates key(value) to global assoc array 'fileRollCall'; 
  53     # Output: returns 0 if app found, 1 otherwise 
  59         if [ -f "$arg" ]; then 
  60             fileRollCall
["$arg"]="true"; 
  61             if ! [ "$returnState" = "false" ]; then returnState
="true"; fi; 
  63             fileRollCall
["$arg"]="false"; returnState
="false"; 
  67     #===Determine function return code=== 
  68     if [ "$returnState" = "true" ]; then 
  73 } # Check that file exists 
  75     # Desc: If arg is a dir path, save result in assoc array 'dirRollCall' 
  76     # Usage: checkdir arg1 arg2 arg3 ... 
  78     # Input: global assoc. array 'dirRollCall' 
  79     # Output: adds/updates key(value) to global assoc array 'dirRollCall'; 
  80     # Output: returns 0 if app found, 1 otherwise 
  86         if [ -d "$arg" ]; then 
  87             dirRollCall
["$arg"]="true"; 
  88             if ! [ "$returnState" = "false" ]; then returnState
="true"; fi 
  90             dirRollCall
["$arg"]="false"; returnState
="false"; 
  94     #===Determine function return code=== 
  95     if [ "$returnState" = "true" ]; then 
 100 } # Check that dir exists 
 102     # Desc: Displays missing apps, files, and dirs 
 103     # Usage: displayMissing 
 105     # Input: associative arrays: appRollCall, fileRollCall, dirRollCall 
 106     # Output: stderr: messages indicating missing apps, file, or dirs 
 107     # Depends: bash 5, checkAppFileDir() 
 108     local missingApps value appMissing missingFiles fileMissing
 
 109     local missingDirs dirMissing
 
 111     #==BEGIN Display errors== 
 112     #===BEGIN Display Missing Apps=== 
 113     missingApps
="Missing apps  :"; 
 114     #for key in "${!appRollCall[@]}"; do echo "DEBUG:$key => ${appRollCall[$key]}"; done 
 115     for key 
in "${!appRollCall[@]}"; do 
 116         value
="${appRollCall[$key]}"; 
 117         if [ "$value" = "false" ]; then 
 118             #echo "DEBUG:Missing apps: $key => $value"; 
 119             missingApps
="$missingApps""$key "; 
 123     if [ "$appMissing" = "true" ]; then  # Only indicate if an app is missing. 
 124         echo "$missingApps" 1>&2; 
 127     #===END Display Missing Apps=== 
 129     #===BEGIN Display Missing Files=== 
 130     missingFiles
="Missing files:"; 
 131     #for key in "${!fileRollCall[@]}"; do echo "DEBUG:$key => ${fileRollCall[$key]}"; done 
 132     for key 
in "${!fileRollCall[@]}"; do 
 133         value
="${fileRollCall[$key]}"; 
 134         if [ "$value" = "false" ]; then 
 135             #echo "DEBUG:Missing files: $key => $value"; 
 136             missingFiles
="$missingFiles""$key "; 
 140     if [ "$fileMissing" = "true" ]; then  # Only indicate if an app is missing. 
 141         echo "$missingFiles" 1>&2; 
 144     #===END Display Missing Files=== 
 146     #===BEGIN Display Missing Directories=== 
 147     missingDirs
="Missing dirs:"; 
 148     #for key in "${!dirRollCall[@]}"; do echo "DEBUG:$key => ${dirRollCall[$key]}"; done 
 149     for key 
in "${!dirRollCall[@]}"; do 
 150         value
="${dirRollCall[$key]}"; 
 151         if [ "$value" = "false" ]; then 
 152             #echo "DEBUG:Missing dirs: $key => $value"; 
 153             missingDirs
="$missingDirs""$key "; 
 157     if [ "$dirMissing" = "true" ]; then  # Only indicate if an dir is missing. 
 158         echo "$missingDirs" 1>&2; 
 161     #===END Display Missing Directories=== 
 163     #==END Display errors== 
 164 } # Display missing apps, files, dirs 
 166     # depends: yell(), die(), try() 
 167     blockNum
="$(try bitcoin-cli getblockchaininfo | try jq '."headers
"')" 
 171     # depends: yell(), die(), try() 
 172     # usage printNum arg1 
 173     echo "[$(date --iso-8601=seconds)]:$1" 
 176     # Depends: bitcoin-cli (from bitcoind) 
 177     # Depends: getBlockNum(), printNum() 
 180     if ! checkapp bitcoin-cli jq 
date; then 
 181         yell 
"ERROR:Apps missing." >&2; 
 186     lastBlock
="$(getBlockNum)"; 
 187     printNum 
"$lastBlock"; 
 192         latestBlock
="$(getBlockNum)"; 
 194         # compare last and latestBlock 
 195         if [[ $latestBlock -gt $lastBlock ]]; then 
 198             printNum 
"$latestBlock"; 
 199             #echo "$(date --iso-8601=seconds)":"$latestBlock" 
 201             lastBlock
="$latestBlock" 
 211 #===END Declare local script functions=== 
 212 #==END Define script parameters== 
 216 # Author: Steven Baltakatei Sandoval