Брайан Керниган - UNIX — универсальная среда программирования
- Название:UNIX — универсальная среда программирования
- Автор:
- Жанр:
- Издательство:Финансы и статистика
- Год:1992
- Город:Москва
- ISBN:5-289-00253-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Брайан Керниган - UNIX — универсальная среда программирования краткое содержание
В книге американских авторов — разработчиков операционной системы UNIX — блестяще решена проблема автоматизации деятельности программиста, системной поддержки его творчества, выходящей за рамки языков программирования. Профессионалам открыт богатый "встроенный" арсенал системы UNIX. Многочисленными примерами иллюстрировано использование языка управления заданиями shell.
Для программистов-пользователей операционной системы UNIX.
UNIX — универсальная среда программирования - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Здесь есть некоторая тонкость. Рассмотрим последовательность:
$ sed 's/UNIX/UNIX(TM)g' special | overwrite special
command garbled: s/UNIX(TM)g
$ ls -l special
-rw-rw-rw- 1 you 0 Oct 1 09:02 special #$%@*!
$
Если в программе, поставляющей входной поток для команды overwrite, произойдет ошибка, то выходной поток будет пустым, и overwrite
обязательно (с сознанием выполненного долга) уничтожит файл, заданный в качестве аргумента.
Во избежание такого финала можно предложить несколько решений. Команда overwrite
могла бы запрашивать подтверждение перед заменой файла, но, сделав команду диалоговой, мы потеряем большую часть ее достоинств. Она могла бы проверять, что ее входной поток не пуст (с помощью test -2
), но это некрасиво и к тому же неверно: выходной поток мог быть создан до обнаружения ошибки.
Наилучшее решение заключается в том, чтобы выполнять программу, поставляющую данные, под контролем команды overwrite
, чтобы можно было проверить ее код завершения. Это, правда, противоречит традициям и здравому смыслу: ведь в конвейере команда overwrite
обычно должна быть последней, но для правильной работы она должна идти первой. Однако overwrite
ничего не выдает в стандартный выходной поток, поэтому можно считать, что не происходит потери общности. Более того, ее синтаксис не является каким-то необычным: time
, nice
, nohup
представляют собой команды, аргументами которых служат другие команды. Ниже приведен безопасный вариант:
# overwrite: copy standard input to output after EOF
# final version
opath=$PATH
PATH=/bin:/usr/bin
case $# in
0|1) echo 'Usage: overwrite file cmd [args]' 1>&2; exit 2
esac
file=$1; shift
new=/tmp/overwr1.$$; old=/tmp/overwr2.$$
trap 'rm -f $new $old; exit 1' 1 2 15 # clean up files
if PATH=$opath "$@" >$new # collect input
then
cp $file $old # save original file
trap '' 1 2 15 # we are committed; ignore signals
cp $new $file
else
echo "overwrite: $1 failed, $file unchanged" 1>&2 exit 1
fi
rm -f $new $old
Встроенная команда интерпретатора shift
сдвигает весь список аргументов на одну позицию влево: $2
становится $1
, $3
становится $2
и т.д. Строка обозначает все аргументы (после shift
), как и $*
, но без интерпретации; мы вернемся к ее рассмотрению в разд. 5.7.
Заметьте, что значение PATH
нужно восстановить перед выполнением команды пользователя; если этого не сделать, то команды, не находящиеся в /bin
или /usr/bin
, будут недоступны для overwrite
.
Теперь команда overwrite
выполняется верно (хотя и она получилась несколько громоздкой):
$ cat notice
Unix is a Trademark of Bell Laboratories
$ overwrite notice sed 's/UNIXUNIX(TM)/g' notice
command garbled: s/UNIXUNIX(TM)/g
overwrite: sed failed, notice unchanged
$ cat notice
UNIX is a Trademark of Bell Laboratories
He изменился
$ overwrite notice sed 's/UNIX/UNIX(TM)/g' notice
$ cat notice
UNIX(TM) is a Trademark of Bell Laboratories
$
Типичной задачей является использование редактора sed
для замены всех вхождений одного слова на другое слово. Имея под рукой команду overwrite
, легко написать программу на языке shell
для ее решения:
$ cat replace
# replace: replace str1 in files with str2, in place
PATH=/bin:/usr/bin
case $# in
0|1|2) echo 'Usage: replace str1 str2 files' 1>&2; exit 1
esac
left="$1"; right="$2"; shift; shift
for i do
overwrite $i sed "s@$left@$right@g" $i
done
$ cat footnote
UNIX is not an acronym
$ replace UNIX Unix footnote
$ cat footnote
Unix is not an acronym
$
(Вспомните: если список в цикле for
пуст, то по умолчанию он равен $*
.) Мы использовали @
вместо /
для разбиения в команде подстановки, поскольку менее вероятно, что @
вступит в конфликт с входной строкой. Команда replace
устанавливает PATH
равным /bin:/usr/bin
, исключая $HOME/bin
. Это означает, что overwrite
должна находиться в /usr/bin
, чтобы команда replace
сработала. Мы сделали такое предположение для простоты; если вы не можете поместить overwrite
в /usr/bin
, вам придется добавить $HOME/bin
к PATH
в команде replace
или явно задать полное имя overwrite
. В дальнейшем будем полагать, что команды, которые мы создаем, находятся в /usr/bin
, где им и следует быть.
Почему команда overwrite
не использует сигнал 0 в команде trap
, чтобы файлы удалялись при выходе из нее? Подсказка: попробуйте нажать клавишу DEL во время выполнения следующей программы:
trap "echo exiting; exit 1" 0 2
sleep 10
Добавьте флаг -v
к команде replace
для вывода всех измененных строк на /dev/tty
.
Подсказка : s/$left/$right/g $vflag
.
Увеличьте надежность команды replace
, чтобы ее выполнение не зависело от символов в строке замены.
Можно ли использовать replace
для замены i
на index
всюду в программе? Какие вы внесли бы изменения, чтобы добиться этого?
Достаточно ли команда replace
эффективна и удобна, чтобы находиться в каталоге /usr/bin
? Не лучше ли вводить по мере необходимости подходящие команды редактора sed
(да или нет)? Обоснуйте свой ответ.
( Усложненное .) Команда
$ overwrite файл 'who | sort'
не выполняется. Объясните причину этого и исправьте ее. Подсказка : посмотрите eval
в справочном руководстве по sh(1)
. Как ваше решение повлияет на интерпретацию специальных символов в команде?
5.6 Команда zap
: уничтожение процесса по имени
Команда kill
только завершает процесс с указанным номером. Если нужно уничтожить определенный фоновый процесс, обычно приходится выполнить команду ps
, чтобы узнать номер процесса, а затем ввести этот номер в качестве аргумента для команды kill
. Однако нелепо иметь программу, выдающую номер процесса, который сразу же передается вручную другой программе. Имеет смысл написать программу, скажем zap
, для автоматического выполнения такой работы. Здесь, правда, есть одно препятствие: уничтожение процессов опасно, поэтому следует принять меры для обеспечения сохранности нужных процессов. Хорошей защитой всегда служат диалоговое выполнение zap и использование команды pick
для выбора "жертв".
Кратко напомним вам о команде pick
: она выдает поочередно свои аргументы, спрашивая ответ у пользователя; если ответ — y
, то аргумент выводится (команда pick
обсуждается в следующем разделе). В нашем случае pick
используется для подтверждения, что процессы, выбранные по имени, — именно те, которые пользователь хочет уничтожить:
Интервал:
Закладка: