- Note: The intent of a minimum age limit for files to be timestamped
is to avoid timestamping files that are frequently changing.
calendars+=("https://btc.calendar.catallaxy.com");
calendars+=("https://alice.btc.calendar.opentimestamps.org");
calendars+=("https://bob.btc.calendar.opentimestamps.org");
calendars+=("https://btc.calendar.catallaxy.com");
calendars+=("https://alice.btc.calendar.opentimestamps.org");
calendars+=("https://bob.btc.calendar.opentimestamps.org");
+age_threshold="60"; # min age to add file; seconds;
# Declare functions
yell() { echo "$0: $*" >&2; } # print script path and all args to stderr
# Declare functions
yell() { echo "$0: $*" >&2; } # print script path and all args to stderr
vbm "DEBUG:showVersion function called."
cat <<'EOF'
vbm "DEBUG:showVersion function called."
cat <<'EOF'
Copyright (C) 2022 Steven Baltakatei Sandoval
License GPLv3: GNU GPL version 3
This is free software; you are free to change and redistribute it.
Copyright (C) 2022 Steven Baltakatei Sandoval
License GPLv3: GNU GPL version 3
This is free software; you are free to change and redistribute it.
themselves are also ignored by default
(e.g. '/home/user/.gitconfig').
themselves are also ignored by default
(e.g. '/home/user/.gitconfig').
+ Files modified less than 1 minute ago are ignored.
+
EXAMPLES:
bkots -v foo.txt
bkots foo.txt bar.pdf /home/username/Pictures/
EXAMPLES:
bkots -v foo.txt
bkots foo.txt bar.pdf /home/username/Pictures/
# - for each file in each dir specified in arrayPosArgs array
# Output file created alongside each file or in output directory specified by pathDirIn1
# Usage: main "$@";
# - for each file in each dir specified in arrayPosArgs array
# Output file created alongside each file or in output directory specified by pathDirIn1
# Usage: main "$@";
- # Input: arrayPosArgs array with positional arguments
- # pathDirOut1 path for output `.ots` files (if pathDirOut1 is specified and is a path)
+ # Input: arrayPosArgs array with positional arguments
+ # pathDirOut1 path for output `.ots` files (if pathDirOut1 is specified and is a path)
+ # age_threshold var: mininum age in seconds to timestamp file
+
# Output: file(s) creates `.ots` file alongside specified files
# Depends: find (GNU findutils) 4.8.0, GNU Coreutils 8.32 (sort)
# Ref/Attrib: [1] How to create an array of unique elements from a string/array in bash https://unix.stackexchange.com/a/167194
# [2] How to find files containing newlines in their names https://stackoverflow.com/a/21727028
# Output: file(s) creates `.ots` file alongside specified files
# Depends: find (GNU findutils) 4.8.0, GNU Coreutils 8.32 (sort)
# Ref/Attrib: [1] How to create an array of unique elements from a string/array in bash https://unix.stackexchange.com/a/167194
# [2] How to find files containing newlines in their names https://stackoverflow.com/a/21727028
+ # [3] Get mtime of specific file using Bash? https://stackoverflow.com/a/4774377
local -a file_list file_list_pruned;
local -a files_to_verify files_to_upgrade files_to_stamp
local -a files_to_verify_pruned files_to_upgrade_pruned files_to_stamp_pruned
local -a file_list file_list_pruned;
local -a files_to_verify files_to_upgrade files_to_stamp
local -a files_to_verify_pruned files_to_upgrade_pruned files_to_stamp_pruned
die "FATAL:Missing dependencies.";
fi;
die "FATAL:Missing dependencies.";
fi;
- # Check arguments
- ## Mark if output dir option specified
- if [[ -v pathDirOut1 ]]; then
- vbm "DEBUG:output directory specified:pathDirOut1:$pathDirOut1";
- if [[ -d $pathDirOut1 ]]; then
- vbm "DEBUG:pathDirOut1:$pathDirOut1";
- config_output_dir="true";
- else
- die "ERROR:Not a dir:$pathDirOut1";
+ # Check arguments
+ for arg in "${arrayPosArgs[@]}"; do
+ arg="$(readlink -f "$arg")";
+ if ! { [[ -d $arg ]] || [[ -f $arg ]]; }; then
+ die "FATAL:Not a file or dir:arg:$arg";
# Display ots details
vbm "$(type ots)"; # show how 'ots' is defined
# Display ots details
vbm "$(type ots)"; # show how 'ots' is defined
done < <(find "$item" -maxdepth 1 -type f);
fi;
else
done < <(find "$item" -maxdepth 1 -type f);
fi;
else
- die "ERROR:Not a file or dir:item:$item";
+ die "FATAL:Not a file or dir:item:$item";
fi;
done;
if [[ $opVerbose == "true" ]]; then
fi;
done;
if [[ $opVerbose == "true" ]]; then
# Prune file_list
for item in "${file_list[@]}"; do
# Prune file_list
for item in "${file_list[@]}"; do
+ ## Ignore files that end in '.ots.bak'.
+ if [[ $item =~ '.ots.bak'$ ]]; then
+ yell "INFO :Skipping file ending in '.ots.bak':item:$item";
+ continue; # skip to next item
+ fi;
+
+ ## Ignore dotfiles
if ! [[ $option_include_dotfiles == "true" ]]; then
if ! [[ $option_include_dotfiles == "true" ]]; then
- ## Ignore files located beneath a dotfile directory (e.g. '/home/my_repo/.git/config')
+ ### Ignore files located beneath a dotfile directory (e.g. '/home/my_repo/.git/config')
unset flag_contains_dotfile_parent;
while read -r line; do
unset flag_contains_dotfile_parent;
while read -r line; do
- ### Check line from output of get_parent_dirnames
+ #### Check line from output of get_parent_dirnames
pattern="^\.";
if [[ $line =~ $pattern ]]; then
pattern="^\.";
if [[ $line =~ $pattern ]]; then
- #### line starts with '.'
+ ##### line starts with '.'
vbm "DEBUG:Dotfile parent detected. Not including in file_list_pruned:$item";
vbm "DEBUG:Dotfile in path:item:$item";
vbm "DEBUG:Dotfile parent:line:$line";
vbm "DEBUG:Dotfile parent detected. Not including in file_list_pruned:$item";
vbm "DEBUG:Dotfile in path:item:$item";
vbm "DEBUG:Dotfile parent:line:$line";
continue; # skip to next item (i.e. don't add to file_list_pruned)
fi;
continue; # skip to next item (i.e. don't add to file_list_pruned)
fi;
- ## Ignore dotfiles themselves
+ ### Ignore dotfiles themselves
item_basename="$(basename "$item")";
pattern="^\.";
if [[ $item_basename =~ $pattern ]]; then
item_basename="$(basename "$item")";
pattern="^\.";
if [[ $item_basename =~ $pattern ]]; then
continue; # skip to next item
fi;
fi;
continue; # skip to next item
fi;
fi;
## Ignore files with newlines present in filename. See [2].
if [[ $item =~ $'\n' ]]; then
yell "INFO :Skipping file name with newline:$item";
## Ignore files with newlines present in filename. See [2].
if [[ $item =~ $'\n' ]]; then
yell "INFO :Skipping file name with newline:$item";
continue; # skip to next item
fi;
continue; # skip to next item
fi;
- ## Ignore files that end in '.ots.bak'.
- if [[ $item =~ '.ots.bak'$ ]]; then
- yell "INFO :Skipping file ending in '.ots.bak':item:$item";
+ ## Ignore files modified less than age_threshold. See [3].
+ time_now="$(date +%s)"; # epoch seconds
+ item_age="$(stat -c %Y "$item")"; # age in seconds
+ if [[ $(( time_now - item_age )) -lt "$age_threshold" ]]; then
+ yell "INFO :Skipping file modified less than $age_threshold seconds ago:item:$item";
continue; # skip to next item
fi;
continue; # skip to next item
fi;