Home About BC DR HA Support Training Download
You are here: Home/ Downloads/ Scripts/ Korn/ Please Login or Register

-
Current Location
-

js
  Downloads
    Scripts
      Korn



-
 Mt Xia Inc.
-
BOOK:Advanced Shell Scripting



 Join our LinkedIn Group
AIX Advanced Technical Experts
Contract Opportunities

www.LinkedIn.com
-
 Train By Tweet
Training courses Tweet By Tweet
Various Subjects and Products
TrainByTweet.com


AIX Admin Methodology
Global Consolidation Project
All AIX admins should join
www.aixexpert.com
-

digg Digg this page
del.icio.us Post to del.icio.us
Slashdot Slashdot it!
This script builds arrays of values representing directory and file names, with owner, group, and permissions. It will also generate the commands necessary to recreate the directory structure, and to restore the owner, group, and permissions to all directories and files under a top level directory.

(ksh93 version)   (bash version)   (multi-shell version)



#!/usr/bin/ksh93
#!/bin/zsh
#!/bin/bash
################################################################
#### 
#### This script will run in KornShell93, Zshell, or Bash, all you need to do 
#### is put the desired "shebang" line at the top of the script.
#### 
################################################################
function usagemsg_getfilestruct_zbksh {
  CMD_ECHO="${GBL_ECHO:-echo -e }"
  [[ "_${SHCODE}" == "_korn" ]] && typeset CMD_ECHO="${GBL_ECHO:-echo -e }"
  [[ "_${SHCODE}" == "_bash" ]] && declare CMD_ECHO="${GBL_ECHO:-echo -e }"
  ${CMD_ECHO} ""
  ${CMD_ECHO} "${1:+Program: ${1}}${2:+        Version: ${2}}"
  ${CMD_ECHO} ""
  ${CMD_ECHO} "This script builds arrays of values representing directory and file"
  ${CMD_ECHO} "names, with owner, group, and permissions. It will also generate the"
  ${CMD_ECHO} "commands necessary to recreate the directory structure, and to restore"
  ${CMD_ECHO} "the owner, group, and permissions to all directories and files under a"
  ${CMD_ECHO} "top level directory."
  ${CMD_ECHO} ""
  ${CMD_ECHO} "Usage: ${1} [-v|-V] [-a] [-c] [-s] [-d|-f] [-R /Alt_Root] TopDir"
  ${CMD_ECHO} ""
  ${CMD_ECHO} "    Where '-v' = Verbose mode"
  ${CMD_ECHO} "          '-V' = Very Verbose mode"
  ${CMD_ECHO} "          '-a' = Generate Arrays of values as Output"
  ${CMD_ECHO} "                           (Default: array definitions)"
  ${CMD_ECHO} "          '-c' = Generate commands to create directory structures"
  ${CMD_ECHO} "                           (Default: array definitions)"
  ${CMD_ECHO} "          '-s' = Generate commands to create Symbolic Links"
  ${CMD_ECHO} "                           (Default: OFF)"
  ${CMD_ECHO} "          '-d' = Only gather directory structure information"
  ${CMD_ECHO} "                           (Default: Files and Directories)"
  ${CMD_ECHO} "          '-f' = Only gather file information"
  ${CMD_ECHO} "                           (Default: Files and Directories)"
  ${CMD_ECHO} "          '-R /ALT_ROOT' = Add an alternate root directory to every path"
  ${CMD_ECHO} "                           This directory does not need to actually exist"
  ${CMD_ECHO} "                           Useful for chroot'ed dirs or ALT_DISK filesystems"
  ${CMD_ECHO} "                           (Default: NUL)"
  ${CMD_ECHO} ""
  ${CMD_ECHO} "        TopDir = The full path directory name from which to"
  ${CMD_ECHO} "                 extract the directory and file structure"
  ${CMD_ECHO} ""
  ${CMD_ECHO} "Author: Dana French (dfrench@mtxia.com)"
  ${CMD_ECHO} "Copyright 2007-2015, All Rights Reserved"
  ${CMD_ECHO} ""
  ${CMD_ECHO} "\"AutoContent\" enabled"
  ${CMD_ECHO} "\"Multi-Shell\" enabled"
  ${CMD_ECHO} ""
}
################################################################
#### 
#### Description:
#### 
#### This script builds arrays of values representing directory and file
#### names, with owner, group, and permissions. It will also generate the
#### commands necessary to recreate the directory structure, and to restore
#### the owner, group, and permissions to all directories and files under a
#### top level directory.
#### 
#### This script can operate in two modes: Array or Command generating.
#### In "Array" mode, KornShell93/Bash code is generated is used
#### to define an array of values containing the directory information
#### and attributes.  In "Command" mode, unix style commands are generated
#### to recreate the directory structure and attributes.  The default is
#### "Array" mode.
#### 
#### Assumptions:
#### 
#### If you are using this script to build arrays of values, it is assumed
#### the number of files in the specified top level directory will be limited
#### on only a few thousand.  This is because the values are stored in shell
#### variable arrays which are  limited in size, depending upon the platform.
#### You will need to test this on your own system to determine the actual
#### limitations.
#### 
#### Dependencies:
#### 
#### This script is dependent upon the following Unix utilities:
####     ksh93, bash, or zsh
####     ls
####     find
####     uname
#### 
#### Products:
#### 
#### This script generates KornShell93/Bash Compliant commands that can
#### be used to define an array of values, or this script can generate
#### Unix commands to create the directory structure and its attributes.
#### 
#### Configured Usage:
#### 
#### This script can be run from the command line, used as a function, or
#### called from a function library.
#### 
#### Details:
#### 
################################################################
function getfilestruct_zbksh
{

if [[ "_${SHCODE}" == "_korn"   ]] ||
   [[ "_${SHCODE}" == "_zshell" ]]
then
  typeset VERSION="3.1-zbksh"
  typeset TRUE="${TRUE:-1}"
  typeset FALSE="${FALSE:-0}"
  typeset CMD_ECHO="${GBL_ECHO:-echo -e }"
  typeset VERBOSE="${FALSE}"
  typeset VERYVERB="${FALSE}"
  typeset GENCMDS="${FALSE}"
  typeset GENSLNK="${FALSE}"
  typeset GENARYS="${FALSE}"
  typeset SHWDIRS="${TRUE}"
  typeset SHWFILS="${TRUE}"
  typeset DCNT="0"
  typeset FCNT="0"
  typeset SCNT="0"
  typeset ALT_ROOT=""
  typeset CMD=""
  typeset DGROUP
  typeset DIRID1
  typeset DIRIDX
  typeset DIRNAME
  typeset DMODE
  typeset DOWNER
  typeset GPERMS
  typeset LNAME
  typeset MACHNAME
  typeset OPERMS
  typeset PERMS
  typeset RAWFNAME
  typeset RAWGROUP
  typeset RAWOWNER
  typeset RAWPERMS
  typeset SNAME
  typeset UPERMS
elif [[ "_${SHCODE}" == "_bash" ]]
then
  declare VERSION="3.1-zbksh"
  declare TRUE="${TRUE:-1}"
  declare FALSE="${FALSE:-0}"
  declare CMD_ECHO="${GBL_ECHO:-echo -e }"
  declare VERBOSE="${FALSE}"
  declare VERYVERB="${FALSE}"
  declare GENCMDS="${FALSE}"
  declare GENSLNK="${FALSE}"
  declare GENARYS="${FALSE}"
  declare SHWDIRS="${TRUE}"
  declare SHWFILS="${TRUE}"
  declare DCNT="0"
  declare FCNT="0"
  declare SCNT="0"
  declare ALT_ROOT=""
  declare CMD=""
  declare DGROUP
  declare DIRID1
  declare DIRIDX
  declare DIRNAME
  declare DMODE
  declare DOWNER
  declare GPERMS
  declare LNAME
  declare MACHNAME
  declare OPERMS
  declare PERMS
  declare RAWFNAME
  declare RAWGROUP
  declare RAWOWNER
  declare RAWPERMS
  declare SNAME
  declare UPERMS
else
  VERSION="3.1-zbksh"
  TRUE="${TRUE:-1}"
  FALSE="${FALSE:-0}"
  CMD_ECHO="${GBL_ECHO:-echo -e }"
  VERBOSE="${FALSE}"
  VERYVERB="${FALSE}"
  GENCMDS="${FALSE}"
  GENSLNK="${FALSE}"
  GENARYS="${FALSE}"
  SHWDIRS="${TRUE}"
  SHWFILS="${TRUE}"
  DCNT="0"
  FCNT="0"
  SCNT="0"
  ALT_ROOT=""
  CMD=""
fi

################################################################

while getopts ":vVcasdfR:" OPTION
do
    case "${OPTION}" in
        'a') GENARYS="${TRUE}";;
        'c') GENCMDS="${TRUE}";;
        's') GENSLNK="${TRUE}";;
        'd') SHWFILS="${FALSE}";;   # Yes, -d turns off showing files
        'f') SHWDIRS="${FALSE}";;   # Yes, -f turns off showing dirs
        'R') ALT_ROOT="${OPTARG}";;
        'v') VERBOSE="${TRUE}";;
        'V') VERBOSE="${TRUE}"
             VERYVERB="${TRUE}";;
        '?') usagemsg_getfilestruct_zbksh "${0}" "${VERSION}" && return 1 ;;
    esac
done
 
shift $(( ${OPTIND} - 1 ))

################################################################

trap "usagemsg_getfilestruct_zbksh ${0} ${VERSION} " EXIT
MACHNAME=$( uname -n )
DIRID1="${1:?ERROR: Top level directory not specified}"

if [[ ! -d "${DIRID1}" ]]
then
    ${CMD_ECHO} "# ERROR: \"${DIRID1}\" is not a directory or does not exist"
    return 4
fi

if (( GENARYS == FALSE )) &&
   (( GENCMDS == FALSE ))
then
    GENARYS="${TRUE}"
fi

if (( SHWFILS == FALSE )) &&
   (( SHWDIRS == FALSE ))
then
    ${CMD_ECHO} "# ERROR: Do not specify both -d and -f, you must specify one or the other, or neither."
    return 2
fi

trap "-" EXIT

################################################################

DCNT="0"
FCNT="0"
SCNT="0"
DIRIDX="${DIRID1##*/}"
(( ${#DIRIDX} > 8 )) && DIRIDX="${DIRIDX:0:8}"

(( VERBOSE == TRUE )) && ${CMD_ECHO} "${SHEBANG:-#!/usr/bin/ksh93}"
(( VERBOSE == TRUE )) && ${CMD_ECHO} "################################################################"
(( VERBOSE == TRUE )) && ${CMD_ECHO} "# Program Name..........: ${0}"
(( VERBOSE == TRUE )) && ${CMD_ECHO} "# Version...............: ${VERSION}"
(( VERBOSE == TRUE )) && ${CMD_ECHO} "# Script Execution Mode.: ${SHCODE}"
(( VERBOSE == TRUE )) && ${CMD_ECHO} "# Copyright Info........: Copyright 2007-2015 by Dana French, All Rights Reserved"
(( VERBOSE == TRUE )) && ${CMD_ECHO} "# Local hostname........: ${MACHNAME}"
(( VERBOSE == TRUE )) && ${CMD_ECHO} "# Top Level Directory...: ${DIRID1}"
(( VERBOSE == TRUE )) && ${CMD_ECHO} "# Variable index name...: ${DIRIDX}"

(( VERBOSE == TRUE )) && (( SHWFILS == TRUE  )) && ${CMD_ECHO} "# Show Files............: TRUE"
(( VERBOSE == TRUE )) && (( SHWFILS == FALSE )) && ${CMD_ECHO} "# Show Files............: FALSE"

(( VERBOSE == TRUE )) && (( SHWDIRS == TRUE  )) && ${CMD_ECHO} "# Show Directories......: TRUE"
(( VERBOSE == TRUE )) && (( SHWDIRS == FALSE )) && ${CMD_ECHO} "# Show Directories......: FALSE"

(( VERBOSE == TRUE )) && (( GENCMDS == TRUE  )) && ${CMD_ECHO} "# Generate Commands.....: TRUE"
(( VERBOSE == TRUE )) && (( GENCMDS == FALSE )) && ${CMD_ECHO} "# Generate Commands.....: FALSE"

(( VERBOSE == TRUE )) && (( GENARYS == TRUE  )) && ${CMD_ECHO} "# Generate Arrays.......: TRUE"
(( VERBOSE == TRUE )) && (( GENARYS == FALSE )) && ${CMD_ECHO} "# Generate Arrays.......: FALSE"

(( VERBOSE == TRUE )) && (( GENSLNK == TRUE  )) && ${CMD_ECHO} "# Generate Sym Link CMDS: TRUE"
(( VERBOSE == TRUE )) && (( GENSLNK == FALSE )) && ${CMD_ECHO} "# Generate Sym Link CMDS: FALSE"

${CMD_ECHO} ""
${CMD_ECHO} "ALT_ROOT=\"${ALT_ROOT}\""

################################################################
#### 
#### The first thing the "getfilestruct" script does is to execute a "find"
#### command to retrieve all the directories under the top level directory
#### specified on the  command line when the script was run.  The "find"
#### command produces "ls -ld" style output for the purpose of extracting and
#### processing the attributes associated with each directory.
#### 
################################################################

(( SHWFILS == FALSE )) && (( SHWDIRS == TRUE  )) && CMD='find "${DIRID1%/}" -type d -exec ls -ld {} \;'
(( SHWFILS == TRUE  )) && (( SHWDIRS == FALSE )) && CMD='find "${DIRID1%/}" ! -type d -exec ls -ld {} \;'
(( SHWFILS == TRUE  )) && (( SHWDIRS == TRUE  )) && CMD='find "${DIRID1%/}" -exec ls -ld {} \;'
(( SHWFILS == FALSE )) && (( SHWDIRS == FALSE )) && return 3

eval ${CMD} | while read -r -- RAWPERMS RAWLINKS RAWOWNER RAWGROUP RAWSIZE RAWDATE1 RAWDATE2 RAWDATE3 RAWFNAME
do

################################################################
#### 
#### If the file is a symbolic link, generate the command to recreate the
#### symbolic link and continue with the next file.
####
################################################################

  if [[ "_${RAWPERMS}" == _l* ]]
  then
      LNAME="${RAWFNAME##* -> }"
      SNAME="${RAWFNAME% -> *}"

      [[ "_${LNAME}" != _/* ]] && LNAME="${SNAME%/*}/${LNAME}"

      if (( GENARYS == TRUE ))
      then
          ${CMD_ECHO} "\n#### symbolic link \"${RAWFNAME}\""
          ${CMD_ECHO} "SYM_${DIRIDX}_SNAME[${SCNT}]=\"\${ALT_ROOT}${SNAME}\""
          ${CMD_ECHO} "SYM_${DIRIDX}_FLINK[${SCNT}]=\"\${ALT_ROOT}${LNAME}\""
          SCNT=$(( ${SCNT} + 1 ))
      fi

      if (( GENSLNK == TRUE ))
      then
          ${CMD_ECHO} "\n#### Generate symbolic link \"${RAWFNAME}\""
          ${CMD_ECHO} "ln -s \"${LNAME}\" \"${SNAME}\""
      else
          ${CMD_ECHO} "\n#### Skipping symbolic link \"${RAWFNAME}\""
          ${CMD_ECHO} "# ln -s \"${LNAME}\" \"${SNAME}\""
      fi

      continue
  fi

################################################################
#### 
#### The file owner and group are easily
#### extracted from the "ls -ld" output, however the permissions require
#### some processing.
#### 
################################################################

# extract the owner for the directory from the ls -l output
    DOWNER="${RAWOWNER}"
# extract the group for the directory from the ls -l output
    DGROUP="${RAWGROUP}"
# extract the permission settings for the directory from the ls -l output
    PERMS="${RAWPERMS:1:9}"

# extract the name of the directory from the ls -l output
    DIRNAME="${RAWFNAME}"
    [[ "_${DIRNAME}" == *lost+found ]] && continue

################################################################
#### 
#### The permission settings are contained within the first 10 characters
#### of the "ls -ld" output and are processed in 3 steps. The first character
#### is the file type and is ignored, the next 3 characters are associated
#### with the "user" or file owner permissions.  The permissions are
#### checked to see if the tacky bit or SUID bit is set.  If so
#### the appropriate permission setting is added to the permission string
#### which will be used when directory permissions are set.
#### 
################################################################

# extract the user permission settings for the directory from the ls -ld output
    UPERMS="${PERMS:0:3}"
# remove the dashes "-" from the user permissions
    UPERMS="${UPERMS//\-/}"
# Convert lowercase "s" to "xs" in the user permissions
    UPERMS="${UPERMS//s/xs}"
# Convert uppercase "S" to "s" in the user permissions
    UPERMS="${UPERMS//S/s}"
# Convert lowercase "t" to "xt" in the user permissions
    UPERMS="${UPERMS//t/xt}"
# Convert uppercase "T" to "t" in the user permissions
    UPERMS="${UPERMS//T/t}"

################################################################
#### 
#### The next set of 3 characters are associated with the "group" 
#### category of permissions.  The permissions are checked to see 
#### if the tacky bit or SUID bit is set.  If so the appropriate 
#### permission setting is added to the permission string which will 
#### be used when the directory permissions are set.
#### 
################################################################

# extract the group permission settings for the directory from the ls -ld output
    GPERMS="${PERMS:3:3}"
# remove the dashes "-" from the group permissions
    GPERMS="${GPERMS//\-/}"
# Convert lowercase "s" to "xs" in the group permissions
    GPERMS="${GPERMS//s/xs}"
# Convert uppercase "S" to "s" in the group permissions
    GPERMS="${GPERMS//S/s}"
# Convert lowercase "t" to "xt" in the group permissions
    GPERMS="${GPERMS//t/xt}"
# Convert uppercase "T" to "t" in the group permissions
    GPERMS="${GPERMS//T/t}"

################################################################
#### 
#### The last set of 3 characters are associated with the "other" 
#### category of permissions.  Again, the permissions are checked to see 
#### if the tacky bit or SUID bit is set.  If so the appropriate permission 
#### setting is added to the permission string which will be used when the 
#### directory permissions are set.
#### 
################################################################

# extract the other permission settings for the directory from the ls -ld output
    OPERMS="${PERMS:6:3}"
# remove the dashes "-" from the other permissions
    OPERMS="${OPERMS//\-/}"
# Convert lowercase "s" to "xs" in the other permissions
    OPERMS="${OPERMS//s/xs}"
# Convert uppercase "S" to "s" in the other permissions
    OPERMS="${OPERMS//S/s}"
# Convert lowercase "t" to "xt" in the other permissions
    OPERMS="${OPERMS//t/xt}"
# Convert uppercase "T" to "t" in the other permissions
    OPERMS="${OPERMS//T/t}"

################################################################
#### 
#### With the permission setting strings for each user category now known
#### and extracted from the "ls -ld" output, a mnemonic "exact setting"
#### string is constructed for use with the "chmod" command.
#### 
################################################################

# Build the mnemonic mode exact permission setting command
    DMODE="u=${UPERMS},g=${GPERMS},o=${OPERMS}"

    (( VERBOSE == TRUE )) && ${CMD_ECHO} "\n#### \n#### ${MACHNAME}:${DMODE}:${DOWNER}:${DGROUP}:${DIRNAME}"

################################################################
#### Depending upon the options specified when this script was run,
#### either KornShell93/Bash compliant commands or Unix commands will
#### be generated.
#### 
#### The generated KornShell93/Bash Compliant commands can be used to 
#### define a variable array of values which contain the directory name 
#### and various attributes associated with each directory.
#### 
#### The Unix commands generated consist of mkdir, chown, chgrp, and 
#### chmod, which can be used to create the directory and change its 
#### attributes to match those of the original directory.
#### 
################################################################

    if [[ -d "${DIRNAME}" ]]
    then

        (( VERBOSE == TRUE )) && ${CMD_ECHO} "\n${CMD_ECHO} \"# Working on ${DIRNAME}\""

        if (( GENARYS == TRUE ))
        then
            ${CMD_ECHO} "DIR_${DIRIDX}_DNAME[${DCNT}]=\"\${ALT_ROOT}${DIRNAME}\";"
            ${CMD_ECHO} "DIR_${DIRIDX}_OWNER[${DCNT}]=\"${DOWNER}\";"
            ${CMD_ECHO} "DIR_${DIRIDX}_GROUP[${DCNT}]=\"${DGROUP}\";"
            ${CMD_ECHO} "DIR_${DIRIDX}_CHMOD[${DCNT}]=\"${DMODE}\";"
        fi

        if (( GENCMDS == TRUE ))
        then
            ${CMD_ECHO} "mkdir -p \"\${ALT_ROOT}${DIRNAME}\";"
            ${CMD_ECHO} "chown ${DOWNER} \"\${ALT_ROOT}${DIRNAME}\";"
            ${CMD_ECHO} "chgrp ${DGROUP} \"\${ALT_ROOT}${DIRNAME}\";"
            ${CMD_ECHO} "chmod \"${DMODE}\" \"\${ALT_ROOT}${DIRNAME}\";"
        fi

        DCNT=$(( ${DCNT} + 1 ))

    else

        if (( GENARYS == TRUE ))
        then
            ${CMD_ECHO} "FIL_${DIRIDX}_FNAME[${FCNT}]=\"\${ALT_ROOT}${DIRNAME}\";"
            ${CMD_ECHO} "FIL_${DIRIDX}_OWNER[${FCNT}]=\"${DOWNER}\";"
            ${CMD_ECHO} "FIL_${DIRIDX}_GROUP[${FCNT}]=\"${DGROUP}\";"
            ${CMD_ECHO} "FIL_${DIRIDX}_CHMOD[${FCNT}]=\"${DMODE}\";"
        fi

        if (( GENCMDS == TRUE ))
        then
            ${CMD_ECHO} "chown ${DOWNER} \"\${ALT_ROOT}${DIRNAME}\";"
            ${CMD_ECHO} "chgrp ${DGROUP} \"\${ALT_ROOT}${DIRNAME}\";"
            ${CMD_ECHO} "chmod \"${DMODE}\" \"\${ALT_ROOT}${DIRNAME}\";"
        fi

        FCNT=$(( ${FCNT} + 1 ))

    fi

  done

return 0

}
################################################################
################################################################
################################################################
#### 
#### Main Body of Script Begins Here
#### 
################################################################

TRUE="1"
FALSE="0"

#### 
#### Extract the "shebang" line from the beginning of the script

read SHEBANG < "${0}"
export SHEBANG

#### 
#### Test the "shebang" line to determine what shell interpreter is specified

SHCODE="unknown"
[[ "_${SHEBANG}" == _*/ksh*  ]] && SHCODE="korn"
[[ "_${SHEBANG}" == _*/bash* ]] && SHCODE="bash"
[[ "_${SHEBANG}" == _*/zsh*  ]] && SHCODE="zshell"
export SHCODE

#### 
#### Modify the commands and script according to the shell intpreter

GBL_ECHO="echo -e"
[[ "_${SHCODE}" == "_korn"   ]] && GBL_ECHO="print --"
[[ "_${SHCODE}" == "_zshell" ]] && GBL_ECHO="print --" && emulate ksh93
[[ "_${SHCODE}" == "_bash"   ]] && shopt -s extglob    # Turn on extended globbing

#### 
#### Call the script function to begin processing

getfilestruct_zbksh "${@}"

exit ${?}


-
Gather Dir/File Perms
-