Читать интересную книгу Искусство программирования на языке сценариев командной оболочки - Мендель Купер

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 82 83 84 85 86 87 88 89 90 ... 96

All information about hard linked files are shared, except

for the names and the name's location in the directory system.

NOTE: A "Hard link" is known as a "File Alias" on some systems.

'-' An undistingushed file

Followed by three groups of letters for: User, Group, Others

Character 1: '-' Not readable; 'r' Readable

Character 2: '-' Not writable; 'w' Writable

Character 3, User and Group: Combined execute and special

'-' Not Executable, Not Special

'x' Executable, Not Special

's' Executable, Special

'S' Not Executable, Special

Character 3, Others: Combined execute and sticky (tacky?)

'-' Not Executable, Not Tacky

'x' Executable, Not Tacky

't' Executable, Tacky

'T' Not Executable, Tacky

Followed by an access indicator

Haven't tested this one, it may be the eleventh character

or it may generate another field

' ' No alternate access

'+' Alternate access

LSfieldsDoc

ListDirectory()

{

local -a T

local -i of=0 # Default return in variable

# OLD_IFS=$IFS # Using BASH default ' tn'

case "$#" in

3) case "$1" in

-of) of=1 ; shift ;;

* ) return 1 ;;

esac ;;

2) : ;; # Poor man's "continue"

*) return 1 ;;

esac

# NOTE: the (ls) command is NOT quoted (")

T=( $(ls --inode --ignore-backups --almost-all --directory

--full-time --color=none --time=status --sort=none

--format=long $1) )

case $of in

# Assign T back to the array whose name was passed as $2

0) eval $2=( "${T[@]}" ) ;;

# Write T into filename passed as $2

1) echo "${T[@]}" > "$2" ;;

esac

return 0

}

# # # # # Is that string a legal number? # # # # #

#

# IsNumber "Var"

# # # # # There has to be a better way, sigh...

IsNumber()

{

local -i int

if [ $# -eq 0 ]

then

return 1

else

(let int=$1) 2>/dev/null

return $? # Exit status of the let thread

fi

}

# # # # # Index Filesystem Directory Information # # # # #

#

# IndexList "Field-Array-Name" "Index-Array-Name"

# or

# IndexList -if Field-Array-Filename Index-Array-Name

# IndexList -of Field-Array-Name Index-Array-Filename

# IndexList -if -of Field-Array-Filename Index-Array-Filename

# # # # #

: << IndexListDoc

Walk an array of directory fields produced by ListDirectory

Having suppressed the line breaks in an otherwise line oriented

report, build an index to the array element which starts each line.

Each line gets two index entries, the first element of each line

(inode) and the element that holds the pathname of the file.

The first index entry pair (Line-Number==0) are informational:

Index-Array-Name[0] : Number of "Lines" indexed

Index-Array-Name[1] : "Current Line" pointer into Index-Array-Name

The following index pairs (if any) hold element indexes into

the Field-Array-Name per:

Index-Array-Name[Line-Number * 2] : The "inode" field element.

NOTE: This distance may be either +11 or +12 elements.

Index-Array-Name[(Line-Number * 2) + 1] : The "pathname" element.

NOTE: This distance may be a variable number of elements.

Next line index pair for Line-Number+1.

IndexListDoc

IndexList()

{

local -a LIST # Local of listname passed

local -a -i INDEX=( 0 0 ) # Local of index to return

local -i Lidx Lcnt

local -i if=0 of=0 # Default to variable names

case "$#" in # Simplistic option testing

0) return 1 ;;

1) return 1 ;;

2) : ;; # Poor man's continue

3) case "$1" in

-if) if=1 ;;

-of) of=1 ;;

* ) return 1 ;;

esac ; shift ;;

4) if=1 ; of=1 ; shift ; shift ;;

*) return 1

esac

# Make local copy of list

case "$if" in

0) eval LIST=( "${$1[@]}" ) ;;

1) LIST=( $(cat $1) ) ;;

