Applied style guide. Fixed bug in check size, that lead to copying to extra location, while file with different size does not exist.

This commit is contained in:
Stephan
2023-11-22 22:52:33 +01:00
parent eb087ba8ef
commit 53e5439095
2 changed files with 245 additions and 196 deletions

25
photosync.conf Normal file
View File

@@ -0,0 +1,25 @@
#!/bin/bash
# Target server. Comment if target folder is on the same machine!
TOSSH="192.168.0.5"
# port to use for ssh on the server.
SSHPORT=10110
# User for the server.
SSHUSER="myuser"
# target folder on the server.
SYNC_TARGET="/srv/Photos/"
SYNC_EXTRA="/srv/Photos/duplicate/"
# Extensions of the files to be copied.
EXTENSIONS="*.jpg *.JPG *.mp4 *.MP4"
# Prefixes replacing the to replace with
REPLACE="IMG VID"; # What to replace
PREFIXES="USER USERVid"; # replace with
# Max number of parallel copy processes.
THRESHOLD=9
# Overwrite the default log level of the photosync script.
# Valid levels are LLDebug, LLInfo, LLWarning, LLError, LLMdtry, LLMute.
Log_Level=$LLInfo

View File

@@ -2,33 +2,44 @@
## Syncs all data in folder given to the configured destiny. ## Syncs all data in folder given to the configured destiny.
## Log levels for messages ## Log levels for messages
LLMUTE=0 LLMute=0
LLMDTRY=1 LLMdtry=1 # mandatory: messages that are always written to the log (except mute)
LLERROR=2 LLError=2
LLWARNING=3 LLWarning=3
LLINFO=4 LLInfo=4
LLDEBUG=5 LLDebug=5
## Actual log level of the logger used ## Actual log level of the logger used
LOGLEVEL=$LLDEBUG Log_Level=$LLDebug
## Write log of the script. ## Write log of the script.
## $1 Loglevel to log the message with. ## $1 Loglevel to log the message with.
## $2 message to log. ## $2 message to log.
function __logger() { function logger() {
local LOGGINGLEVEL=$1; local _logging_level=$1;
local LOGMESSAGE=$2; local _log_message=$2;
local _NOW=$($DATE +%Y%m%d_%H:%M:%S); if [[ $Log_Level -lt $_logging_level ]]; then
if [[ $LOGLEVEL -ge $LOGGINGLEVEL ]]; then return;
echo "photosync $_NOW: ${LOGMESSAGE}" >> $LOGFILE;
fi fi
if [[ $LOGLEVEL -eq $LLDEBUG ]]; then local _now=$($DATE +%Y%m%d_%H:%M:%S);
echo "photosync $_NOW: ${LOGMESSAGE}"; if [[ $_logging_level -eq $LLInfo ]]; then
_type=" Info:";
elif [[ $_logging_level -eq $LLError ]]; then
_type=" ERROR!";
elif [[ $_logging_level -eq $LLWarning ]]; then
_type=" Warning:";
elif [[ $_logging_level -eq $LLDebug ]]; then
_type=" DEBUG:";
else
_type=":";
fi
printf "photosync ${_now}${_type} ${_log_message}\n" >> $Log_File;
if [[ $Log_Level -eq $LLDebug ]]; then
printf "photosync ${_now}${_type} ${_log_message}\n";
fi fi
} }
## Display Help ## Display Help
function __usage() function usage() {
{
echo "$0 syncs all data from a source folder to a target folder. Target folder may optionally be on a remote ssh server." echo "$0 syncs all data from a source folder to a target folder. Target folder may optionally be on a remote ssh server."
echo echo
echo "Syntax: scriptTemplate [-h|c|v|V]" echo "Syntax: scriptTemplate [-h|c|v|V]"
@@ -42,250 +53,264 @@ function __usage()
## Cleanup function to exit script gracefully ## Cleanup function to exit script gracefully
# param1 Exit value to end with # param1 Exit value to end with
function __cleanup() { function cleanup() {
local EXITVAL=$1 logger $LLMdtry "Done! Exiting with value ${1}.";
exit $1;
exit $EXITVAL;
} }
## Returns the binaries full path if existent. ## Returns the binaries full path if existent.
## $1 referenced variable the found path to the binary is stored and returned in. ## $1 referenced variable the found path to the binary is stored and returned in.
## $2 Name of the binary to look for. ## $2 Name of the binary to look for.
## return 0 in case of success (binary found), 1 on fail. $1 then contains "$2 not found!". ## return 0 in case of success (binary found), 1 on fail. $1 then contains "$2 not found!".
function __which_is() { function which_is() {
declare -n RETVAL=$1; declare -n _ret_val=$1; # define _ret_val as a reference to the first parameter of the function.
EXECUTABLE=$2; local _executable=$2;
WITHFULLPATH=$(which ${EXECUTABLE} 2>/dev/null); local _with_full_path=$(which ${_executable} 2>/dev/null);
if [ -x "$WITHFULLPATH" ]; then if [ -x "$_with_full_path" ]; then
RETVAL="$WITHFULLPATH"; _ret_val="$_with_full_path";
return 0; return 0;
else else
RETVAL="$EXECUTABLE not found!"; _ret_val="$_executable not found!";
return 1; return 1;
fi fi
} }
## Checks given folder for files with certain extensions. Subfolders are checked recursively. ## Checks given folder for files with certain extensions. Subfolders are checked recursively.
## $1 Folder to check. ## $1 Folder to check.
## $2 space separated list of extensions to check for. e.g.: "*.jpg *.JPG *.mp4 *.MP4". ## $2 String of space separated extensions to check for. e.g.: "*.jpg *.JPG *.mp4 *.MP4".
## returns Count of files found with the desired extension. ## returns Count of files found with the desired extension.
__check_folder() { function check_folder() {
local _FOLDER=$1; local _folder=$1;
local _EXTENSIONS=$2; local _extensions=$2;
local _FILE_C=0; local _file_count=0;
if [ -d "$_FOLDER" ]; then # is a folder if [ -d "$_folder" ]; then # is a folder
local _ITEM=""; local _item="";
local _FC=${#FILESNPATHS[@]}; local _fc=${#Files_N_Paths[@]};
pushd "$_FOLDER" 1>/dev/null; pushd "$_folder" 1>/dev/null;
for _ITEM in ${_EXTENSIONS}; do # lookup all files with the desired extensions for _item in ${_extensions}; do # lookup all files with the desired extensions
if [[ -f "$_ITEM" ]]; then # is a file if [[ -f "$_item" ]]; then # is a file
FILESNPATHS[$_FC]="$(pwd)/$_ITEM"; Files_N_Paths[$_fc]="$(pwd)/$_item";
((_FC+=1)); ((_fc+=1));
((_FILE_C+=1)); ((_file_count+=1));
fi fi
done done
# check subfolders if exist # check subfolders if exist
local _SUBFOLDERS="$(/usr/bin/ls . 2>/dev/null)"; local _sub_folders="$(/usr/bin/ls . 2>/dev/null)";
local _CNT=0; local _cnt=0;
for _SUBITEM in ${_SUBFOLDERS}; do for _sub_item in ${_sub_folders}; do
if [[ -d "$_SUBITEM" ]]; then if [[ -d "$_sub_item" ]]; then
__check_folder "$_SUBITEM" "$_EXTENSIONS"; check_folder "$_sub_item" "$_extensions";
_CNT=$? _cnt=$?
((_FILE_C+=_CNT)); ((_file_count+=_cnt));
fi fi
done done
popd 1>/dev/null; popd 1>/dev/null;
fi fi
return $_FILE_C return $_file_count
} }
## Check filesizes of local and remote file ## Check filesizes of local and remote file
## $1 Path of local file ## $1 Path of local file
## $2 Path of remote file ## $2 Path of remote file
## return 0 in case of matching sizes, 1 means size differs, 2 remote file does not exist.
check_local_remote_filesize() { check_local_remote_filesize() {
local LocalFile=$1; local _local_file=$1;
local RemoteFile=$2; local _remote_file=$2;
local LocFileSize=$(stat -c%s "${LocalFile}"); local _local_file_size=$(stat -c%s "${_local_file}");
__logger $LLDEBUG "Local file size : $LocFileSize <${FILESNPATHS[$FILE_C]}>"; if [ ! -z $TOSSH ]; then
if [ -n $TOSSH ]; then local _remote_file_size=$($S $TOSSH "stat -c%s ${_remote_file}" 2>/dev/null);
local RemFileSize=$($S $TOSSH "stat -c%s ${RemoteFile}" 2>/dev/null);
else else
local RemFileSize=$(stat -c%s "${RemoteFile}"); local _remote_file_size=$(stat -c%s "${_remote_file}" 2>/dev/null);
fi fi
__logger $LLDEBUG "Remote file size : ${RemFileSize} <${TARGETPATH}/${FILEBASENAME}>"; if [[ $_remote_file_size != ?(-)+([0-9]) ]]; then # value should be integer to test true
if [[ $RemFileSize != ?(-)+([0-9]) ]]; then # value should be integer to test true
__logger $LLERROR "Remote file »${RemoteFile}« does not exist!";
return 2; return 2;
fi fi
if [ $LocFileSize -ne $RemFileSize ]; then if [[ $_local_file_size -ne $_remote_file_size ]]; then
__logger $LLERROR "ERROR! Sizes of local and remote file size do not match! <${LocalFile}>!";
return 1; return 1;
fi fi
return 0; return 0;
} }
## Main function ## Main function
function __main() { function main() {
# create file list to move to copy to server # create file list to move to copy to server
declare -A FILESNPATHS; # associative array declare -A Files_N_Paths; # associative array
__check_folder "$CPFOLDER" "$EXTENSIONS"; check_folder "$Cp_Folder" "$EXTENSIONS";
FILE_COUNT=$? local _file_count=$?
__logger $LLDEBUG "Count of files with extensions »$EXTENSIONS« is $FILE_COUNT."; logger $LLDebug "Count of files with extensions »$EXTENSIONS« is $_file_count.";
if [[ $FILE_COUNT -eq 0 ]]; then if [[ $_file_count -eq 0 ]]; then
__logger $LLERROR "No files to copy!" logger $LLError "No files to copy!"
__cleanup 1; cleanup 1;
fi fi
# Make Lists for prefixes to replace # Make Lists for prefixes to replace
declare -A PREFIXES; declare -A _prefixes;
PRE_C=0; local _pre_c=0;
for PRE in $PREFIX; do for _prefx in $PREFIXES; do
PREFIXES[$PRE_C]="$PRE"; #echo "Arrayinhalt an der Stelle $INP_C: ${FILE[$INP_C]}"; _prefixes[$_pre_c]="$_prefx"; #echo "Arrayinhalt an der Stelle $INP_C: ${FILE[$INP_C]}";
((PRE_C=PRE_C+1)); ((_pre_c+=1));
done done
if [ $PRE_C -eq 0 ]; then if [[ $_pre_c -eq 0 ]]; then
__logger $LLERROR "ERROR! Number of prefixes ($PRE_C) must not be 0! Check variables in <$SOURCECONFFILE>!"; logger $LLError "Number of prefixes ($_pre_c) must not be 0! Check variables in <$Conf_File>!";
exit 1; exit 1;
fi fi
# Make List with replacement prefixes # Make List with replacement prefixes
declare -A REPLACEMENTS; declare -A _replacements;
REP_C=0; local _repl_c=0;
for REP in $REPLACE; do for _repl in $REPLACE; do
REPLACEMENTS[$REP_C]="$REP"; _replacements[$_repl_c]="$_repl";
((REP_C=REP_C+1)); ((_repl_c+=+1));
done done
if [ $REP_C -eq 0 ]; then if [[ $_repl_c -eq 0 ]]; then
__logger $LLERROR "ERROR! Number of replacements ($REP_C) must not be 0! Check variables in <$SOURCECONFFILE>!"; logger $LLError "Number of replacements ($_repl_c) must not be 0! Check variables in <$Conf_File>!";
exit 1; exit 1;
fi fi
if [ $REP_C -ne $PRE_C ]; then if [[ $_repl_c -ne $_pre_c ]]; then
__logger $LLERROR "ERROR! Number of prefixes ($PRE_C) is not equal to number of replacements ($REP_C)! Check variables in <$SOURCECONFFILE>!"; logger $LLError "Number of prefixes ($_pre_c) is not equal to number of replacements ($_repl_c)! Check variables in <$Conf_File>!";
exit 1; exit 1;
fi fi
__logger $LLMDTRY "_______________________ cloud_photosync.sh __________________________"; logger $LLMdtry "_______________________ ${0} __________________________";
__logger $LLMDTRY "$($DATE '+%h:%n %d.%m.%Y')"; logger $LLMdtry "$($DATE +'%h:%n %d.%m.%Y'), File count: $_file_count";
__logger $LLMDTRY "File count: $FILE_COUNT"; for((_pc=0;_pc<${#_prefixes[*]};_pc++)); do
for((C=0;C<${#PREFIXES[*]};C++)); do logger $LLMdtry "${_prefixes[$_pc]} -> ${_replacements[$_pc]}";
__logger $LLMDTRY "${PREFIXES[C]} -> ${REPLACEMENTS[C]}";
done done
local _succ_count=0; # successfully copied files
local _done_count=0; # files where already there
local _dup_diff=0; # there already is a duplicate file
local _miss_count=0; # after copy file sizes do not match
local _fail_count=0; # file is missing after copy.
declare -A _original_files;
declare -A _date_times;
# Start copy loop # Start copy loop
for((FILE_C=0;FILE_C<${#FILESNPATHS[*]};FILE_C++)); do for((_fc=0;_fc<${#Files_N_Paths[*]};_fc++)); do
# we only start copying, when there are no more copy procedures ongoing, than THRESHOLD! # we only start copying, when there are no more copy procedures ongoing, than THRESHOLD!
while [ ${#ORIGINALFILES[*]} -eq $THRESHOLD ]; do while [ ${#_original_files[*]} -eq $THRESHOLD ]; do # as long as the length of original_files array is THRESHOLD
__logger $LLDEBUG "$FILE_C Threshold reached."; logger $LLDebug "$_fc Threshold reached.";
for CPID in "${!ORIGINALFILES[@]}"; do for _pid in "${!_original_files[@]}"; do # check all process ids in _original_files
if [ -n "${CPID}" -a -d "/proc/${CPID}" ]; then if [ -n "${_pid}" -a -d "/proc/${_pid}" ]; then
# Prozess läuft noch, check nicht möglich # Copy process still running
__logger $LLDEBUG "${CPID} still running"; logger $LLDebug "Copying of ${_original_files[$_pid]} (${_pid}) still running.";
else else
# hochladen beendet, kann Größe testen # Copy process done, compare file sizes
__logger $LLDEBUG "# Check on target ${TARGETFILES[$CPID]}"; logger $LLDebug "Check target »${_target_files[$_pid]}«";
check_local_remote_filesize "${ORIGINALFILES[$CPID]}" "${TARGETFILES[$CPID]}"; check_local_remote_filesize "${_original_files[$_pid]}" "${_target_files[$_pid]}";
RET=$?; local _ret_clrfs=$?;
if [ $RET -eq 0 ]; then # sizes match if [ $_ret_clrfs -eq 0 ]; then # sizes match
if [ ! -z "$TOSSH" ]; then # otherwise cp is done with -p if [ ! -z "$TOSSH" ]; then # otherwise cp is done with -p
FILEBASENAME=$(basename -- "${TARGETFILES[$CPID]}"); local _file_base_name=$(basename -- "${_target_files[$_pid]}");
$S $TOSSH "touch -d '${DATETIMES[$CPID]}' ${TARGETFILES[$CPID]}"; # restore file creation date $S $TOSSH "touch -d '${_date_times[$_pid]}' ${_target_files[$_pid]}"; # restore file creation date
fi fi
((SUC_C=SUC_C+1)) ((_succ_count+=1))
__logger $LLDEBUG "$SUC_C ${ORIGINALFILES[$CPID]}"; logger $LLDebug "$SUC_C ${_original_files[$_pid]}";
else # sizes don't match or file does not exist elif [[ $_ret_clrfs -eq 1 ]]; then
((MIS_C=MIS_C+1)) logger $LLError "Sizes of local and remote file size do not match! »${_original_files[$_pid]}« <-> »${_target_files[$_pid]}«";
((_miss_count+=1))
else # 2: file does not exist
logger $LLError "Remote file »${_target_files[$_pid]}« does not exist!";
((_fail_count+=1))
fi fi
unset ORIGINALFILES["${CPID}"]; unset _original_files["${_pid}"];
unset TARGETFILES["${CPID}"]; unset _target_files["${_pid}"];
unset DATETIMES["${CPID}"]; unset _date_times["${_pid}"];
fi fi
done # for CPID in "${!ORIGINALFILES[@]}"; do done # for _pid in "${!_original_files[@]}"; do
done done
# set file creation date by exif date # set file creation date by exif date
DATETIME=$($EXIFTOOL -DateTimeOriginal -s -s -s -d '%F %H:%M:%S' "${FILESNPATHS[$FILE_C]}"); local _datetime=$($EXIFTOOL -DateTimeOriginal -s -s -s -d '%F %H:%M:%S' "${Files_N_Paths[$_fc]}");
# construct server path # construct server path
DATE_Y=$(date +%Y --date="$DATETIME"); local _date_y=$(date +%Y --date="$_datetime");
DATE_M=$(date +%m --date="$DATETIME"); local _date_m=$(date +%m --date="$_datetime");
DATE_D=$(date +%d --date="$DATETIME"); local _date_d=$(date +%d --date="$_datetime");
# Targetpath format : YYYY/YYYY_MM_DD_PREFIX # _target_path format : YYYY/YYYY_MM_DD_PREFIX
TARGETPATH="${SYNC_TARGET}${DATE_Y}/${DATE_Y}_${DATE_M}_${DATE_D}_${PREFIXES[0]}"; # Path on server for target file _target_path="${SYNC_TARGET}${_date_y}/${_date_y}_${_date_m}_${_date_d}_${_prefixes[0]}"; # Path on server for target file
EXTRAPATH="${SYNC_EXTRA}${DATE_Y}/${DATE_Y}_${DATE_M}_${DATE_D}_${PREFIXES[0]}"; # Path on server for target file _extra_path="${SYNC_EXTRA}${_date_y}/${_date_y}_${_date_m}_${_date_d}_${_prefixes[0]}"; # Path on server for target file
__logger $LLDEBUG "Server target path »$TARGETPATH«"; logger $LLDebug "Server target path »$_target_path«";
# create new file name # create new file name
FILEBASENAME=$(basename -- "${FILESNPATHS[$FILE_C]}"); local _file_base_name=$(basename -- "${Files_N_Paths[$_fc]}");
for((REPL_C=0;REPL_C<${#PREFIXES[*]};REPL_C++)); do for((_rc=0;_rc<${#_prefixes[*]};_rc++)); do
PREF="${PREFIXES[$REPL_C]}"; _pref="${_prefixes[$_rc]}";
REPL="${REPLACEMENTS[$REPL_C]}"; _repl="${_replacements[$_rc]}";
FILEBASENAME="${FILEBASENAME/$REPL/$PREF}"; _file_repl_name="${_file_base_name/$_repl/$_pref}";
done done
logger $LLDebug "$_file_base_name -> $_file_repl_name";
# Test for existing files # Test for existing files
check_local_remote_filesize "${FILESNPATHS[$FILE_C]}" "${TARGETPATH}/${FILEBASENAME}"; check_local_remote_filesize "${Files_N_Paths[$_fc]}" "${_target_path}/${_file_repl_name}";
CLRFSres=$? CLRFSres=$?
if [ $CLRFSres -eq 0 ]; then if [ $CLRFSres -eq 0 ]; then # file is already there
__logger $LLINFO "File <${FILESNPATHS[$FILE_C]}> already exists as <${TARGETPATH}/${FILEBASENAME}>, skipping."; ((_done_count+=1))
elif [ $CLRFSres -eq 1 ]; then # file does not exist logger $LLInfo "File <${Files_N_Paths[$_fc]}> already exists as <${_target_path}/${_file_repl_name}>, skipping.";
elif [ $CLRFSres -eq 2 ]; then # file does not exist, just start copy
if [ ! -z $TOSSH ]; then # if [ ! -z $TOSSH ]; then #
__logger $LLINFO "Copying file <${FILESNPATHS[$FILE_C]}> -> Server<${TARGETPATH}/${FILEBASENAME}>"; logger $LLInfo "Copying file <${Files_N_Paths[$_fc]}> -> Server<${_target_path}/${_file_repl_name}>";
cat "${FILESNPATHS[$FILE_C]}" | $S $TOSSH "mkdir -p ${TARGETPATH};cat > '${TARGETPATH}/${FILEBASENAME}'" & cat "${Files_N_Paths[$_fc]}" | $S $TOSSH "mkdir -p ${_target_path};cat > '${_target_path}/${_file_repl_name}'" &
COPYPID=$!; _cp_pid=$!;
else # no TOSSH else # no TOSSH
if [ ! -e "${TARGETPATH}" ]; then # file path does not exist if [ ! -e "${_target_path}" ]; then # file path does not exist
mkdir -p "${TARGETPATH}"; mkdir -p "${_target_path}";
fi fi
if [ -d "${TARGETPATH}" ]; then if [ -d "${_target_path}" ]; then
cp -p "${FILESNPATHS[$FILE_C]}" "${TARGETPATH}/${FILEBASENAME}" & cp -p "${Files_N_Paths[$_fc]}" "${_target_path}/${_file_repl_name}" &
COPYPID=$!; _cp_pid=$!;
else else
__logger $LLERROR "Unable to create ${TARGETPATH}! Skipping file ${FILESNPATHS[$FILE_C]}!"; logger $LLError "Unable to create ${_target_path}! Skipping file ${Files_N_Paths[$_fc]}!";
continue; continue;
fi fi
fi fi
ORIGINALFILES+=( ["${COPYPID}"]="${FILESNPATHS[$FILE_C]}" ); _original_files+=( ["${_cp_pid}"]="${Files_N_Paths[$_fc]}" );
TARGETFILES+=( ["${COPYPID}"]="${TARGETPATH}/${FILEBASENAME}" ); _target_files+=( ["${_cp_pid}"]="${_target_path}/${_file_repl_name}" );
DATETIMES+=( ["${COPYPID}"]="${DATETIME}" ); _date_times+=( ["${_cp_pid}"]="${_datetime}" );
else # 2: different size-> start copying else # 1:
logger $LLInfo "Copying file <${Files_N_Paths[$_fc]}> to Server<${_extra_path}/${_file_repl_name}>; creating link to ${_target_path}/${_file_repl_name}.";
if [ ! -z $TOSSH ]; then # if [ ! -z $TOSSH ]; then #
__logger $LLINFO "Copying file <${FILESNPATHS[$FILE_C]}> -> Server<${EXTRAPATH}/${FILEBASENAME}>"; cat "${Files_N_Paths[$_fc]}" | $S $TOSSH "mkdir -p ${_extra_path};cat > ${_extra_path}/${_file_repl_name}" &
cat "${FILESNPATHS[$FILE_C]}" | $S $TOSSH "mkdir -p ${EXTRAPATH};cat > ${EXTRAPATH}/${FILEBASENAME} && ln -s ${TARGETPATH}/${FILEBASENAME} ${EXTRAPATH}/_${FILEBASENAME}" & _cp_pid=$!;
COPYPID=$!; $S $TOSSH "ln -s ${_target_path}/${_file_repl_name} ${_extra_path}/_${_file_repl_name}" &
else # no TOSSH else # no TOSSH
if [ ! -e "${TARGETPATH}" ]; then # path does not exist if [ ! -e "${_extra_path}" ]; then # path does not exist
mkdir -p "${TARGETPATH}"; mkdir -p "${_extra_path}";
fi fi
if [ -d "${TARGETPATH}" ]; then # check if target path exists as folder if [ -d "${_extra_path}" ]; then # check if target path exists as folder
cp -p "${FILESNPATHS[$FILE_C]}" "${TARGETPATH}/${FILEBASENAME}" & cp -p "${Files_N_Paths[$_fc]}" "${_extra_path}/${_file_repl_name}" &
COPYPID=$!; _cp_pid=$!;
ln -s "${_target_path}/${_file_repl_name}" "${_extra_path}/_${_file_repl_name}" &
else else
__logger $LLERROR "Unable to create ${TARGETPATH}! Skipping file ${FILESNPATHS[$FILE_C]}!"; logger $LLError "Unable to create ${_extra_path}! Skipping file ${Files_N_Paths[$_fc]}!";
((_miss_count+=1))
continue; continue;
fi fi
fi fi
ORIGINALFILES+=( ["${COPYPID}"]="${FILESNPATHS[$FILE_C]}" ); ((_dup_diff+=1))
TARGETFILES+=( ["${COPYPID}"]="${TARGETPATH}/${FILEBASENAME}" ); _original_files+=( ["${_cp_pid}"]="${Files_N_Paths[$_fc]}" );
DATETIMES+=( ["${COPYPID}"]="${DATETIME}" ); _target_files+=( ["${_cp_pid}"]="${_target_path}/${_file_repl_name}" );
_date_times+=( ["${_cp_pid}"]="${_datetime}" );
fi fi
done # Start copy loop done # copy loop
logger $LLMdtry "Tried to copy $_file_count files.\n$_done_count where already there,\n$_succ_count where copied of which $_dup_diff where of different size and got copied to the extra location,\n$_miss_count have different size after copy and\n$_fail_count could not be copied.";
} ## end main } ## end main
# Get the options from commandline # Get the options from commandline
while getopts ":hc:f:" option 2>/dev/null; do while getopts ":hc:f:" Option 2>/dev/null; do
case $option in case $Option in
h) # display Help h) # display Help
__usage usage
__cleanup 1 cleanup 1
;; ;;
c) # configuration file to use c) # configuration file to use
CONFFILE=$OPTARG; Conf_File=$OPTARG;
;; ;;
f) # folder to copy f) # folder to copy
CPFOLDER=$OPTARG; Cp_Folder=$OPTARG;
;; ;;
\?) \?)
echo "Invalid option: -$OPTARG"; echo "Invalid option: -$OPTARG";
@@ -297,81 +322,78 @@ while getopts ":hc:f:" option 2>/dev/null; do
esac esac
done done
if [[ -z "$CONFFILE" ]]; then if [[ -z "$Conf_File" ]]; then
echo "The option -c is mandatory! Provide a configuration file!"; echo "The option -c is mandatory! Provide a configuration file!";
__cleanup 1; cleanup 1;
fi fi
if [[ -f "${CONFFILE}" ]]; then if [[ -f "${Conf_File}" ]]; then
echo "Using configuration file $CONFFILE."; echo "Using configuration file $Conf_File.";
source $CONFFILE; source $Conf_File;
else else
echo "ERROR: $CONFFILE is not a file!"; echo "ERROR: $Conf_File is not a file!";
__cleanup 1; cleanup 1;
fi fi
if [[ -z "$CPFOLDER" ]]; then if [[ -z "$Cp_Folder" ]]; then
echo "The option -f is mandatory! Provide a folder to copy!"; echo "The option -f is mandatory! Provide a folder to copy!";
__cleanup 1; cleanup 1;
fi fi
if [[ -d "${CPFOLDER}" ]]; then if [[ -d "${Cp_Folder}" ]]; then
echo "Copying folder $CPFOLDER."; echo "Copying folder $Cp_Folder.";
else else
echo "ERROR: $CPFOLDER is not a folder!"; echo "ERROR: $Cp_Folder is not a folder!";
__cleanup 1; cleanup 1;
fi fi
## Check binaries availability ## Check binaries availability
__which_is SUDO 'sudo'; which_is SUDO 'sudo';
if [ $? -ne 0 ]; then echo $SUDO; exit 1; fi if [ $? -ne 0 ]; then echo $SUDO; exit 1; fi
__which_is DATE 'date'; which_is DATE 'date';
if [ $? -ne 0 ]; then echo $DATE; exit 1; fi if [ $? -ne 0 ]; then echo $DATE; exit 1; fi
__which_is LN 'ln'; which_is LN 'ln';
if [ $? -ne 0 ]; then echo $LN; exit 1; fi if [ $? -ne 0 ]; then echo $LN; exit 1; fi
__which_is RM 'rm'; which_is RM 'rm';
if [ $? -ne 0 ]; then echo $RM; exit 1; fi if [ $? -ne 0 ]; then echo $RM; exit 1; fi
__which_is SSH 'ssh'; which_is SSH 'ssh';
if [ $? -ne 0 ]; then echo $SSH; exit 1; fi if [ $? -ne 0 ]; then echo $SSH; exit 1; fi
__which_is TOUCH 'touch'; which_is TOUCH 'touch';
if [ $? -ne 0 ]; then echo $TOUCH; exit 1; fi if [ $? -ne 0 ]; then echo $TOUCH; exit 1; fi
__which_is CHOWN 'chown'; which_is CHOWN 'chown';
if [ $? -ne 0 ]; then echo $CHOWN; exit 1; fi if [ $? -ne 0 ]; then echo $CHOWN; exit 1; fi
__which_is EXIFTOOL 'exiftool'; which_is EXIFTOOL 'exiftool';
if [ $? -ne 0 ]; then echo $EXIFTOOL; exit 1; fi if [ $? -ne 0 ]; then echo $EXIFTOOL; exit 1; fi
__which_is NC 'nc'; which_is NC 'nc';
if [ $? -ne 0 ]; then echo $NC; exit 1; fi if [ $? -ne 0 ]; then echo $NC; exit 1; fi
RUNDATE=$($DATE +%Y_%m_%d) Run_Date=$($DATE +%Y_%m_%d)
LOGFILE="/tmp/${RUNDATE}_photosync.log"; Log_File="/tmp/${Run_Date}_photosync.log";
# Check if target is on remote server (TOSSH nonzero length) # Check if target is on remote server (TOSSH nonzero length)
if [ ! -z $TOSSH ]; then if [ ! -z $TOSSH ]; then
__logger $LLDEBUG "Will copy to »$TOSSH«!"; logger $LLDebug "Will copy to »$TOSSH«!";
# Check validity of ssh data # Check validity of ssh data
if [ "$SSHUSER" ] && [ "$SSHPORT" ]; then if [ "$SSHUSER" ] && [ "$SSHPORT" ]; then
S="$SSH -p $SSHPORT -l $SSHUSER"; S="$SSH -p $SSHPORT -l $SSHUSER";
else else
__logger $LLERROR "Invalid ssh command, port or user: »$SSH« »$SSHPORT« «$SSHUSER«"; logger $LLError "Invalid ssh command, port or user: »$SSH« »$SSHPORT« «$SSHUSER«";
__cleanup 1; cleanup 1;
fi fi
# Check availability of target server # Check availability of target server
$NC -z -w1 $TOSSH $SSHPORT > /dev/null $NC -z -w1 $TOSSH $SSHPORT > /dev/null
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
__logger $LLERROR "The server $TOSSH is not reachable."; logger $LLError "The server $TOSSH is not reachable.";
__cleanup 1; cleanup 1;
fi fi
fi fi
RUNDATE=$($DATE +%Y_%m_%d)
LOGFILE="/tmp/${RUNDATE}_cloud_photosync.log";
# Add slash to paths if missing # Add slash to paths if missing
if [ "${SYNC_TARGET:${#SYNC_TARGET}-1:1}" != "/" ]; then if [ "${SYNC_TARGET:${#SYNC_TARGET}-1:1}" != "/" ]; then
SYNC_TARGET=$SYNC_TARGET/ SYNC_TARGET=$SYNC_TARGET/
@@ -386,4 +408,6 @@ if [ "${CONFIG_NC_LOGPATH:${#CONFIG_NC_LOGPATH}-1:1}" != "/" ]; then
fi fi
# run the program after basics where checked. # run the program after basics where checked.
__main main
cleanup 0;