分析Shell脚本中的文件

时间:2013-11-14 05:57:12

标签: linux bash shell terminal sh

我需要编写一个带有一个或多个参数(文件名)的shell脚本。无论文件名是否包含空格,都应该正确处理。 对于每个文件,脚本应检查文件是否可读,可写,可执行,是纯文件,还是目录。对于每个检查,应将Y或N放在适当的列中。如果文件不存在,则应在每个字段中放置短划线“---”。

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

我对UNIX shell脚本不太熟悉,但在阅读了各种在线文章后,我想出了以下解决方案。

#! /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
}

不幸的是,脚本无法正常执行。我知道有问题(特别是格式化),但我不知道如何解决它们。我们非常感谢您提供的任何帮助/建议。

2 个答案:

答案 0 :(得分:4)

  

读写执行Plain Dir文件名./script:第7行:意外令牌完成附近的语法错误'./script:第7行:完成'

因为,;之前需要do

Bash从上到下扫描,并执行每一行。因此,在前几行中,Bash不了解FileExistsPrintFileName。所以你需要做的是将声明放在之前调用它们。

function FileExists
{
...
}

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

//Iterate here and call the above functions.

更清洁的迭代方式:

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

您可能会遇到格式化问题,因为echo会显示换行符;你可能只是不能把事情放在一条线上。请改用printf,然后手动手动写出printf "\n"

另外,@ devnull指出,fi块的每个实例都缺少if

答案 1 :(得分:0)

虽然“function Name()”语法有效,但我更喜欢declare -f Name返回的样式作为我的书面形式,因为我使用“declare -f name ...”来重现函数体。

另外,你可以将每个函数的“echo Y”和“echo N”因子分解,简单地返回断言的真实性。所以,... IsReadable,..成为:

  IsReadable () 
  {
      test -r $1
  }

并使用

  IsReadable $1 && echo Y || echo N

因为我找不到“&amp;&amp;” (AND)和“||” (或)语法太吵了。另外,我更喜欢这个

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

所以,我的isreadable

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

因为我允许对“declare -f”规则进行单行异常,甚至还有一个函数,fbdy 如果函数体(较少的标题,尾部)适合一行,则将其显示为单行,否则,将其显示为默认值。

很高兴看到你使用功能。保持。我非常鼓励他们使用。