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 ...
vbm "DEBUG:showVersion function called."
cat <<'EOF'
-bkots 1.0.1
+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.
--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
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 "$@"
--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";;
# 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
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
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].
### 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
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"))";
### 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
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].
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;
-
}; # main program
# Run program
main "$@";
+exit 0;