Произведем над сценарием одну «хирургическую» операцию, что предполагает удаление его аргумента (файла или директории), но означает и некоторые проблемы:
admin@serverl:~$ cat delete #!/bi n/bash if гш $1 then
echo file $1 deleted else if rmdir $1 then
echo directory $1 deleted
fi
fi
Сценарий предназначен для удаления файла, указанного в виде аргумента. Он использует команду rm и выводит сообщение, если операция пройдет успешно. Если команда гш не сработает, сценарий считает, что аргумент определяет директорию и вместо этого пробует команду rmdi г.
Рассмотрим некоторые результаты работы сценария:
admin@serverl:$ ./delete hello2
file hel 1о2 deleted
admin@serverl:$ ./delete hello2
rm: cannot remove 'hello2': No such file or directory
rmdir: ~hel1o2': No such file or directory
adminOserverl:$ mkdir hello3
admin@serverl:~$ ./delete hello3
rm: cannot remove "hel1o3': Is a directory
directory hel1o3 deleted
admin@serverl:~
Применяя эти сообщения об ошибках, попытаемся удалить сценарий. Сначала воспользуемся перенаправлением вводавывода для сохранения результатов в файлы журналов и ошибок, которые мы можем просмотреть в наше совсем уж свободное время. Далее мы перехватим возвращаемое значение команды гш для генерирования сообщения об успехе или неудаче. Мы также зафиксируем актуальную дату и время для внесения их в журнал вывода:
admin@serverl:$ cat removefiles #!/bi n/bash

# removefiles deletes either files or directories echo "$0 ran at" $(date) » delete.log if rm $1 2» deleteerr.log then

echo "deleted file $1" » delete.log el if rmdir $1 2» deleteerr.log then
echo „deleted directory $1" » delete.log else
echo ..failed to delete $1" » delete.log
fi
В сценарии все еще есть некоторые недостатки: он не проверяет, существует ли файл вообще, и не различает файлов и директорий. Мы можем использовать некоторые из встроенных операторов, упоминавшихся выше, для устранения этих проблем:
admin@serverl:$ cat removefi1es

#!/bin/bash # removefiles deletes either files or directories echo "$0 ran at" $(date) » delete.log if [ ! e $1 ] then

echo "$1 does not exist" » delete.log elif [ f $1 ] then
echo n "file $1 " » delete.log if rm $1 2» deleteerr.log then
echo "deleted" » delete.log else
echo "not deleted" » delete.log
fi
elif [ d $1 ] then
echo "directory $1 " » delete.log if rmdir $1 2» deleteerr.log then
echo "deleted" » delete.log else
echo "not deleted" » delete.log
fi
fi
Это выглядит очень хорошо, но у нас есть еще один вариант, чтобы встряхнуть вас: что, если имя файла или директории содержит пробелы? Вы точно увидите это, если у вас будут файлы из систем Windows или Мае. Создайте файл под названием my f i 1 е, а затем попытайтесь удалить его с помощью нашего преданного сценария:
admin@serverl:$ ./removefiles my file
Тогда последняя строка файла del ete. 1 og будет содержать такой текст:
my does not exist
Пока мы не поместим выражение my fi 1 е в кавычки, оболочка будет делить ту и fi 1 е на переменные сценария $1 и $2. Поэтому поместим выражение my fi 1 е в кавычки для сохранения его в переменную $1:
admin@serverl:$ ./removefiles "ту file" ./removefiles: [: ту: binary operator expected ./removefiles: [: my: binary operator expected
Ой! Мы получили последовательность символов my fi 1е в переменной оболочки $1, но мы должны снова заключить ее в кавычки внутри сценария, чтобы защитить от тестов имени и удаления команд:
admin@serverl:~$ cat removefiles #! /Ы n/bash

# removefiles удаляет каждый файл или директорию echo "$0 ran at" $(date) » delete.log if [ ! e "$1" ] then

echo "$1 does not exist" » delete.log elif [ f "$1" ] then
echo n "file $1 " » delete.log if rm "$1" 2» deleteerr.log then
echo "deleted" » delete.log else
echo "not deleted" » delete.log
fi
elif [ d "$1" ] then
echo n "directory $1 " » delete.log if rmdir "$1" 2» deleteerr.log then
echo "deleted" » delete.log else
echo "not deleted" » delete.log
fi
fi
Теперь, наконец, если вы запустите следующую команду: admin@serverl:~$ ./removefiles "my file" последняя строка del ete. 1 og будет такой: file my file deleted