2013-11-14 3 views
0

Мне нужно написать сценарий оболочки, который принимает один или несколько аргументов (имена файлов). Имена файлов должны обрабатываться корректно независимо от того, содержат ли они пробелы. Для каждого файла сценарий должен проверять, является ли файл доступным для чтения, записываемый, исполняемый, является простым файлом и является каталогом. Для каждой из этих проверок a или Y следует помещать в соответствующий столбец. Если файл не существует, в каждом из полей должны быть помечены символы «---».Анализ файлов в командной оболочке

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, но после прочтения различных статей в Интернете, я придумал следующее решением.

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

«К сожалению, сценарий не выполняется должным образом». Что правильно? Можете ли вы присоединить текущий вывод? – SuperSaiyan

+0

Чтение Write Execute Plain Dir Filename ./script: строка 7: ошибка синтаксиса рядом с неожиданным токеном 'done ' ./script: строка 7:' done' – user2990676

+0

Вам нужно добавить «или» вокруг строк, чтобы избежать проблем с whitespace. – Johan

ответ

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 "[email protected]" 
do 
    FileExists $var 
    PrintFileName $var 
done 

Вы можете иметь проблемы с форматированием, потому что эхо выплевывает символ новой строки; и вы можете просто не получить вещи в одной строке. используйте вместо этого printf и вручную выпишите printf "\n" вручную.

Кроме того, @devnull указывает, fi отсутствует в каждом экземпляре блока if.

+0

Спасибо! Скрипт теперь выполняется правильно, если аргументы не переданы. Если какие-либо имена файлов переданы, я получаю следующий вывод: ./script testfile Чтение записи Выполнить обычное имя файла Dir ./script: строка 6: FileExists : команда не найдена ./script: строка 7: PrintFileName: команда не найдена – user2990676

+0

Я неправильно вызываю свои функции? – user2990676

+0

Нет, не проверяйте обновленный ответ. – SuperSaiyan

0

в то время как синтаксис функции Name() ", я предпочитаю стиль, возвращенный declare -f Name в качестве моей письменной формы, так как я использую" declare -f name ... "для воспроизведения тел функций.

Кроме того, вы можете указать «эхо Y» и «эхо 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 ]] ; } 

, так как я допустить исключения одной строки к правилу «объявить -f», и даже есть функция, которая делает fbdy что: если тело функции (меньше заголовка, трейлера) подходит к одной строке, покажите его как однострочный, в противном случае покажите его как значение по умолчанию.

Приятно видеть вас, используя функции. Так держать. Я могу поощрять их использование.

Смежные вопросы