我需要编写一个带有一个或多个参数(文件名)的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
}
不幸的是,脚本无法正常执行。我知道有问题(特别是格式化),但我不知道如何解决它们。我们非常感谢您提供的任何帮助/建议。
答案 0 :(得分:4)
读写执行Plain Dir文件名./script:第7行:意外令牌完成附近的语法错误'./script:第7行:完成'
因为,;
之前需要do
。
Bash从上到下扫描,并执行每一行。因此,在前几行中,Bash不了解FileExists
和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
。
答案 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
如果函数体(较少的标题,尾部)适合一行,则将其显示为单行,否则,将其显示为默认值。
很高兴看到你使用功能。保持。我非常鼓励他们使用。