0

我需要编写一个带有一个或多个参数(文件名)的 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
}

不幸的是,脚本无法正确执行。我知道存在问题(尤其是格式问题),但我不确定如何解决它们。您的任何帮助/建议将不胜感激。

4

2 回答 2

4

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

这是因为,你需要一个;before do

Bash 从上到下扫描,并执行每一行。所以在前几行中,Bash 不知道FileExistsand PrintFileName。所以你需要做的是在调用它们之前放置声明。

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

于 2013-11-14T06:14:43.720 回答
0

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

此外,您可能会从每个函数中考虑“echo Y”和“echo N”,只需返回断言的真实性。所以,...IsReadable, .. 变成:

  IsReadable () 
  {
      test -r $1
  }

并使用

  IsReadable $1 && echo Y || echo N

因为我没有找到“&&”(AND)和“||” (OR) 语法太嘈杂。另外,我更喜欢这个

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

所以,我的isreadable

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

因为我允许“declare -f”规则的单行例外,甚至有一个函数,fbdy它可以做到这一点:如果函数体(更少的标题,拖车)适合一行,则将其显示为单行,否则, 显示为默认值。

很高兴看到你使用函数。保持。我强烈鼓励他们使用。

于 2014-02-21T16:15:05.600 回答