Last active
January 16, 2022 13:52
-
-
Save kwhitefoot/ee6c44f6c4a58d77523c599906267f36 to your computer and use it in GitHub Desktop.
Nautlis script to move selected files to an archive directory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e # exit immediately on failure | |
set -u # fail if unset variable is used | |
set -o pipefail # exit with first error in a pipeline | |
set -x | |
##################### | |
# Move the specified files to the archive | |
# This version has no error handling, it is a proof of concept that | |
# will be developed further if necessary | |
# Does not move directories or their contents only individual files. | |
# Does not move symlinks. | |
# Depends on: | |
# - zenity: to display error and information messages | |
# Configuration: | |
# Expects a configuration file named "move to archive.config" in the | |
# same directory as the script. | |
# Logging: | |
# Creates a log in "move to archive.log". The script reduces this | |
# file to the last 1000 lines before adding more. | |
##################### | |
show_info(){ | |
echo "${1}" | |
zenity --info --width=400 \ | |
--title="${title}" \ | |
--text="${1}" | |
} | |
limit_log(){ | |
local log | |
log="$(tail --lines=${MAX_LOG_FILE_LINES} "${log_file}")" && | |
echo "${log}" > "${log_file}" | |
} | |
abs_filename() { | |
# $1 : relative filename | |
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")" | |
} | |
iso_date_time(){ | |
date --iso-8601="seconds" | |
} | |
archive_one(){ | |
local -r src="${1}" | |
local -r dst="${ARCHIVE}/${src}" | |
local -r timestamp="$(iso_date_time)" | |
local -r version="${dst}.${timestamp}" | |
echo "----------------" | |
echo "src: $src" | |
echo "dst: $dst" | |
# Move the file to the archive | |
mv --verbose "${src}" "${dst}" | |
# Link the file to a dated version in case the user creates or | |
# restores the file and archives it again. | |
ln --verbose "${dst}" "${version}" | |
# # Leave a marker in place of the source to remind the user that | |
# # the archived file exists. | |
# local -r placeholder="${src}.archived" | |
# echo "archive=\"${dst}\"" > "${placeholder}" | |
# echo "when=\"${timestamp}\"" >> "${placeholder}" | |
# replace the source file with a symlink | |
ln --symbolic --verbose "${dst}" "${src}" | |
} | |
archive_all(){ | |
local -i count=0 | |
local -i total="${#}" | |
local -i progress_percent | |
for i in "${@}" | |
do | |
(( ++count )) | |
echo "item: $i" | |
local src="$(abs_filename "${i}")" | |
if [[ -d "${src}" ]] | |
then | |
local msg="Cannot archive directories (yet)\n ${src}" | |
echo "${msg}" | |
(( ++count_directories )) | |
continue | |
fi | |
if [[ -L "${src}" ]] | |
then | |
local msg="Ignoringing symlink\n ${src}" | |
echo "${msg}" | |
(( ++count_symlinks )) | |
continue | |
fi | |
archive_one "${src}" | |
# Note pre-increment to avoid killing the script. | |
(( ++count_archived )) | |
(( progress_percent = count * 100 / total )) | |
echo "${progress_percent}" >&"${progress[1]}" | |
done | |
echo "100" >&"${progress[1]}" | |
echo "----------------" | |
echo "Archived ${count_archived} files" | |
} | |
# Wrap the main in a block so that we can redirect to a log file. | |
# Redirect errors as well | |
main(){ | |
# Load the configuration. At the moment this is just the path to | |
# the archive. | |
# The configuration file should look somthing like this | |
# #!/bin/bash | |
# ARCHIVE="/media/username/diskname/path/to/archive/" | |
# MAX_LOG_FILE_LINES=1000 | |
# shellcheck source=archive.config | |
. "${script_path}.config" | |
declare -rg title="$script_name" | |
# Create a coprocess to show the progress | |
coproc progress ( zenity --progress --auto-close --title="${title}" ) | |
echo "The progress coprocess array: ${progress[@]}" | |
echo "The PID of the print coprocess is ${progress_PID}" | |
echo | |
echo | |
echo "================" | |
date | |
echo "Archiving to ${ARCHIVE}" | |
echo "Current directory" | |
pwd | |
echo "Item count: ${#}" | |
declare -ig count_archived=0 | |
declare -ig count_symlinks=0 | |
declare -ig count_directories=0 | |
if [[ ${#} == 0 ]] | |
then | |
local -r msg="No files selected." | |
show_info "${msg}" | |
else | |
archive_all "${@}" | |
fi | |
local -r exit_msg="Archived ${count_archived} of ${#} files, \n\ | |
ignored ${count_directories} directories, \n\ | |
ignored ${count_symlinks} symlinks." | |
show_info "${exit_msg}" | |
echo "================" | |
echo | |
echo | |
} | |
# Defaults: | |
declare -i MAX_LOG_FILE_LINES=1000 | |
declare -r script_name="$(basename "$0")" | |
declare -r script_path="$(readlink -f "$0")" | |
declare -r log_file="${script_path}.log" | |
limit_log | |
main "${@}" &>> "${log_file}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment