UNIX — универсальная среда программирования
Шрифт:
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
, где им и следует быть. Упражнение 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)
. Как ваше решение повлияет на интерпретацию специальных символов в команде? 5.6 Команда
zap
: уничтожение процесса по имени Команда
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
как отдельные аргументы вместо того, чтобы обрабатываться сразу по строке. Обычная процедура интерпретатора заключается в разбиении строк на аргументы с границами пробел/не пробел, как показано ниже:
Поделиться:
Популярные книги
Первый среди равных. Книга XII
12. Первый среди Равных
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Последний Паладин
1. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Мастер Трав III
3. Мастер Трав
Фантастика:
фэнтези
рпг
фантастика: прочее
попаданцы
5.75
рейтинг книги
Встреча
7. Петя и Валерон
Фантастика:
рпг
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 25
25. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Товарищ "Чума" 7
7. Товарищ "Чума"
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Кодекс Охотника. Книга XII
12. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
аниме
7.50
рейтинг книги
Курсант: назад в СССР
1. Курсант
Фантастика:
попаданцы
альтернативная история
7.33
рейтинг книги
Вечный. Книга III
3. Вечный
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Инженер Петра Великого 4
4. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный рынок
6. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Ваше Сиятельство 7
7. Ваше Сиятельство
Фантастика:
боевая фантастика
аниме
5.00
рейтинг книги
Камень. Книга восьмая
8. Камень
Фантастика:
фэнтези
боевая фантастика
7.00
рейтинг книги
Ефрейтор. Назад в СССР. Книга 2
2. Второй шанс
Фантастика:
попаданцы
альтернативная история
7.00