esac

# Grok (grope?) the array

Lcnt=${#LIST[@]}

Lidx=0

until (( Lidx >= Lcnt ))

do

if IsNumber ${LIST[$Lidx]}

then

local -i inode name

local ft

inode=Lidx

local m=${LIST[$Lidx+2]} # Hard Links field

ft=${LIST[$Lidx+1]:0:1} # Fast-Stat

case $ft in

b) ((Lidx+=12)) ;; # Block device

c) ((Lidx+=12)) ;; # Character device

*) ((Lidx+=11)) ;; # Anything else

esac

name=Lidx

case $ft in

-) ((Lidx+=1)) ;; # The easy one

b) ((Lidx+=1)) ;; # Block device

c) ((Lidx+=1)) ;; # Character device

d) ((Lidx+=1)) ;; # The other easy one

l) ((Lidx+=3)) ;; # At LEAST two more fields

# A little more elegance here would handle pipes,

#+ sockets, deleted files - later.

*) until IsNumber ${LIST[$Lidx]} || ((Lidx >= Lcnt))

do

((Lidx+=1))

done

;; # Not required

esac

INDEX[${#INDEX[*]}]=$inode

INDEX[${#INDEX[*]}]=$name

INDEX[0]=${INDEX[0]}+1 # One more "line" found

# echo "Line: ${INDEX[0]} Type: $ft Links: $m Inode:

# ${LIST[$inode]} Name: ${LIST[$name]}"

else

((Lidx+=1))

fi

done

case "$of" in

0) eval $2=( "${INDEX[@]}" ) ;;

1) echo "${INDEX[@]}" > "$2" ;;

esac

return 0 # What could go wrong?

}

# # # # # Content Identify File # # # # #

#

# DigestFile Input-Array-Name Digest-Array-Name

# or

# DigestFile -if Input-FileName Digest-Array-Name

# # # # #

# Here document used as a comment block.

: <<DigestFilesDoc

The key (no pun intended) to a Unified Content File System (UCFS)

is to distinguish the files in the system based on their content.

Distinguishing files by their name is just, so, 20th Century.

The content is distinguished by computing a checksum of that content.

This version uses the md5sum program to generate a 128 bit checksum

representative of the file's contents.

There is a chance that two files having different content might

generate the same checksum using md5sum (or any checksum). Should

that become a problem, then the use of md5sum can be replace by a

cyrptographic signature. But until then...

The md5sum program is documented as outputting three fields (and it

does), but when read it appears as two fields (array elements). This

is caused by the lack of whitespace between the second and third field.

So this function gropes the md5sum output and returns:

[0] 32 character checksum in hexidecimal (UCFS filename)

[1] Single character: ' ' text file, '*' binary file

[2] Filesystem (20th Century Style) name

Note: That name may be the character '-' indicating STDIN read.

DigestFilesDoc

DigestFile()

{

local if=0 # Default, variable name

local -a T1 T2

case "$#" in

3) case "$1" in

-if) if=1 ; shift ;;

* ) return 1 ;;

esac ;;

2) : ;; # Poor man's "continue"

*) return 1 ;;

esac

case $if in

0) eval T1=( "${$1[@]}" )

T2=( $(echo ${T1[@]} | md5sum -) )

;;

1) T2=( $(md5sum $1) )

;;

esac

case ${#T2[@]} in

0) return 1 ;;

1) return 1 ;;

2) case ${T2[1]:0:1} in # SanScrit-2.0.5

