简体   繁体   中英

Analyzing Files in a Shell Script

I need to write a shell script that takes one or more arguments (filenames). Filenames should be handled corretly regardless of whether or not they contain spaces. For each file, the script should check if the file is readable, writeable, executable, is a plain file, and is a directory. For each of these checks, aa Y or N should be placed in the appropriate column. If the file does not exist, dashes "---" should be placed in each of the fields.

Example output: 
Read Write Execute Plain Dir Filename 
Y    Y     Y       Y     N   /tmp/testfiles/executable 
Y    Y     N       Y     N   /tmp/testfiles/file with spaces 
Y    N     N       Y     N   /tmp/testfiles/justread 
N    Y     N       Y     N   /tmp/testfiles/justwrite 
N    N     N       Y     N   /tmp/testfiles/noperms 
---  ---   ---     ---   --- /tmp/testfiles/nosuchfile 
Y    Y     N       Y     N   /tmp/testfiles/readwrite 
Y    Y     Y       N     Y   /tmp/testfiles/somedir

I am not very familiar with UNIX shell scripts, but after reading through various articles online, I came up with the following solution.

#! /bin/sh
echo Read Write Execute Plain Dir Filename
argnum=0
while $argnum < $# do
FileExists $($argnum)
PrintFileName $($argnum)
done

function FileExists()
{
if test -e $1
then
    IsReadable $1
    IsWritable $1
    IsExecutable $1
    IsPlain $1
    IsDir $1
else
    echo --- --- --- --- ---
}

function IsReadable()
{
if test -r $1
then
    echo Y
else
    echo N
}

function IsWritable()
{
if test -w $1
then
    echo Y
else
    echo N
}

function IsExecutable()
{
if test -x $1
then
    echo Y
else
    echo N
}

function IsPlain()
{
if test -f $1
then
    echo Y
else
    echo N
}

function IsDirectory()
{
if test -d $($argnum)
then
    echo Y
else
    echo N
}

function PrintFilename()
{
echo $1
}

Unfortunately, script doesn't execute properly. I know there are problems (especially with the formatting), but I'm not sure how to fix them. Any help/suggestions you have would be very much appreciated.

Read Write Execute Plain Dir Filename ./script: line 7: syntax error near unexpected token done' ./script: line 7: done'

Its because, you need a ; before do .

Bash scans from top to down, and executes every line. So in the top few lines, Bash does not know about FileExists and PrintFileName . So what you'd need to do is put the declarations before calling them.

function FileExists
{
...
}

function IsReadable
{
...
}
// more functions..

//Iterate here and call the above functions.

Cleaner way of iterating:

for var in "$@"
do
    FileExists $var
    PrintFileName $var
done

You might have problems with formatting because echo spits out a newline; and you might just not get things in a single line. use printf instead, and manually write out printf "\\n" manually.

Also, @devnull points out, fi is missing in every single instance of an if block.

while "function Name () " syntax works, I prefer the style returned by declare -f Name as my written form, since I use "declare -f name ..." to reproduce function bodies.

also, you might factor the "echo Y" and "echo N" from each function, simply returning the truth of the assertion. so, ...IsReadable, .. become:

  IsReadable () 
  {
      test -r $1
  }

and used

  IsReadable $1 && echo Y || echo N

since I don't find the "&&" (AND) and the "||" (OR) syntax too noisy. Also, i prefer this

  [[ -r $1 ]] && echo Y || echo N

So, my isreadable :

  isreadable () {  [[ test -r $1 ]] ; }

since i allow one-line exceptions to the "declare -f" rule, and even have a function, fbdy which does that: if the function body (less header, trailer) fits on one line, show it as a one-liner, otherwise, show it as the default.

Good to see you using functions. Keep it up. I mightily encourage their use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM