From 5ed2992871e3395e1c39387116bedaa3dbbe9cf9 Mon Sep 17 00:00:00 2001 From: Steven Baltakatei Sandoval Date: Thu, 25 Jul 2024 17:13:49 +0000 Subject: [PATCH 1/1] feat(user/bkots):Execute via array elements, not string concat - Note: v1.0.3 --> v2.0.0 --- user/bkots | 116 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 35 deletions(-) diff --git a/user/bkots b/user/bkots index baffb08..cca1fd8 100755 --- a/user/bkots +++ b/user/bkots @@ -10,13 +10,13 @@ calendars+=("https://finney.calendar.eternitywall.com"); calendars+=("https://btc.calendar.catallaxy.com"); calendars+=("https://alice.btc.calendar.opentimestamps.org"); calendars+=("https://bob.btc.calendar.opentimestamps.org"); -declare -a commands # array for storing assembled commands age_threshold="60"; # min age to add file; seconds; +max_job_count="2"; # default max job count # Declare functions yell() { echo "$0: $*" >&2; } # print script path and all args to stderr die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status -try() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails +must() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails checkapp() { # Desc: If arg is a command, save result in assoc array 'appRollCall' # Usage: checkapp arg1 arg2 arg3 ... @@ -200,7 +200,7 @@ showVersion() { vbm "DEBUG:showVersion function called." cat <<'EOF' -bkots 1.0.3 +bkots 2.0.0 Copyright (C) 2022 Steven Baltakatei Sandoval License GPLv3: GNU GPL version 3 This is free software; you are free to change and redistribute it. @@ -239,6 +239,8 @@ showUsage() { --include-dotfiles Include files and directories starting with '.' (not included by default). + -j, --jobs + Specify simultaneous job count (default: 2) -r, --recursive Consider files in dirs recursively. --version @@ -268,6 +270,32 @@ showUsage() { bkots foo.txt bar.pdf /home/username/Pictures/ EOF } # Display information on how to use this script. +count_jobs() { + # Desc: Count and return total number of jobs + # Usage: count_jobs + # Input: None. + # Output: stdout integer number of jobs + # Depends: Bash 5.1.16 + # Example: while [[$(count_jobs) -gt 0]]; do echo "Working..."; sleep 1; done; + # Version: 0.0.1 + + local job_count; + job_count="$(jobs -r | wc -l | tr -d ' ' )"; + #yell "DEBUG:job_count:$job_count"; + if [[ -z $job_count ]]; then job_count="0"; fi; + echo "$job_count"; +}; # Return number of background jobs +wait_for_jobslot() { + # Desc: Does not return until count_jobs() falls below $max_job_count + # Input: var max_job_count + # Output: return code 0 + # Depends: count_jobs(), yell(); + while [[ $(count_jobs) -ge $max_job_count ]]; do + printf "\r%d:Working..." "$SECONDS"; + sleep 1; + done; + return 0; +}; processArgs() { # Desc: Processes arguments provided to script. # Usage: processArgs "$@" @@ -302,6 +330,15 @@ processArgs() { --include-dotfiles) # Include dotfiles option_include_dotfiles="true"; vbm "DEBUG:Option enabled:include dotfiles";; + -j | --jobs) # Specify max_job_count + if [[ -n "$2" ]] && [[ "$2" =~ ^[0-9]+$ ]]; then + max_job_count="$2"; + vbm "STATUS:Max job count set to:$max_job_count"; + shift; + else + showUsage; + die "FATAL:Invalid job count:$2"; + fi;; -r | --recursive) # Specify recursive option option_recursive="true"; vbm "DEBUG:option enabled:include files in dirs recursively";; @@ -336,7 +373,7 @@ get_parent_dirnames() { # Input: arg1 input path # Output: stdout newline-delimited list of parent dirs # Version: 0.0.1 - # Depends: yell(), die(), try() + # Depends: yell(), die(), must() local path # Check input @@ -354,14 +391,6 @@ get_parent_dirnames() { echo "$name_base"; done; }; # Output parent dirnames to stdout -cmdwrap() { - # print command to stderr - echo "$@" 1>&2; - - # execute command - "$@"; -}; # print and execute string together -export -f cmdwrap; # export cmdwrap for use in other functions main() { # Desc: Creates `.ots` file: # - for each file specified in arrayPosArgs array @@ -640,7 +669,7 @@ main() { fi; # Act on files - ## Assemble upgrade file commands + ## Assemble and execute upgrade file commands for item in "${files_to_upgrade_pruned[@]}"; do path_prf="$(cut -d $'\n' -f1 < <(echo "$item"))"; path_prf_sesc="${path_prf//\"/\\\"}"; # escape path double quotes. See [4]. @@ -653,11 +682,19 @@ main() { ### Try upgrade with known calendars in random order while read -r url; do vbm "DEBUG:Upgrading with calendar:url:$url"; - if [[ "$opVerbose" = "true" ]]; then - commands+=("cmdwrap ots -v -l $url --no-default-whitelist upgrade \"$path_prf_sesc\"") && break; - else - commands+=("cmdwrap ots -l $url --no-default-whitelist upgrade \"$path_prf_sesc\"") && break; - fi; + + #### assemble command + local -a cmd_temp; + cmd_temp+=("ots"); + if [[ "$opVerbose" = "true" ]]; then cmd_temp+=("-v"); fi; + cmd_temp+=("-l" "$url" "--no-default-whitelist"); + cmd_temp+=("upgrade" "$path_prf_sesc"); + if [[ "$opVerbose" = "true" ]]; then declare -p cmd_temp; fi; + + #### execute command + wait_for_jobslot && must "${cmd_temp[@]}" & + unset cmd_temp; + break; #ots -l "$url" --no-default-whitelist upgrade "$path_prf" && break; done < <(printf "%s\n" "${calendars[@]}" | shuf); else @@ -665,7 +702,7 @@ main() { fi; done; - ## Assemble verify file commands + ## Assemble and execute verify file commands for item in "${files_to_verify_pruned[@]}"; do path_src="$(cut -d $'\n' -f1 < <(echo "$item"))"; path_prf="$(cut -d $'\n' -f2 < <(echo "$item"))"; @@ -681,11 +718,19 @@ main() { ### Try verify with known calendars in random order while read -r url; do vbm "DEBUG:Verifying with calendar:url:$url"; - if [[ "$opVerbose" = "true" ]]; then - commands+=("cmdwrap ots -v -l $url --no-default-whitelist verify -f \"$path_src_sesc\" \"$path_prf_sesc\"") && break; - else - commands+=("cmdwrap ots -l $url --no-default-whitelist verify -f \"$path_src_sesc\" \"$path_prf_sesc\"") && break; - fi; + + #### assemble command + local -a cmd_temp; + cmd_temp+=("ots"); + if [[ "$opVerbose" = "true" ]]; then cmd_temp+=("-v"); fi; + cmd_temp+=("-l" "$url" "--no-default-whitelist"); + cmd_temp+=("verify" "-f" "$path_src_sesc" "$path_prf_sesc"); + if [[ "$opVerbose" = "true" ]]; then declare -p cmd_temp; fi; + + #### execute command + wait_for_jobslot && must "${cmd_temp[@]}" & + unset cmd_temp; + break; #ots -l "$url" --no-default-whitelist verify -f "$path_src" "$path_prf" && break; done < <(printf "%s\n" "${calendars[@]}" | shuf); else @@ -693,7 +738,7 @@ main() { fi; done; - ## Assemble stamp file commands + ## Assemble and execute stamp file commands for item in "${files_to_stamp_pruned[@]}"; do path_src="$(cut -d $'\n' -f1 < <(echo "$item"))"; path_src_sesc="${path_src//\"/\\\"}"; # escape path double quotes. See [4]. @@ -703,21 +748,22 @@ main() { fi; vbm "DEBUG:Attempting to stamp source file:path_src:$path_src"; if [[ ! $option_dry_run == "true" ]]; then - if [[ "$opVerbose" = "true" ]]; then - commands+=("cmdwrap ots -v stamp \"$path_src_sesc\""); - else - commands+=("cmdwrap ots stamp \"$path_src_sesc\""); - fi; + + #### assemble command + local -a cmd_temp; + cmd_temp+=("ots"); + if [[ "$opVerbose" = "true" ]]; then cmd_temp+=("-v"); fi; + cmd_temp+=("stamp" "$path_src_sesc"); + if [[ "$opVerbose" = "true" ]]; then declare -p cmd_temp; fi; + + #### execute command + wait_for_jobslot && must "${cmd_temp[@]}" & + unset cmd_temp; #ots stamp "$path_src"; else yell "DEBUG:DRY RUN:Not running:\"ots stamp $path_src\""; fi; done; - - ## Run commands - #yell "DEBUG:commands:$(printf "%s\n" "${commands[@]}")"; - printf "%s\n" "${commands[@]}" | parallel --group --jobs 25%; - }; # main program # Run program -- 2.30.2