*) T2[${#T2[@]}]=${T2[1]:1}

T2[1]=*

;;

*) T2[${#T2[@]}]=${T2[1]}

T2[1]=" "

;;

esac

;;

3) : ;; # Assume it worked

*) return 1 ;;

esac

local -i len=${#T2[0]}

if [ $len -ne 32 ] ; then return 1 ; fi

eval $2=( "${T2[@]}" )

}

# # # # # Locate File # # # # #

#

# LocateFile [-l] FileName Location-Array-Name

# or

# LocateFile [-l] -of FileName Location-Array-FileName

# # # # #

# A file location is Filesystem-id and inode-number

# Here document used as a comment block.

: <<StatFieldsDoc

Based on stat, version 2.2

stat -t and stat -lt fields

[0] name

[1] Total size

File - number of bytes

Symbolic link - string length of pathname

[2] Number of (512 byte) blocks allocated

[3] File type and Access rights (hex)

[4] User ID of owner

[5] Group ID of owner

[6] Device number

[7] Inode number

[8] Number of hard links

[9] Device type (if inode device) Major

[10] Device type (if inode device) Minor

[11] Time of last access

May be disabled in 'mount' with noatime

atime of files changed by exec, read, pipe, utime, mknod (mmap?)

atime of directories changed by addition/deletion of files

[12] Time of last modification

mtime of files changed by write, truncate, utime, mknod

mtime of directories changed by addtition/deletion of files

[13] Time of last change

ctime reflects time of changed inode information (owner, group

permissions, link count

-*-*- Per:

Return code: 0

Size of array: 14

Contents of array

Element 0: /home/mszick

Element 1: 4096

Element 2: 8

Element 3: 41e8

Element 4: 500

Element 5: 500

Element 6: 303

Element 7: 32385

Element 8: 22

Element 9: 0

Element 10: 0

Element 11: 1051221030

Element 12: 1051214068

Element 13: 1051214068

For a link in the form of linkname -> realname

stat -t linkname returns the linkname (link) information

stat -lt linkname returns the realname information

stat -tf and stat -ltf fields

[0] name

[1] ID-0? # Maybe someday, but Linux stat structure

[2] ID-0? # does not have either LABEL nor UUID

# fields, currently information must come

# from file-system specific utilities

These will be munged into:

[1] UUID if possible

[2] Volume Label if possible

Note: 'mount -l' does return the label and could return the UUID

[3] Maximum length of filenames

[4] Filesystem type

[5] Total blocks in the filesystem

[6] Free blocks

[7] Free blocks for non-root user(s)

[8] Block size of the filesystem

[9] Total inodes

[10] Free inodes

-*-*- Per:

Return code: 0

Size of array: 11

Contents of array

Element 0: /home/mszick

Element 1: 0

Element 2: 0

Element 3: 255

Element 4: ef53

Element 5: 2581445

Element 6: 2277180

Element 7: 2146050

Element 8: 4096

Element 9: 1311552

Element 10: 1276425

StatFieldsDoc

# LocateFile [-l] FileName Location-Array-Name

# LocateFile [-l] -of FileName Location-Array-FileName

LocateFile()

{

local -a LOC LOC1 LOC2

local lk="" of=0

case "$#" in

0) return 1 ;;

1) return 1 ;;

2) : ;;

*) while (( "$#" > 2 ))

do

case "$1" in

-l) lk=-1 ;;

-of) of=1 ;;

*) return 1 ;;

esac

shift

done ;;

esac

# More Sanscrit-2.0.5

# LOC1=( $(stat -t $lk $1) )

# LOC2=( $(stat -tf $lk $1) )

# Uncomment above two lines if system has "stat" command installed.

LOC=( ${LOC1[@]:0:1} ${LOC1[@]:3:11}

${LOC2[@]:1:2} ${LOC2[@]:4:1} )

case "$of" in

0) eval $2=( "${LOC[@]}" ) ;;

1) echo "${LOC[@]}" > "$2" ;;

esac

return 0

# Which yields (if you are lucky, and have "stat" installed)

# -*-*- Location Discriptor -*-*-

# Return code: 0

# Size of array: 15

# Contents of array

# Element 0: /home/mszick 20th Century name

1 ... 82 83 84 85 86 87 88 89 90 ... 96
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Искусство программирования на языке сценариев командной оболочки - Мендель Купер.
Книги, аналогичгные Искусство программирования на языке сценариев командной оболочки - Мендель Купер

Оставить комментарий