Читаем UNIX полностью

Упражнение 5.17

Почему команда overwrite не использует сигнал 0 в команде trap, чтобы файлы удалялись при выходе из нее? Подсказка: попробуйте нажать клавишу DEL во время выполнения следующей программы:

trap "echo exiting; exit 1" 0 2

sleep 10

Упражнение 5.18

Добавьте флаг -v к команде replace для вывода всех измененных строк на /dev/tty.

Подсказка: s/$left/$right/g $vflag.

Упражнение 5.19

Увеличьте надежность команды replace, чтобы ее выполнение не зависело от символов в строке замены.

Упражнение 5.20

Можно ли использовать replace для замены i на index всюду в программе? Какие вы внесли бы изменения, чтобы добиться этого?

Упражнение 5.21

Достаточно ли команда replace эффективна и удобна, чтобы находиться в каталоге /usr/bin? Не лучше ли вводить по мере необходимости подходящие команды редактора sed (да или нет)? Обоснуйте свой ответ.

Упражнение 5.22

(Усложненное.) Команда

$ overwrite файл 'who | sort'

не выполняется. Объясните причину этого и исправьте ее. Подсказка: посмотрите eval в справочном руководстве по sh(1). Как ваше решение повлияет на интерпретацию специальных символов в команде?

<p>5.6 Команда <code>zap</code>: уничтожение процесса по имени</p>

Команда kill только завершает процесс с указанным номером. Если нужно уничтожить определенный фоновый процесс, обычно приходится выполнить команду ps, чтобы узнать номер процесса, а затем ввести этот номер в качестве аргумента для команды kill. Однако нелепо иметь программу, выдающую номер процесса, который сразу же передается вручную другой программе. Имеет смысл написать программу, скажем zap, для автоматического выполнения такой работы. Здесь, правда, есть одно препятствие: уничтожение процессов опасно, поэтому следует принять меры для обеспечения сохранности нужных процессов. Хорошей защитой всегда служат диалоговое выполнение zap и использование команды pick для выбора "жертв".

Кратко напомним вам о команде pick: она выдает поочередно свои аргументы, спрашивая ответ у пользователя; если ответ — y, то аргумент выводится (команда pick обсуждается в следующем разделе). В нашем случае pick используется для подтверждения, что процессы, выбранные по имени, — именно те, которые пользователь хочет уничтожить:

$ cat zap

# zap pattern: kill all processes matching pattern

# BUG in this version

PATH=/bin:/usr/bin

case $# in

0) echo 'Usage: zap pattern' 1>&2; exit 1

esac

kill `pick \`ps -ag | grep "$*"\` | awk '{print $1}'`

Обратите внимание на вложенные знаки слабого ударения, защищенные символами обратной дробной черты, awk программа выделяет номер процесса из выходных данных команды ps, выбранной с помощью pick:

$ sleep 1000 &

2216

$ ps -ag

 PID TTY TIME CMD

...

2216   0 0:00 sleep 1000

...

$ zap sleep

2216?

0? q Что происходит?

$

Проблема состоит в том, что выходные данные команды ps разбиты на слова, которые воспринимаются и обрабатываются командой pick как отдельные аргументы вместо того, чтобы обрабатываться сразу по строке. Обычная процедура интерпретатора заключается в разбиении строк на аргументы с границами пробел/не пробел, как показано ниже:

for i in 1 2 3 4 5

В этой программе нужно контролировать процесс разбиения интерпретатором строк на аргументы, чтобы только символ перевода строки разделял соседние "слова".

Внутренняя переменная интерпретатора IFS (internal field separator — внутренний разделитель полей) представляет собой строку символов, которая разделяет слова в списке аргументов, находящихся в знаках слабого ударения или циклах for. Обычно IFS содержит пробелы, символы табуляции и конца строки, но мы можем заменить ее на что-либо нужное, например просто на символ перевода строки:

Перейти на страницу:

Похожие книги