Шрифт:
(Более простое.) Используйте команду
read
в вашем файле .profile
для инициации TERM
, а также всего, что зависит от нее, например позиции табуляции. 5.8 Команда
news
: служба информации пользователей В гл. 1 упоминалось о том, что в вашей системе может быть команда
news
для передачи сообщений, представляющих интерес для всех пользователей системы. Хотя названия команды и ее детали могут различаться, большинство систем имеет службу информации. Мы рассматриваем команду news
не для замены вашей местной команды, а чтобы показать, как легко написать такую программу на языке shell
. Неплохо было бы сравнить реализацию предлагаемой здесь команды news с вашей версией. Обычно основная идея таких программ заключается в том, что отдельные фрагменты новостей хранятся по одному в файлах в специальном каталоге типа
/usr/news
. Наша команда news
сравнивает время изменения файлов в каталоге /usr/news
и вашем исходном каталоге (.news_time
). В целях отладки мы можем использовать каталог '.'
как для файлов новостей, так и для news_time
. Можно заменить его на /usr/news
, когда программа будет готова для общего пользования:
$ cat news
# news: print news files, version 1
HOME=. # debugging only
cd . # place holder for /usr/news
for i in `ls -t * $HOME/.news_time`
do
case $i in
*/.news_time) break ;;
*) echo news: $i
esac
done
touch $HOME/.news_time
$ touch .news-time
$ touch x
$ touch y
$ news
news: y
news: x
$
Команда
touch
заменяет время последней модификации файла, заданного в качестве аргумента, на настоящее время, не подвергая сам файл модификации. Для отладки мы даем только эхо имен файлов новостей, а не печатаем их. Цикл завершается при обнаружении news_time
, тем самым перечисляются только файлы со свежими новостями. Заметьте, что символ *
в операторе case
может быть сопоставлен с /
, что недопустимо для шаблонов имен файлов. А что будет, если news_time
не существует?
$ rm .news_time
$ news
$
Отсутствие ответа удивляет и является ошибочным. Это вызвано тем, что когда команда
ls
не находит файл, она выдает соответствующее сообщение в стандартный выходной поток прежде, чем вывести какую-либо информацию о существующих файлах. Такая ситуация, безусловно, ошибочна — диагностические сообщения должны передаваться в стандартный файл диагностики. Но мы можем обнаружить эту ситуацию в цикле и переключить стандартный файл диагностики на стандартный выходной поток, так что все версии будут работать одинаково. (Данная проблема решена в новой версии, но мы рассмотрели ее, чтобы проиллюстрировать, как легко устранить недоделки.)
$ cat news
# news: print news files, version 2
HOME=. # debugging only
cd . # place holder for /usr/news
IFS='
' # just a newline
for i in `ls -t * $HOME/.news_time 2>&1`
do
case $i in
*' not found') ;;
*/.news_time) break ;;
*) echo news: $i ;;
esac
done
touch $HOME/.news_time
$ news
news: news
news: y
news: x
$
Мы должны были установить
IFS
равным символу конца строки, чтобы сообщение
./.news_time not found
не распознавалось как три слова.
Команда
news
должна выводить на печать файлы новостей, а не создавать эхо их имен. Полезно знать, кто и когда послал сообщение, поэтому мы воспользуемся командами set
и ls -l
для вывода заголовка перед самим сообщением:
$ ls -l news
– rwxrwxrwx 1 you 208 Oct 1 12:05 news
$ set `ls -l news`
– rwxrwxrwx: bad option(s)
Что-то неправильно!
$
Это один из тех случаев, когда взаимозаменяемость программы и данных на языке
shell
имеет значение. Команда set
"ругается", потому что ее аргумент ("– rwxrwxrwx
") начинается с минуса и, следовательно, выглядит как флаг. Очевидным (хотя и неэлегантным) решением было бы предварить аргумент обычным символом: