Главная » Программирование для UNIX » Команда news: служебные сообщения

0

В главе 1 рассказывалось о том,  что в вашей системе может присутствовать команда news, передающая сообщения, представляющие интерес  для  всех  пользователей системы.  Называться такая команда может  и по-другому, у каждой реализации могут  быть  и свои особенности, но, в том или  ином  виде, она есть в большинстве систем. Команда news, которая будет создаваться сейчас, не призвана заменить вашу локальную команду, просто  на  ее  примере будет  показано, насколько просто  написать такую команду в  оболочке. Потом  интересно будет сравнить версию, разработанную нами, с локальной версией.

Основной идеей  программ такого рода  является хранение персональных  новостей в  специальном каталоге (по  одной  в файле)  /usr/news. Тогда  news (это  и  есть  рассматриваемая программа news) сравнивает время изменения файлов в /usr/news   со временем изменения файла в домашнем каталоге (.news_time), который  служит временной меткой. При отладке можно использовать «.» как каталог и для файлов новос-

тей  и для  .news_time; когда  же  программа  будет  готова  к работе, его можно будет заменить на /usr/news.

$ cat  news

# news:  выводить файлы  новостей,  версия 1

HOME=.           # только для отладки

cd .       #  символ–заполнитель  для /usr/news for  i in  `ls –t  *  $HOME/.news_time`

do

done

case  $i  in

*/.news_time)     break  ;;

*)           echo  news:  $i esac

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:  выводить файлы  новостей,  версия 2

HOME=.           # только для отладки

cd .       # символ–заполнитель  для /usr/news

IFS=’

‘       # только  символ разделителя  строк for  i in    `ls  –t  *  $HOME/.news_time  2>&1`

do

done

case  $i  in

*’ not  found’)   ;;

*/.news_time)     break  ;;

*)           echo  news:  $i  ;; esac

touch  $HOME/.news_time

$ rm .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)                                          Что5то не так!

$

Вот пример того,  как проявляется единообразие программ и данных в оболочке. Команда set выражает недовольство, потому  что ее аргумент (–rwxrwxrwx) начинается со знака минус,  напоминая тем  самым пара метр. Простой  (хотя и некрасивый) способ  разрешения  ситуации состоит в том, чтобы предварить аргумент обычным символом:

$ set  X`ls   -l news`

$ echo "news:  ($3)  $5 $6 $7"

news:  (you)  Oct 1 12:05

$

Формат вывода удобен:  наряду с именем файла  указывается автор  и дата сообщения.

Готова окончательная версия команды news:

# news:  выводить файлы  новостей,  окончательная  версия PATH=/bin:/usr/bin

IFS=’

‘       #  только  разделитель  строк cd  /usr/news

for  i in  `ls –t  *  $HOME/.news_time  2>&1` do

IFS=’  ‘ case  $i  in

*’ not  found’)   ;;

*/.news_time)     break  ;;

*)    set  X`ls  –l  $i` echo  "

$i:  ($3)  $5  $6 $7 "

done

cat  $i esac

touch  $HOME/.news_time

Дополнительные символы новой  строки в  заголовке разделяют сообщения по мере печати. Первоначально значение IFS – это символ новой строки, поэтому сообщение not  found (если  оно выводится) первой команды ls обрабатывается как единый аргумент. При втором присваивании значением IFS становится пробел, поэтому вывод второй ls раз бивается на множество аргументов.

Упражнение 5.27.  Добавьте параметр –n (notify – уведомить) для команды news, чтобы  извещать о новых сообщениях, но не выводить их и не обращаться к .news_time. Такую команду можно добавить в .profile. ~

Упражнение 5.28.  Сравните принцип работы и реализацию команды news, предложенные в этой книге, с соответствующей командой вашей системы. ~

Источник: Керниган Б., Пайк Р., UNIX. Программное окружение. – Пер. с англ. – СПб: Символ-Плюс, 2003. – 416 с., ил.

По теме:

  • Комментарии