#!/bin/sh # # Purpose {{{ # This script will try to get the list of directories that doesn't # have a owner known from the system # 1. … # … # # 2022-03-28 # }}} # Vars {{{ readonly PROGNAME=$(basename "${0}") readonly PROGDIR=$(readlink -m $(dirname "${0}")) readonly ARGS="${*}" readonly NBARGS="${#}" [ -z "${DEBUG}" ] && DEBUG=1 ## Export DEBUG for sub-script export DEBUG ## Colors readonly PURPLE='\033[1;35m' readonly RED='\033[0;31m' readonly RESET='\033[0m' readonly COLOR_DEBUG="${PURPLE}" # }}} usage() { # {{{ cat <<- HELP usage: $PROGNAME [-d|-h] Try to give a description… EXAMPLES : - Check the directories of the current place : ${PROGNAME} OPTIONS : --debug Enable debug messages. -h,--help Print this help message. HELP } # }}} debug_message() { # {{{ local_debug_message="${1}" ## Print message if DEBUG is enable (=0) [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG − ${PROGNAME} : ${local_debug_message}" unset local_debug_message return 0 } # }}} error_message() { # {{{ local_error_message="${1}" local_error_code="${2}" ## Print message printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}" exit "${local_error_code:=66}" } # }}} define_vars() { # {{{ ## If path_to_check wasn't defined (argument) {{{ if [ -z "${path_to_check}" ]; then ## Use default value readonly path_to_check=$(pwd) fi ## }}} ## Temp file vars {{{ full_dir_list_path="/tmp/${PROGNAME}.full.list" true > "${full_dir_list_path}" unknow_dir_list_path="/tmp/${PROGNAME}.unkwon.list" true > "${unknow_dir_list_path}" ## }}} } # }}} is_file_empty() { # {{{ local_file="${1}" ## File is empty by default return_is_file_empty="0" ## Check if the file is empty if [ ! -s "${local_file}" ]; then return_is_file_empty="0" debug_message "is_file_empty − \ The file ${RED}${local_file}${COLOR_DEBUG} is empty or doesn't exists." else return_is_file_empty="1" debug_message "is_file_empty − \ The file ${RED}${local_file}${COLOR_DEBUG} exists and has a size greater than zero." fi return "${return_is_file_empty}" } # }}} get_dir_list() { # {{{ ## Return False by default return_get_dir_list="1" ## Get directories and exclude hidden if command find "${path_to_check}" -mindepth 1 -maxdepth 1 -type d -not -iname '.*' -printf '%f\n' \ > "${full_dir_list_path}"; then debug_message "get_dir_list − \ ${RED}${path_to_check}${COLOR_DEBUG} directories list successfully created (see ${full_dir_list_path} file)." return_get_dir_list="0" else debug_message "get_dir_list − \ Error in ${RED}find${COLOR_DEBUG} command for ${path_to_check} directory." return_get_dir_list="1" fi return "${return_get_dir_list}" } # }}} main() { # {{{ ## Define all vars define_vars ## Get the list of all directories {{{ get_dir_list ## }}} ## Verify if directories list is empty {{{ ### And EXIT with error message is_file_empty "${full_dir_list_path}" \ && error_message "The directories list of ${path_to_check} is empty (${full_dir_list_path} file)." 10 ## }}} ## Parse directories list {{{ while IFS= read -r dir; do ### Get owner information {{{ debug_message "while loop - Try to get ${RED}${dir}${COLOR_DEBUG} owner information." dir_owner_name="$(stat -c "%U" "${path_to_check}/${dir}" \ || error_message "Can't stat ${path_to_check}/${dir} directory." 20)" ### }}} ### If owner is UNKNOWN {{{ if [ "${dir_owner_name}" = "UNKNOWN" ]; then debug_message "while loop - Owner of ${path_to_check}/${dir} directory is no longer available on this system (${RED}${dir_owner_name}${COLOR_DEBUG})." ### Add this directory to specific list printf '%b\n' "${path_to_check}/${dir}" >> "${unknow_dir_list_path}" ### }}} ### If owner is known from the system {{{ else debug_message "while loop - Owner of ${path_to_check}/${dir} directory is ${RED}${dir_owner_name}${COLOR_DEBUG}, skip this directory." fi ### }}} done < "${full_dir_list_path}" ## }}} ## Clean temp file {{{ ### full_dir_list_path if DEBUG is NOT enable [ ! "${DEBUG}" -eq "0" ] && rm --force -- "${full_dir_list_path}" ## }}} ## If unknow_dir_list_path doesn't contains anything {{{ ## Exit with success is_file_empty "${unknow_dir_list_path}" \ && debug_message "${path_to_check} doesn't contains any directory with unknown owner." \ && exit 0 ## }}} ## If some directories without owner are presents {{{ debug_message "${RED}${path_to_check}${COLOR_DEBUG} seems to contain some directories without owners. Please check the content of ${unknow_dir_list_path} file." ## }}} } # }}} # Manage arguments # {{{ # This code can't be in a function due to argument management if [ ! "${NBARGS}" -eq "0" ]; then manage_arg="0" ## If the first argument is not an option if ! printf -- '%s' "${1}" | grep -q -E -- "^-+"; then ## Print help message and exit printf '%b\n' "${RED}Invalid option: ${1}${RESET}" printf '%b\n' "---" usage exit 1 fi # Parse all options (start with a "-") one by one while printf -- '%s' "${1}" | grep -q -E -- "^-+"; do case "${1}" in --debug ) ## debug DEBUG=0 ;; -h|--help ) ## help usage ## Exit after help informations exit 0 ;; -d|--dir|--directory ) ## Define path_to_check with given arg ## Move to the next argument shift ## Define var readonly path_to_check="${1}" ;; * ) ## unknow option printf '%b\n' "${RED}Invalid option: ${1}${RESET}" printf '%b\n' "---" usage exit 1 ;; esac debug_message "Arguments management − \ ${RED}${1}${COLOR_DEBUG} option managed." ## Move to the next argument shift manage_arg=$((manage_arg+1)) done debug_message "Arguments management − \ ${RED}${manage_arg}${COLOR_DEBUG} argument(s) successfully managed." else debug_message "Arguments management − \ No arguments/options to manage." fi # }}} main exit 0