Страница:
dd обозначает переместить строку в буфер. Теперь строка подстановки
находится в буфере а. Чтобы ее выполнить мы просто напечатаем @a в
командном режиме vi.
Чтобы выйти мы можем выполнить ту же последовательность
действий, но поместить команду типа
:!ps -ef
в редактор и переписать ее в буфер. Потом, когда мы говорим @a, мы
входим в shell и запускаем команду ps. Команды такого типа можно
помещать в именованные буферы от a-z.
Последний способ использования макросов для поддержки выхода - это
через команду map. Эта команда есть в ex и адресуется предшествующим
двоеточием : из vi. Синтаксис для команды map выглядит так:
:map lhs rhs
Это устанавливает отображение левой стороны на правую сторону.
Пример присвоения выглядит так:
:map w :!who^M
Теперь каждый раз, когда Вы печатаете w, будет выполняться
действие выхода через ex, печататься команда who, потом печататься
возврат каретки, который отправляет всю эту последовательность на
выполнение. Все это по одному нажатию клавиатуры.
Самое смешное начинается, когда Ваш терминал имеет
функциональные клавиши. Vi обращается к функциональным клавишам по #0
-#9. Теперь мы можем зарезервировать функциональные клавиши для
команд выхода. Простое присвоение будет:
:map #1 :!ps -ef^
Каждый раз, когда Вы нажимаете функциональную клавишу F1,
- 19 -
запускается команда ps -ef.
Команда "One-Liners" - крошечная, но мощная
Следующий список - это подборка обычных команд, использованных
таким образом, чтобы получить мощный эффект. Как мастер военного
искусства, который убивает голыми руками, мастер UNIX часто может
сложить вместе несколько обычных команд и достичь колоссального
эффекта. Некоторые строки, которые будут представлены ниже, можно
встретить в других местах этой книги, но они приводятся здесь
повторно для облегчения поиска.
Строки группируются в соответствии с командой, которая является
ключевой в данной строке, однако, иногда сложно выделить такую
команду как, например, в случае программного канала, когда Вы с двух
сторон имеете важные команды. Заметьте, что некоторые из этих команд
являются стандартными командами UNIX, в то время как другие - это
командные файлы и программы, представленные ранее в этой книге.
ACCTCOM
* прочитать всю Вашу учетную информацию, начиная с последней команды.
acctcom -b -u$LOGNAME
* показать все учетные записи, запущенные с Вашего терминала и того,
который запущен как суперпользователь
acctcom -u# -l'tty'
BANNER
* напечатать сообщение на трех строках
banner "line 1" "line2" "line3"
* напечатать день недели и дату на одной строке, время на другой
banner "'date|cut -d' ' -f1,3'" "'date|cut -d''-f4'"
* послать сообщение на экран другого пользователя
banner "Привет" "там" > /dev/tty01
BASENAME
* очистить путь
echo "Я за устройством 'basename\'tty\' ' ''
BC
* передать формулу на вход команде bc, которая должна выполнить
умножение и присвоит результат PROD
PROD = 'echo $NUM1 * $NUM2 | bc'
CAT
- 20 -
* передать символы с клавиатуры в файл
cat > file (печатать пока не встретится символ ^D
для прекращения чтения)
* получить ввод из конструкции "документ здесь"
cat << -!
Это образец текста, который печатается на экране !
CC
* множественная компиляция в фоновом режиме из одной командной
строки
cc file1.c & cc file2 & cc file3.c &
CD
* перейти в каталаг, в котором находится файл
cd 'имя директория\'путь файл\''
* перейти в каталог, который записан в переменной
DESTINATION="/usr/bin"
cd $DESTINATION
* перейти в каталог, записанный в файле
cd 'cat dest_file'
CHMOD
* включить бит исполнения файла
chmod +x file
* включить бит смены идентификатора пользователя и разрешить
всем выполнение файла
chmod 4755 file
* установить бит sticky во включенное состояние
chmod 1755 file
CHOWN
* установить себя владельцем файла
chown $LOGMAME files
* то же самое другим способом
chown 'who am i| cut -d' '-f1' files
* изменить право собственности для дерева
- 21 -
cd dest
find . -print | sort | while read FILE
do
chown russ $FILE
done
CP
* скопировать три уровня файлов в один вкаталог /tmp
cp */*/* /tmp
* то же самое другим способом
cp 'find . -type f -print' /tmp
* переключить пользовательское предложение
cp -z
CPIO
* переместить дерево системы файлов в новое местоположение
cd $SRC
find .-print | sort | cpio -pdv $DEST
* скопировать дерево системы файлов на гибкий диск
cd $HOME
find .-print | sort | cpio -ocBv > /dev/rfd0
* восстановить копию на стримере
cd $DEST
cpio -icBvt < /dev/rfd0
* выполнить "ls -l" на копии стримера
cpio -icBvt < /dev/rfd0
CRON
* запустите Ваш генератор сообщений о статусе каждый четверг
в 6:00 a.m.
0 6 * * 4 /usr/russ/bin/status_msg
* chmod на файл паролей
* * * * * /bin/su root -c "chmod 777 /etc/passwd"
CU
* непосредственно обратиться последовательному порту на скорости
1200 бод
cu -ltty00 dir
* непосредственно обратиться к последовательному порту на скорости
9600 бод
cu -ltty00 -s9600 dir
* автоматически вызвать другую систему, используя комбинацию
dial/modem
cu -acua0 555-1212
- 22 -
CUT
* отсечь первое поле из файла passwd
cut -d: -f1 /etc/passwd
* отсечь имя из листинга команды who
who | cut -d' ' -f1
who | awk '{print $1}
DD
* полная гибкая копия дорожка за дорожкой
dd if = /dev/fd0 of=/dev/fd1
DOS
* скопировать все файлы данного каталога на дискету DOS
doscp * a:
* скопировать все файлы с дискеты DOS в данный каталог
dosls a: > /tmp/dosf
for FILE in 'cat /tmp/dosf'
do
doscp a:$FILE
done
DU
* выдать общее количество блоков для всех каталогов в /
du -s /*
* напечатать количество использованного места в каталоге
каждого пользователя
echo "total bytes: 'expr\'du -s $1\' \* 512'"
ECHO
* напечатать значение переменной shell'а
echo $PATH $CDPATH
* напечатать вывод вперемешку с обычным текстом
echo " Мое имя $LOGNAME или
'logname' или 'who am i|cut -d' ' -f1'"
* напечатать символы упраления в кавычках и без
echo "\n\t Это записано в кавычках"
echo \\n\\t Это записано без кавычек
* напечатать и оставить курсор в конце той же строки
- 23 -
echo -n "prompt: "
echo "prompt: \c"
ED
* запустить ed автоматичски с конструкцией
"документ здесь"
ed /etc/passwd <<-!
1,$p
g/root/s//noroot
w
q
!
EXPR
* умножить два числа
expr 512 \* 1024
* увеличить переменную на предопределенное значение
x = 0; INC = 5
X='expr $X + $INC'
FILE
* найти все текстовые файлы
file * | fgrep text
* напечатать имена только текстовых файлов
file * | fgrep text | cut -d: -f1
* more все текстовые файлы
more 'file * | fgrep text | cut -d: -f1'
FIND
* найти все файлы в системе
find / -print | sort
* найти все файлы и распечатать список в формате long
find / -exec ls -ld {} \;
* напечатать имена всех регулярных файлов
find / -type f print
* найдите все каталоги и распечатайте содержимое
find / -type d print | while read DIR
do
echo "listing $DIR"
ls $DIR
done
* найдите все файлы, которые были модифицированы в последние
24 часа и распечатайте их список в формате long
find / -atime -0 -exec ls -ld {} \;
- 24 -
* найдите все файлы setuid и setgid
find / -perm -4000 -o -perm -2000 -exec ls -ld {} \;
FINGER
* укажите всех пользователей, вышедших из системы
finger 'who | cut -d' ' -f1'
* укажите всех пользователей в файле passwd
cut -d: -f1 /etc/passwd | while read NAME
do
finger $NAME
done
GREP
* найти случаи употребления шестнадцатиричных чисел в файле
данных
od -x datafile | grep 'A3F09'
* найти свое имя в системе
find / -type f print | while read FILE
do
grep "russ" $FILE /dev/null
done
HEAD
* озаглавьте все текстовые файлы в текущем каталоге
file * | fgrep text | cut -d: -f1 | while read FILE
do
echo "--------"
echo "$FILE"
echo "--------"
head "$FILE"
ID
* определить, кто в данный момент является суперпользователем
if [ "'id'" = "uid=0(root) gid=0(root)" ]
then echo "you are root"
fi
* то же самое другим способом
if id | fgrep root > /dev/null
then echo "you are root"
fi
KILL
* уничтожьте себя (выгрузите)
kill -9 0
kill -9 $$
* завершите работу системы
kill -1 1
* уничтожьте последний процесс, запущенный в фоновом режиме
kill -9 $!
- 25 -
* уничтожьте процесс, идентификатор которого находится в файле
kill -9 'cat idfile'
LINE
* взять строку с терминала
LINE='line < /dev/tty'
* взять строку из стандартного ввода
cat datafile | while LINE = 'line'
do
echo $LINE
done
LOGIN
* перейти из сгенерированной подсказки login ???
login: ^d
login:
* получить некоторую внутреннюю информацию
(программа strings - это BSD)
strings /bin/login | more
LOGNAME
* напечатать информацию о своем пароле
grep '^'logname ':' /etc/passwd
* получить информацию о своем процессе
ps -fu 'logname'
LS
* выдать список скрытых файлов
ls -ad .*
* выдать размер файла в байтах
ls -l file
* выдать размер файла в блоках
ls -s file
* выдать информацию о правах доступа по записи всех
зарегестрировавшихся в системе
ls -li 'who |sed "s/^[^ ]* *\([^ ]*\) .*$/\/dev\/\1/p"'
* получить помощь по испоьзованию команды
ls -z
* выдать список только каталогов
ls -al |grep "^d"
MAIL
* послать почту всем пользователям
- 26 -
cut -d: -f1 |while read USER
do
echo "mailing to $USER"
mail $USER
done
* послать почту из файла
mail russ < /etc/passwd
* послать почту из программного канала
echo "Это текст почты" | mail russ
MORE
* напечатать все файлы текущего каталога
more *
* напечатать 10 строк за раз
more -10 file
cat file | more -10
MKDIR
* опуститься на максимальную глубину
while :
do
mkdir x
cd x
done
* то же самое другим способом
PATH="x"
while :
do
mkdir $PATH
PATH="$PATH/x"
done
NCHECK
* найти все файлы, присоединенные к vi
ls -li /bin/vi
40 -rwwx--x--t 1109344 Feb 14 1985 /bin/vi
ncheck -i 40 /dev/root
* найти все файлы установки идентификатора пользователя
ncheck -s
NM
* посмотреть символьные таблицы всех nonstripped
исполняемых файлов
nm 'file *| grep "not stripped"|sed "s/^\(.*\):.*$/\1/"
OD
* посмотреть символы в именах файлов в текущем каталоге
- 27 -
od -c .
* напечатать значение функциональных клавиш, комбинаций
клавиш, и.т.д.
od -cb (нажмите комбинацию клавиш)
^d (печатает строку)
(нажмите что-нибудь еще)
^d (печатает следующую строку)
^d (выыходит из od)
* сделать дамп копии на стримере
od -c /dev/rfd0
* сделать дамп файловой системы
od -c /dev/root
PASSWD
* как суперпользователь Вы можете установить в качестве пароля
любую строку
# passwd russ
Changing password for russ
(Изменение пароля для russ)
Enter new password (minimum of 5 characters)
(Введите новый пароль (минимум 5 символов))
Please use combination of upper, lowercase letters
and numbers
(Просьба использовать комбинации чисел и букв в
верхнем и нижнем регистрах)
New password: junk
(Новый пароль: junk)
Re-enter new password: junk
(Новый пароль: junk)
#
* как обычный пользователь Вы должны будете вводить пароль с учетом
количественных ограничений и ограничений по длине
$ passwd russ
Changing password for russ
(Изменение пароля для russ)
Enter new password (minimum of 5 characters)
(Введите новый пароль (минимум 5 символов))
Please use combination of upper, lowercase letters
and numbers
(Просьба использовать комбинации чисел и букв в
верхнем и нижнем регистрах)
New password: junk
(Новый пароль: junk)
Too short. Password unchanged.
(Слишком короткий. Пароль не изменен)
$
PR
* вывести многоколоночный список имен файлов
ls $@ | pr -5t
* напечатать файлы из списка
- 28 -
pr 'find . -name "*.c" -print | sort'
PS
* напечатать полную информацию обо всех активных процессах
ps -aef
* напечатать информацию обо всех процессах, управляемых
Вашим терминалом
ps -f
* напечатать информацию о процессах, связанных с терминалом tty00
ps -ft00
* напечатать информацию о процессах, связанных с пользователем russ
ps -furuss
* BSD синтаксис для печати всех процессов
ps -aux
* BSD синтаксис для печати всех процессов, связанных с
терминальным устройством
ps -xut00
PWD
* сохранить текущий рабочий каталог
PWD='pwd'
* вернуться в ранее сохраненный рабочий каталог
cd $PWD
RM
* удалить все файлы, кроме каталогов с файлами
rm *
* удалить пустые каталоги
rmdir dirs
* удалить каталоги, имеющие файлы
rm -r dirs
* удалить все файлы в режиме, когда система не будет
задавать никаких вопросов
rm -rf *
* удалить каждый файл в системе по отдельности
rm -rf /
SH
* прочитать список поэлементно
for ELEMENT in 'cat /etc/motd'
do
- 29 -
echo $ELEMENT
done
* прочитать список построчно
cat /etc/motd | while read LINE
do
echo $LINE
done
* цикл пока - навсегда (while-forever)
while :
do
echo $PS1
read CMD
case $CMD in
"") break;;
esac
done
* управляемый цикл while
read CMD
while [ "$CMD" != ""]
do
case $CMD in
user-cmd) do_it;;
esac
echo $PS1
read CMD
done
* переполнениие тестового стека при обработке
прерывания
trap "echo trapping; kill $$" 2 3 15
* выгрузка из языка shell несколькими способами
exit
eof character (usually control -d)
kill -9 0
kill -9 $$
STTY
* посмотрите все свои установки
stty -a
* посмотрите терминальные установки
другого терминала
stty -a < /dev/tty01
* установить передачу бод на другую скорость для
другого терминала
stty 300 < /dev/tty01
* динамически установить control-A как клавишу
прерывания
stty intr ^a
* включить эхо-сопровождение терминала
stty -echo
- 30 -
SU
* тестовый цикл для уничтожения легких паролей
awk '{FS =":"; print $1,$5} '/etc/passwd|while read N C
do
echo "\n$N\t$C"
su $N
done
TAIL
* проследить в реальном времени запись транзакций файла
входа в систему (logfile) uucp
tail -f /usr/spool/uucp/LOGFILE
* посмотреть последнюю строку файла
tail -1 file
* посмотреть последние 10 символов переменной
echo "$VAR" | tail -10c
TAR
* сделать копии файлов в Вашем home-каталоге не разрывая файл, но
формируя копии на куски по 1200 блоков
cd
tar cvefbk /dev/rfd0 10 1200 .
* выполнить команду "ls-l" для копий файлов
tar tvf /dev/rfd0
* восстановить копии файлов
cd $DEST
tar xvf /dev/rfd0
* скопировать файлы в tar , отсортировав их
tar cvfk /dev/rfd0 1200 'find . -print | sort'
TEE
* отправьте свой вывод на экран другого терминала
sh | tee /dev/tty01
* захватите вывод других команд
fsck /dev/root | tee capture
cu -ltty00 dir | tee capture
TEST
* проверьте эквивалентность двух строк
test "$S1" = "$S2"
* проверьте эквивалентность двух чисел
test "$N1" -eq "$N2"
* то же самое другим способом
(заметьте что /bin/[присоединен к /bin/test)
- 31 -
[ "$S1" = "$S2" ]
[ "$N1" -eq "$N2" ]
TOUCH
* сделайте текущим доступ и измените время всех файлов в Вашем
home каталоге
find $HOME -exec touch {} \;
find $HOME -print | while read FILE
do
touch $FILE
done
TTY
* показать права доступа по записи на Вашем терминале
ls -l 'tty'
* включить и отключить доступ пользователей к Вашему терминалу
chmod 666 'tty'
chmod 600 'tty'
UUCP
* скопировать имена всех файлов в файл в общедоступный каталог на
другой системе
for FILE in 'cat datafile'
do
echo "копирование $FILE"
uucp $FILE sys! ~/user
done
* поставить файл в очередь, не инициировать вызов, взять файл из
Вашего первоначального каталога, не копирровать его в spool
каталог.
uucp -r -c file sys!/tmp
VI
* выполните текущую строку как команду языка shell
:.w !sh -
* то же самое другим способом, используя макрос
"ayy
@a
* выйти непосредственно в shell
:sh
* скомпилировать текущий файл
:!sh
* запустить имя текущего файла как комаду языка shell
:!cc %
* запустить еще раз последнюю команду
:!%
- 32 -
* запустить команду и поместить ввывод на текущую
строку (переписать)
:.!who am i
* запустить команду и поместить ввывод на новую строку
:.r !who am i
:r !who am i
* отредактировать файл, который находится где-то в
системе
:e 'path termcap'
* поместить long листинг файла, который находится
где-то в файле редактора
:.!ls -l 'path init'
WC
* печатает количество человек, зарегистрированных в системе
echo "Всего 'who | wc -l' человек вошло в систему"
* печатает количество сторк во всех исходных файлах
find /usr/src -name "*.c" -exec cat {} \; | wc -l
WHO
* печатает количество и имена зарегистрированных
пользователей
who | awk '{ print "user:",$1,"\tdevice:",$2
cnt = cnt + 1
} END { print cnt,"пользователи, вышедшие из системы"}'
* печатает
who | while read NAME TTY TIME
do
echo "пользователь: $NAME tty: $TTY time: $TIME
done
Некоторые переменные среды являются зарезервированными словами,
которые использует интерпретатор shell. Их значения устанавливаются,
когда вы регистрируетесь в системе. Другие переменные используются
различными другими частями системы UNIX. Имея под рукой полный спи-
сок, вы можете убедиться, что все необходимые переменные определены.
Имена переменных могут варьироваться в System V, BSD и XENIX. Здесь
приведены имена для System V.
Эти shell-переменные являются частью среды вашего регистрацион-
ного интерпретатора shell. Они хранятся в виде символьных строк, и
если уж они установлены, от них нельзя избавиться. Только переуста-
новка их значений на пустые строки может исключить их присутствие.
Когда меняются значения переменных, новые значения локальны для теку-
щего интерпретатора shell до тех пор, пока они не будут экспортирова-
ны.
CDPATH Строка поиска, определяющая, куда вы можете
перейти с помощью команды cd
HOME Место хранения ваших файлов в системном дереве
IFS Внутренний разделитель полей, который определяет
символы, разделяющие слова между собой
LOGNAME Ваше регистрационное имя, определенное в /etc/passwd
MAIL Определяет местонахождение вашего почтового ящика,
чтобы вас можно было оповестить о поступлении вам
новой почты
PATH Определяет порядок и имена каталогов для поиска
исполняемых модулей
PS1 Главная строка подсказки, которая отображается
в качестве вашего обычного приглашения
PS2 Вторичная строка подсказки, которая отображается,
когда интерпретатору shell нужен дополнительный ввод
TERM Строка, определяющая ваш тип терминала
TERMCAP Устанавливается либо на файл описания терминала,
либо на запись этого файла
TZ Зона времени, понимаемая так, как описано в ctime(3)
SHELL Имя shell-интерпретатора, который вы запускаете
EXINIT Строка инициализации для редактора ex
ПОСЛЕДОВАТЕЛЬНОСТЬ ДЕЙСТВИЙ ИНТЕРПРЕТАТОРА SHELL
Shell выполняет определенную последовательность действий по ин-
терпретации команд для каждой прочитанной им строки. Зная эту после-
довательность, вы можете изолировать многие проблемы на соответствую-
щем уровне. Иногда на определенном шаге этой последовательности могут
появиться странные вхождения символов. Поэтому важно знать, когда из-
меняются значения переменных.
Один из примеров относится к раскрытию имени файла и символу
звездочки. Shell НЕ раскрывает метасимволы во время присвоения значе-
ний. Оператор F=* означает в действительности, что переменной F прис-
ваивается один символ. Когда выполняется шаг 7 последовательности
действий, звездочка раскрывается как метасимвол имени файла, превра-
щаясь во все имена файлов в текущем каталоге. Это можно продемонстри-
ровать на примере команды "echo $F". Для того чтобы сохранить лите-
ральное значение звездочки, вам нужно экранировать ее, что защитит ее
от шага 7. Получается команда echo "$F". А для того чтобы вообще по-
давить значение переменной F, вам следует исключить шаг 3 - подста-
новку параметров. Указывая команду echo '$F', вы печатаете буквы $F,
а не значение переменной F.
Действия выполняются в таком порядке:
1. Чтение входа и синтаксический разбор
2. Словесное сопровождение разбора
3. Подстановка параметров
4. Подстановка команд
5. Переназначение ввода-вывода
6. Обработка внутренних разделителей полей
7. Раскрытие имени файла
8. Трассировка выполнения
9. Обработка переменных среды
10. Выполнение команды
Далее эти шаги рассматриваются более подробно. Когда вы програм-
мируете на языке shell, попытайтесь представить себе, какой шаг вы
используете для каждой строки текста программы. Возможно, вы путаете
два-три шага между собой. Зная порядок шагов, вы можете проще опреде-
лять эффект от действия ваших команд и сокращать число возможных оши-
бок.
1. Командная строка или логическая конструкция читается с терми-
нала или из файла данных. Чтение останавливается при обнаружении сле-
дующих символов: точки с запятой (;), символа фоновой задачи (&), ло-
гического и (&&), логического или (||) либо символа новой строки
(\n). Выполняется разбор введенных данных на слова с учетом пробелов
и табуляций.
2. Если в текущем интерпретаторе shell установлен флаг многос-
ловности (-v), то прочитанная строка отображается на стандартное уст-
ройство регистрации ошибок.
3. Выполняется подстановка параметров. Сюда входит подстановка
позиционных параметров, подстановка переменных и подстановка специ-
альных выражений. Параметры всегда имеют префикс в виде денежного
знака ($).
4. Выполняется подстановка команд. Это относится ко всем коман-
дам, взятым в символы ударения (`). Такая команда вычисляется и вы-
полняется, а результирующий текст заменяет исходное выражение в пол-
ной командной строке. Выполняемая команда может содержать
последовательные команды, конвейеры или команды, сгруппированные в
скобках. Любые лишние пробелы, табуляции или символы новой строки,
появившиеся в результате выполнения команды, впоследствии удаляются
при обработке внутренних разделителей полей. Если нужно сохранить эти
лишние символы, примените двойные кавычки вокруг всего выражения.
5. Проверяется переназначение ввода-вывода. Если таковое имеет-
ся, исходный дескриптор файла (0, 1 или 2) закрывается, а затем отк-
рывается повторно с новым значением. Вновь открытый дескриптор файла
занимает в файловом вводе-выводе то же место, что и закрытый файловый
дескриптор. Символы переназначения удаляются из командной строки.
6. Поскольку командная строка могла измениться по сравнению со
своим исходным состоянием в результате подстановок, она вновь разби-
рается на слова с учетом переменной среды IFS. Эта переменная содер-
жит разделители между полями, которые отделяют слова друг от друга в
командной строке. Каждый символ командной строки, который занесен в
IFS, заменяется на пробел, чтобы разграничить слова. Все неэкраниро-
ванные пробелы, табуляции, символы новой строки и нулевые аргументы
удаляются из командной строки. Все экранированные значения переменных
защищены от разбора, выполняемого в соответствии с IFS. Для того что-
бы увидеть значение IFS, введите такой конвейер команд:
echo "<$IFS>" | od -bc
7. Далее shell ищет все слова, для которых требуется раскрытие
имени файла (метасимвола). Делается попытка сопоставить образец с
файлами текущего каталога. Если подходящие файлы найдены, они заменя-
ют выражение в командной строке. Если соответствия не обнаружено, ме-
тасимволы остаются в этом выражении. Все присвоения переменным защи-
щены от раскрытия метасимволов. Типичным примером является команда
"ls z*". Если имена каких-либо файлов начинаются с буквы z, эти имена
перечисляются. В противном случае печатается сообщение "z* not
found".
8. Если установлен флаг трассировки выполнения (-x), то команд-
ная строка отображается на стандартное устройство регистрации ошибок
перед тем, как она будет фактически выполнена. Если это командная
строка, то она выводится с префиксом "+", если же это просто присвое-
ние значения переменной, префикса нет.
9. На этом шаге всем переменным присваиваются значения, затем в
соответствии с переменной среды PATH ищется местонахождение команды.
Присвоение значений переменным происходит справа налево вдоль команд-
ной строки. Поиск по переменной PATH, наоборот, происходит слева нап-
раво. Если имя найдено, то полное маршрутное имя заменяет вызов ко-
манды в командной строке. Если переменная PATH имеет пустое значение,
подразумевается текущий каталог. Если в каком-либо месте исходного
имени команды имеется косая черта (/), то переменная PATH не просмат-
ривается, а считается, что указано полное маршрутное имя.
10. Наконец, команда выполняется. Если это встроенная команда,
текущий shell отрабатывает ее. В противном случае делается попытка
загрузить команду в память, как если бы это была скомпилированная
программа. Если эта попытка успешна, команда выполняется посредством
системного вызова exec(2). Если загрузка команды не удалась, то счи-
тается, что это командный файл еще одного интерпретатора shell, и по-
рождаемый shell читает этот командный файл в качестве своих данных.
СПЕЦИАЛЬНЫЕ СИМВОЛЫ SHELL-ПЕРЕМЕННЫХ
Приведенные здесь символы рассматриваются shell-переменными как
специальные, так как они означают завершение слова. Для того чтобы
использовать символ в его обычном значении, а не в качестве специаль-
ной функции, нужно экранировать его обратной косой чертой (\) или
взять в одинарные кавычки.
\b Пробел: код 20 (шестнадцатеричный), ограничитель слов
\n Символ новой строки: ^j, код A (шестнадцатеричный),
ограничитель слов
\t Табуляция: ^i, код 9, ограничитель слов
; Точка с запятой: завершает программный конвейер
( Левая скобка: ограничивает подчиненный shell
) Правая скобка: ограничивает подчиненный shell
| Вертикальная черта, или символ программного конвейера:
разделяет команды
^ Стрелка вверх, знак вставки: старый символ,
используемый в качестве |
> Правая угловая скобка (знак больше): переназначает
стандартный вывод
< Левая угловая скобка (знак меньше): переназначает
стандартный ввод
& Амперсанд: вызывает асинхронное (фоновое) выполнение
{ Левая фигурная скобка: очерчивает слово для
первоначального разбора слова
} Правая фигурная скобка: завершает знак очерчивания
слова
СПЕЦИАЛЬНЫЕ СИМВОЛЫ SHELL-ОПЕРАТОРОВ
Эти символы встречаются в синтаксисе операторов языка shell. Их
следует рассматривать как зарезервированные. Отдельные символы могут
использоваться по-разному. Например, символ # является комментарием в
операторе, а также может быть параметром, как в записи $#, означающей
количество аргументов в командной строке.
&& Двойной амперсанд: выполнить список, если программный
конвейер отработал успешно
|| Двойная вертикальная черта: выполнить список в случае
неудачи программного конвейера
` Знак ударения: перехватить стандартный вывод в команде
* При использовании в качестве параметра соответствует
всем позиционным параметрам; является также символом
генерации имен файлов, соответствующим любой строке
# Комментарий до конца строки; соответствует также
количеству позиционных параметров в командной строке
? При использовании в качестве параметра соответствует
статусу завершения последней синхронно выполненной
команды; используется также при генерации имен файлов
и означает при этом любой одинарный символ
- Обозначает флаги, влияющие на функционирование
интерпретатора shell
$ Вводит заменяемые параметры; соответствует также
идентификатору процесса
! При использовании в качестве параметра соответствует
идентификатору процесса последнего фонового задания;
применяется также в команде проверки, где означает "не"
" Двойная кавычка: окаймляет символы и разрешает
производить подстановку параметров
' Одинарная кавычка: окаймляет символы, но запрещает
подстановку параметров
\ Обратная наклонная черта: экранирует одиночный символ,
чтобы снять его специальное значение
[] Альтернативное использование для вызова команды
проверки. Применяется также при генерации имен файлов,
означая при этом диапазон символов
@ Соответствует каждому позиционному параметру
командной строки
>> Дополнить стандартный вывод
<< Переназначить стандартный ввод на вводимые строки
текста
& Используется как символ фонового процесса;
соответствует также "файловому дескриптору",
если используется в переадресации
ВСТРОЕННЫЕ ОПЕРАТОРЫ ЯЗЫКА SHELL
Перечисленные ниже команды употребляются в программах на языке
shell. Здесь имеется в виду System V Bourne shell.
В System V.2 - более новой версии System V - интерпретатор shell
имеет некоторые дополнительные команды, перечисленные в отдельном
списке.
Имеется также интерпретатор ksh (фактически это улучшенный
Bourne shell), обладающий возможностями командных строк, характерными
для csh (Си-shell). Интерпретатор ksh здесь не рассматривается.
ПРИМЕЧАНИЕ. Не позволяйте команде exec сбить вас с толку. Это не
то же самое, что команда exec(2). Данная команда exec обрабатывается
интерпретаторм shell, а exec(2) является системным вызовом.
КОМАНДЫ System V Bourne Shell
. Точка: запустить данную команду из текущего
интерпретатора shell, а не из порождаемого
: Двоеточие: ничего не делать, а только возвратить
успешный статус (0)
{} Фигурные скобки: запустить последовательный список
команд
break Оборвать следующую итерацию текущего цикла
case Многократный выбор if-then-else
cd Сменить каталог
continue Перейти на следующую итерацию цикла for, while
или until
eval Выполнить еще раз этап подстановки переменных
exec Выполнить команду с аргументами, перекрывая
текущий shell
exit Остановить выполнение текущего командного файла
export Отправить значение переменной всем подчиненным
интерпретаторам shell
for Управляющее слово в цикле for-do-done
if Управляющее слово в последовательности if-then-else
newgrp Изменить текущий идентификатор группы
read Одну строку стандартного ввода присвоить переменной
в качестве значения
readonly Объявить переменную только для чтения, ее значение
изменять нельзя
set Включение и выключение флагов конфигурации shell
shift Убрать позиционный параметр из командной строки
test Вычислить взаимосвязи между строками и целыми числами
times Печатать время работы процессов, запущенных
из shell
trap Определить обработчики прерываний для конкретных
сигналов
ulimit Установить предел размера файлов в 512-байтных блоках
umask Маска прав доступа к файлам, используемая при их
создании
until Управляющее слово в цикле until-do-done
wait Shell ждет завершения указанных порожденных
процессов
while Управляющее слово в цикле while-do-done
ДОПОЛНИТЕЛЬНЫЕ КОМАНДЫ System V.2
hash При поиске команд использовать хэширование
name Определить имя shell-функции
pwd Сообщить текущий каталог; теперь это встроенная
команда для ускорения
return Выйти из shell-функции и возвратить значение
set -f Запретить фазу генерации имен файлов
set -h Сохранить, а не выполнять функциональные команды,
если они определены
type Определить, каким образом можно интерпретировать
имя в качестве команды
unset Удалить shell-переменные и функции>-!
>
находится в буфере а. Чтобы ее выполнить мы просто напечатаем @a в
командном режиме vi.
Чтобы выйти мы можем выполнить ту же последовательность
действий, но поместить команду типа
:!ps -ef
в редактор и переписать ее в буфер. Потом, когда мы говорим @a, мы
входим в shell и запускаем команду ps. Команды такого типа можно
помещать в именованные буферы от a-z.
Последний способ использования макросов для поддержки выхода - это
через команду map. Эта команда есть в ex и адресуется предшествующим
двоеточием : из vi. Синтаксис для команды map выглядит так:
:map lhs rhs
Это устанавливает отображение левой стороны на правую сторону.
Пример присвоения выглядит так:
:map w :!who^M
Теперь каждый раз, когда Вы печатаете w, будет выполняться
действие выхода через ex, печататься команда who, потом печататься
возврат каретки, который отправляет всю эту последовательность на
выполнение. Все это по одному нажатию клавиатуры.
Самое смешное начинается, когда Ваш терминал имеет
функциональные клавиши. Vi обращается к функциональным клавишам по #0
-#9. Теперь мы можем зарезервировать функциональные клавиши для
команд выхода. Простое присвоение будет:
:map #1 :!ps -ef^
Каждый раз, когда Вы нажимаете функциональную клавишу F1,
- 19 -
запускается команда ps -ef.
Команда "One-Liners" - крошечная, но мощная
Следующий список - это подборка обычных команд, использованных
таким образом, чтобы получить мощный эффект. Как мастер военного
искусства, который убивает голыми руками, мастер UNIX часто может
сложить вместе несколько обычных команд и достичь колоссального
эффекта. Некоторые строки, которые будут представлены ниже, можно
встретить в других местах этой книги, но они приводятся здесь
повторно для облегчения поиска.
Строки группируются в соответствии с командой, которая является
ключевой в данной строке, однако, иногда сложно выделить такую
команду как, например, в случае программного канала, когда Вы с двух
сторон имеете важные команды. Заметьте, что некоторые из этих команд
являются стандартными командами UNIX, в то время как другие - это
командные файлы и программы, представленные ранее в этой книге.
ACCTCOM
* прочитать всю Вашу учетную информацию, начиная с последней команды.
acctcom -b -u$LOGNAME
* показать все учетные записи, запущенные с Вашего терминала и того,
который запущен как суперпользователь
acctcom -u# -l'tty'
BANNER
* напечатать сообщение на трех строках
banner "line 1" "line2" "line3"
* напечатать день недели и дату на одной строке, время на другой
banner "'date|cut -d' ' -f1,3'" "'date|cut -d''-f4'"
* послать сообщение на экран другого пользователя
banner "Привет" "там" > /dev/tty01
BASENAME
* очистить путь
echo "Я за устройством 'basename\'tty\' ' ''
BC
* передать формулу на вход команде bc, которая должна выполнить
умножение и присвоит результат PROD
PROD = 'echo $NUM1 * $NUM2 | bc'
CAT
- 20 -
* передать символы с клавиатуры в файл
cat > file (печатать пока не встретится символ ^D
для прекращения чтения)
* получить ввод из конструкции "документ здесь"
cat << -!
Это образец текста, который печатается на экране !
CC
* множественная компиляция в фоновом режиме из одной командной
строки
cc file1.c & cc file2 & cc file3.c &
CD
* перейти в каталаг, в котором находится файл
cd 'имя директория\'путь файл\''
* перейти в каталог, который записан в переменной
DESTINATION="/usr/bin"
cd $DESTINATION
* перейти в каталог, записанный в файле
cd 'cat dest_file'
CHMOD
* включить бит исполнения файла
chmod +x file
* включить бит смены идентификатора пользователя и разрешить
всем выполнение файла
chmod 4755 file
* установить бит sticky во включенное состояние
chmod 1755 file
CHOWN
* установить себя владельцем файла
chown $LOGMAME files
* то же самое другим способом
chown 'who am i| cut -d' '-f1' files
* изменить право собственности для дерева
- 21 -
cd dest
find . -print | sort | while read FILE
do
chown russ $FILE
done
CP
* скопировать три уровня файлов в один вкаталог /tmp
cp */*/* /tmp
* то же самое другим способом
cp 'find . -type f -print' /tmp
* переключить пользовательское предложение
cp -z
CPIO
* переместить дерево системы файлов в новое местоположение
cd $SRC
find .-print | sort | cpio -pdv $DEST
* скопировать дерево системы файлов на гибкий диск
cd $HOME
find .-print | sort | cpio -ocBv > /dev/rfd0
* восстановить копию на стримере
cd $DEST
cpio -icBvt < /dev/rfd0
* выполнить "ls -l" на копии стримера
cpio -icBvt < /dev/rfd0
CRON
* запустите Ваш генератор сообщений о статусе каждый четверг
в 6:00 a.m.
0 6 * * 4 /usr/russ/bin/status_msg
* chmod на файл паролей
* * * * * /bin/su root -c "chmod 777 /etc/passwd"
CU
* непосредственно обратиться последовательному порту на скорости
1200 бод
cu -ltty00 dir
* непосредственно обратиться к последовательному порту на скорости
9600 бод
cu -ltty00 -s9600 dir
* автоматически вызвать другую систему, используя комбинацию
dial/modem
cu -acua0 555-1212
- 22 -
CUT
* отсечь первое поле из файла passwd
cut -d: -f1 /etc/passwd
* отсечь имя из листинга команды who
who | cut -d' ' -f1
who | awk '{print $1}
DD
* полная гибкая копия дорожка за дорожкой
dd if = /dev/fd0 of=/dev/fd1
DOS
* скопировать все файлы данного каталога на дискету DOS
doscp * a:
* скопировать все файлы с дискеты DOS в данный каталог
dosls a: > /tmp/dosf
for FILE in 'cat /tmp/dosf'
do
doscp a:$FILE
done
DU
* выдать общее количество блоков для всех каталогов в /
du -s /*
* напечатать количество использованного места в каталоге
каждого пользователя
echo "total bytes: 'expr\'du -s $1\' \* 512'"
ECHO
* напечатать значение переменной shell'а
echo $PATH $CDPATH
* напечатать вывод вперемешку с обычным текстом
echo " Мое имя $LOGNAME или
'logname' или 'who am i|cut -d' ' -f1'"
* напечатать символы упраления в кавычках и без
echo "\n\t Это записано в кавычках"
echo \\n\\t Это записано без кавычек
* напечатать и оставить курсор в конце той же строки
- 23 -
echo -n "prompt: "
echo "prompt: \c"
ED
* запустить ed автоматичски с конструкцией
"документ здесь"
ed /etc/passwd <<-!
1,$p
g/root/s//noroot
w
q
!
EXPR
* умножить два числа
expr 512 \* 1024
* увеличить переменную на предопределенное значение
x = 0; INC = 5
X='expr $X + $INC'
FILE
* найти все текстовые файлы
file * | fgrep text
* напечатать имена только текстовых файлов
file * | fgrep text | cut -d: -f1
* more все текстовые файлы
more 'file * | fgrep text | cut -d: -f1'
FIND
* найти все файлы в системе
find / -print | sort
* найти все файлы и распечатать список в формате long
find / -exec ls -ld {} \;
* напечатать имена всех регулярных файлов
find / -type f print
* найдите все каталоги и распечатайте содержимое
find / -type d print | while read DIR
do
echo "listing $DIR"
ls $DIR
done
* найдите все файлы, которые были модифицированы в последние
24 часа и распечатайте их список в формате long
find / -atime -0 -exec ls -ld {} \;
- 24 -
* найдите все файлы setuid и setgid
find / -perm -4000 -o -perm -2000 -exec ls -ld {} \;
FINGER
* укажите всех пользователей, вышедших из системы
finger 'who | cut -d' ' -f1'
* укажите всех пользователей в файле passwd
cut -d: -f1 /etc/passwd | while read NAME
do
finger $NAME
done
GREP
* найти случаи употребления шестнадцатиричных чисел в файле
данных
od -x datafile | grep 'A3F09'
* найти свое имя в системе
find / -type f print | while read FILE
do
grep "russ" $FILE /dev/null
done
HEAD
* озаглавьте все текстовые файлы в текущем каталоге
file * | fgrep text | cut -d: -f1 | while read FILE
do
echo "--------"
echo "$FILE"
echo "--------"
head "$FILE"
ID
* определить, кто в данный момент является суперпользователем
if [ "'id'" = "uid=0(root) gid=0(root)" ]
then echo "you are root"
fi
* то же самое другим способом
if id | fgrep root > /dev/null
then echo "you are root"
fi
KILL
* уничтожьте себя (выгрузите)
kill -9 0
kill -9 $$
* завершите работу системы
kill -1 1
* уничтожьте последний процесс, запущенный в фоновом режиме
kill -9 $!
- 25 -
* уничтожьте процесс, идентификатор которого находится в файле
kill -9 'cat idfile'
LINE
* взять строку с терминала
LINE='line < /dev/tty'
* взять строку из стандартного ввода
cat datafile | while LINE = 'line'
do
echo $LINE
done
LOGIN
* перейти из сгенерированной подсказки login ???
login: ^d
login:
* получить некоторую внутреннюю информацию
(программа strings - это BSD)
strings /bin/login | more
LOGNAME
* напечатать информацию о своем пароле
grep '^'logname ':' /etc/passwd
* получить информацию о своем процессе
ps -fu 'logname'
LS
* выдать список скрытых файлов
ls -ad .*
* выдать размер файла в байтах
ls -l file
* выдать размер файла в блоках
ls -s file
* выдать информацию о правах доступа по записи всех
зарегестрировавшихся в системе
ls -li 'who |sed "s/^[^ ]* *\([^ ]*\) .*$/\/dev\/\1/p"'
* получить помощь по испоьзованию команды
ls -z
* выдать список только каталогов
ls -al |grep "^d"
* послать почту всем пользователям
- 26 -
cut -d: -f1 |while read USER
do
echo "mailing to $USER"
mail $USER
done
* послать почту из файла
mail russ < /etc/passwd
* послать почту из программного канала
echo "Это текст почты" | mail russ
MORE
* напечатать все файлы текущего каталога
more *
* напечатать 10 строк за раз
more -10 file
cat file | more -10
MKDIR
* опуститься на максимальную глубину
while :
do
mkdir x
cd x
done
* то же самое другим способом
PATH="x"
while :
do
mkdir $PATH
PATH="$PATH/x"
done
NCHECK
* найти все файлы, присоединенные к vi
ls -li /bin/vi
40 -rwwx--x--t 1109344 Feb 14 1985 /bin/vi
ncheck -i 40 /dev/root
* найти все файлы установки идентификатора пользователя
ncheck -s
NM
* посмотреть символьные таблицы всех nonstripped
исполняемых файлов
nm 'file *| grep "not stripped"|sed "s/^\(.*\):.*$/\1/"
OD
* посмотреть символы в именах файлов в текущем каталоге
- 27 -
od -c .
* напечатать значение функциональных клавиш, комбинаций
клавиш, и.т.д.
od -cb (нажмите комбинацию клавиш)
^d (печатает строку)
(нажмите что-нибудь еще)
^d (печатает следующую строку)
^d (выыходит из od)
* сделать дамп копии на стримере
od -c /dev/rfd0
* сделать дамп файловой системы
od -c /dev/root
PASSWD
* как суперпользователь Вы можете установить в качестве пароля
любую строку
# passwd russ
Changing password for russ
(Изменение пароля для russ)
Enter new password (minimum of 5 characters)
(Введите новый пароль (минимум 5 символов))
Please use combination of upper, lowercase letters
and numbers
(Просьба использовать комбинации чисел и букв в
верхнем и нижнем регистрах)
New password: junk
(Новый пароль: junk)
Re-enter new password: junk
(Новый пароль: junk)
#
* как обычный пользователь Вы должны будете вводить пароль с учетом
количественных ограничений и ограничений по длине
$ passwd russ
Changing password for russ
(Изменение пароля для russ)
Enter new password (minimum of 5 characters)
(Введите новый пароль (минимум 5 символов))
Please use combination of upper, lowercase letters
and numbers
(Просьба использовать комбинации чисел и букв в
верхнем и нижнем регистрах)
New password: junk
(Новый пароль: junk)
Too short. Password unchanged.
(Слишком короткий. Пароль не изменен)
$
PR
* вывести многоколоночный список имен файлов
ls $@ | pr -5t
* напечатать файлы из списка
- 28 -
pr 'find . -name "*.c" -print | sort'
PS
* напечатать полную информацию обо всех активных процессах
ps -aef
* напечатать информацию обо всех процессах, управляемых
Вашим терминалом
ps -f
* напечатать информацию о процессах, связанных с терминалом tty00
ps -ft00
* напечатать информацию о процессах, связанных с пользователем russ
ps -furuss
* BSD синтаксис для печати всех процессов
ps -aux
* BSD синтаксис для печати всех процессов, связанных с
терминальным устройством
ps -xut00
PWD
* сохранить текущий рабочий каталог
PWD='pwd'
* вернуться в ранее сохраненный рабочий каталог
cd $PWD
RM
* удалить все файлы, кроме каталогов с файлами
rm *
* удалить пустые каталоги
rmdir dirs
* удалить каталоги, имеющие файлы
rm -r dirs
* удалить все файлы в режиме, когда система не будет
задавать никаких вопросов
rm -rf *
* удалить каждый файл в системе по отдельности
rm -rf /
SH
* прочитать список поэлементно
for ELEMENT in 'cat /etc/motd'
do
- 29 -
echo $ELEMENT
done
* прочитать список построчно
cat /etc/motd | while read LINE
do
echo $LINE
done
* цикл пока - навсегда (while-forever)
while :
do
echo $PS1
read CMD
case $CMD in
"") break;;
esac
done
* управляемый цикл while
read CMD
while [ "$CMD" != ""]
do
case $CMD in
user-cmd) do_it;;
esac
echo $PS1
read CMD
done
* переполнениие тестового стека при обработке
прерывания
trap "echo trapping; kill $$" 2 3 15
* выгрузка из языка shell несколькими способами
exit
eof character (usually control -d)
kill -9 0
kill -9 $$
STTY
* посмотрите все свои установки
stty -a
* посмотрите терминальные установки
другого терминала
stty -a < /dev/tty01
* установить передачу бод на другую скорость для
другого терминала
stty 300 < /dev/tty01
* динамически установить control-A как клавишу
прерывания
stty intr ^a
* включить эхо-сопровождение терминала
stty -echo
- 30 -
SU
* тестовый цикл для уничтожения легких паролей
awk '{FS =":"; print $1,$5} '/etc/passwd|while read N C
do
echo "\n$N\t$C"
su $N
done
TAIL
* проследить в реальном времени запись транзакций файла
входа в систему (logfile) uucp
tail -f /usr/spool/uucp/LOGFILE
* посмотреть последнюю строку файла
tail -1 file
* посмотреть последние 10 символов переменной
echo "$VAR" | tail -10c
TAR
* сделать копии файлов в Вашем home-каталоге не разрывая файл, но
формируя копии на куски по 1200 блоков
cd
tar cvefbk /dev/rfd0 10 1200 .
* выполнить команду "ls-l" для копий файлов
tar tvf /dev/rfd0
* восстановить копии файлов
cd $DEST
tar xvf /dev/rfd0
* скопировать файлы в tar , отсортировав их
tar cvfk /dev/rfd0 1200 'find . -print | sort'
TEE
* отправьте свой вывод на экран другого терминала
sh | tee /dev/tty01
* захватите вывод других команд
fsck /dev/root | tee capture
cu -ltty00 dir | tee capture
TEST
* проверьте эквивалентность двух строк
test "$S1" = "$S2"
* проверьте эквивалентность двух чисел
test "$N1" -eq "$N2"
* то же самое другим способом
(заметьте что /bin/[присоединен к /bin/test)
- 31 -
[ "$S1" = "$S2" ]
[ "$N1" -eq "$N2" ]
TOUCH
* сделайте текущим доступ и измените время всех файлов в Вашем
home каталоге
find $HOME -exec touch {} \;
find $HOME -print | while read FILE
do
touch $FILE
done
TTY
* показать права доступа по записи на Вашем терминале
ls -l 'tty'
* включить и отключить доступ пользователей к Вашему терминалу
chmod 666 'tty'
chmod 600 'tty'
UUCP
* скопировать имена всех файлов в файл в общедоступный каталог на
другой системе
for FILE in 'cat datafile'
do
echo "копирование $FILE"
uucp $FILE sys! ~/user
done
* поставить файл в очередь, не инициировать вызов, взять файл из
Вашего первоначального каталога, не копирровать его в spool
каталог.
uucp -r -c file sys!/tmp
VI
* выполните текущую строку как команду языка shell
:.w !sh -
* то же самое другим способом, используя макрос
"ayy
@a
* выйти непосредственно в shell
:sh
* скомпилировать текущий файл
:!sh
* запустить имя текущего файла как комаду языка shell
:!cc %
* запустить еще раз последнюю команду
:!%
- 32 -
* запустить команду и поместить ввывод на текущую
строку (переписать)
:.!who am i
* запустить команду и поместить ввывод на новую строку
:.r !who am i
:r !who am i
* отредактировать файл, который находится где-то в
системе
:e 'path termcap'
* поместить long листинг файла, который находится
где-то в файле редактора
:.!ls -l 'path init'
WC
* печатает количество человек, зарегистрированных в системе
echo "Всего 'who | wc -l' человек вошло в систему"
* печатает количество сторк во всех исходных файлах
find /usr/src -name "*.c" -exec cat {} \; | wc -l
WHO
* печатает количество и имена зарегистрированных
пользователей
who | awk '{ print "user:",$1,"\tdevice:",$2
cnt = cnt + 1
} END { print cnt,"пользователи, вышедшие из системы"}'
* печатает
who | while read NAME TTY TIME
do
echo "пользователь: $NAME tty: $TTY time: $TIME
done
Некоторые переменные среды являются зарезервированными словами,
которые использует интерпретатор shell. Их значения устанавливаются,
когда вы регистрируетесь в системе. Другие переменные используются
различными другими частями системы UNIX. Имея под рукой полный спи-
сок, вы можете убедиться, что все необходимые переменные определены.
Имена переменных могут варьироваться в System V, BSD и XENIX. Здесь
приведены имена для System V.
Эти shell-переменные являются частью среды вашего регистрацион-
ного интерпретатора shell. Они хранятся в виде символьных строк, и
если уж они установлены, от них нельзя избавиться. Только переуста-
новка их значений на пустые строки может исключить их присутствие.
Когда меняются значения переменных, новые значения локальны для теку-
щего интерпретатора shell до тех пор, пока они не будут экспортирова-
ны.
CDPATH Строка поиска, определяющая, куда вы можете
перейти с помощью команды cd
HOME Место хранения ваших файлов в системном дереве
IFS Внутренний разделитель полей, который определяет
символы, разделяющие слова между собой
LOGNAME Ваше регистрационное имя, определенное в /etc/passwd
MAIL Определяет местонахождение вашего почтового ящика,
чтобы вас можно было оповестить о поступлении вам
новой почты
PATH Определяет порядок и имена каталогов для поиска
исполняемых модулей
PS1 Главная строка подсказки, которая отображается
в качестве вашего обычного приглашения
PS2 Вторичная строка подсказки, которая отображается,
когда интерпретатору shell нужен дополнительный ввод
TERM Строка, определяющая ваш тип терминала
TERMCAP Устанавливается либо на файл описания терминала,
либо на запись этого файла
TZ Зона времени, понимаемая так, как описано в ctime(3)
SHELL Имя shell-интерпретатора, который вы запускаете
EXINIT Строка инициализации для редактора ex
ПОСЛЕДОВАТЕЛЬНОСТЬ ДЕЙСТВИЙ ИНТЕРПРЕТАТОРА SHELL
Shell выполняет определенную последовательность действий по ин-
терпретации команд для каждой прочитанной им строки. Зная эту после-
довательность, вы можете изолировать многие проблемы на соответствую-
щем уровне. Иногда на определенном шаге этой последовательности могут
появиться странные вхождения символов. Поэтому важно знать, когда из-
меняются значения переменных.
Один из примеров относится к раскрытию имени файла и символу
звездочки. Shell НЕ раскрывает метасимволы во время присвоения значе-
ний. Оператор F=* означает в действительности, что переменной F прис-
ваивается один символ. Когда выполняется шаг 7 последовательности
действий, звездочка раскрывается как метасимвол имени файла, превра-
щаясь во все имена файлов в текущем каталоге. Это можно продемонстри-
ровать на примере команды "echo $F". Для того чтобы сохранить лите-
ральное значение звездочки, вам нужно экранировать ее, что защитит ее
от шага 7. Получается команда echo "$F". А для того чтобы вообще по-
давить значение переменной F, вам следует исключить шаг 3 - подста-
новку параметров. Указывая команду echo '$F', вы печатаете буквы $F,
а не значение переменной F.
Действия выполняются в таком порядке:
1. Чтение входа и синтаксический разбор
2. Словесное сопровождение разбора
3. Подстановка параметров
4. Подстановка команд
5. Переназначение ввода-вывода
6. Обработка внутренних разделителей полей
7. Раскрытие имени файла
8. Трассировка выполнения
9. Обработка переменных среды
10. Выполнение команды
Далее эти шаги рассматриваются более подробно. Когда вы програм-
мируете на языке shell, попытайтесь представить себе, какой шаг вы
используете для каждой строки текста программы. Возможно, вы путаете
два-три шага между собой. Зная порядок шагов, вы можете проще опреде-
лять эффект от действия ваших команд и сокращать число возможных оши-
бок.
1. Командная строка или логическая конструкция читается с терми-
нала или из файла данных. Чтение останавливается при обнаружении сле-
дующих символов: точки с запятой (;), символа фоновой задачи (&), ло-
гического и (&&), логического или (||) либо символа новой строки
(\n). Выполняется разбор введенных данных на слова с учетом пробелов
и табуляций.
2. Если в текущем интерпретаторе shell установлен флаг многос-
ловности (-v), то прочитанная строка отображается на стандартное уст-
ройство регистрации ошибок.
3. Выполняется подстановка параметров. Сюда входит подстановка
позиционных параметров, подстановка переменных и подстановка специ-
альных выражений. Параметры всегда имеют префикс в виде денежного
знака ($).
4. Выполняется подстановка команд. Это относится ко всем коман-
дам, взятым в символы ударения (`). Такая команда вычисляется и вы-
полняется, а результирующий текст заменяет исходное выражение в пол-
ной командной строке. Выполняемая команда может содержать
последовательные команды, конвейеры или команды, сгруппированные в
скобках. Любые лишние пробелы, табуляции или символы новой строки,
появившиеся в результате выполнения команды, впоследствии удаляются
при обработке внутренних разделителей полей. Если нужно сохранить эти
лишние символы, примените двойные кавычки вокруг всего выражения.
5. Проверяется переназначение ввода-вывода. Если таковое имеет-
ся, исходный дескриптор файла (0, 1 или 2) закрывается, а затем отк-
рывается повторно с новым значением. Вновь открытый дескриптор файла
занимает в файловом вводе-выводе то же место, что и закрытый файловый
дескриптор. Символы переназначения удаляются из командной строки.
6. Поскольку командная строка могла измениться по сравнению со
своим исходным состоянием в результате подстановок, она вновь разби-
рается на слова с учетом переменной среды IFS. Эта переменная содер-
жит разделители между полями, которые отделяют слова друг от друга в
командной строке. Каждый символ командной строки, который занесен в
IFS, заменяется на пробел, чтобы разграничить слова. Все неэкраниро-
ванные пробелы, табуляции, символы новой строки и нулевые аргументы
удаляются из командной строки. Все экранированные значения переменных
защищены от разбора, выполняемого в соответствии с IFS. Для того что-
бы увидеть значение IFS, введите такой конвейер команд:
echo "<$IFS>" | od -bc
7. Далее shell ищет все слова, для которых требуется раскрытие
имени файла (метасимвола). Делается попытка сопоставить образец с
файлами текущего каталога. Если подходящие файлы найдены, они заменя-
ют выражение в командной строке. Если соответствия не обнаружено, ме-
тасимволы остаются в этом выражении. Все присвоения переменным защи-
щены от раскрытия метасимволов. Типичным примером является команда
"ls z*". Если имена каких-либо файлов начинаются с буквы z, эти имена
перечисляются. В противном случае печатается сообщение "z* not
found".
8. Если установлен флаг трассировки выполнения (-x), то команд-
ная строка отображается на стандартное устройство регистрации ошибок
перед тем, как она будет фактически выполнена. Если это командная
строка, то она выводится с префиксом "+", если же это просто присвое-
ние значения переменной, префикса нет.
9. На этом шаге всем переменным присваиваются значения, затем в
соответствии с переменной среды PATH ищется местонахождение команды.
Присвоение значений переменным происходит справа налево вдоль команд-
ной строки. Поиск по переменной PATH, наоборот, происходит слева нап-
раво. Если имя найдено, то полное маршрутное имя заменяет вызов ко-
манды в командной строке. Если переменная PATH имеет пустое значение,
подразумевается текущий каталог. Если в каком-либо месте исходного
имени команды имеется косая черта (/), то переменная PATH не просмат-
ривается, а считается, что указано полное маршрутное имя.
10. Наконец, команда выполняется. Если это встроенная команда,
текущий shell отрабатывает ее. В противном случае делается попытка
загрузить команду в память, как если бы это была скомпилированная
программа. Если эта попытка успешна, команда выполняется посредством
системного вызова exec(2). Если загрузка команды не удалась, то счи-
тается, что это командный файл еще одного интерпретатора shell, и по-
рождаемый shell читает этот командный файл в качестве своих данных.
СПЕЦИАЛЬНЫЕ СИМВОЛЫ SHELL-ПЕРЕМЕННЫХ
Приведенные здесь символы рассматриваются shell-переменными как
специальные, так как они означают завершение слова. Для того чтобы
использовать символ в его обычном значении, а не в качестве специаль-
ной функции, нужно экранировать его обратной косой чертой (\) или
взять в одинарные кавычки.
\b Пробел: код 20 (шестнадцатеричный), ограничитель слов
\n Символ новой строки: ^j, код A (шестнадцатеричный),
ограничитель слов
\t Табуляция: ^i, код 9, ограничитель слов
; Точка с запятой: завершает программный конвейер
( Левая скобка: ограничивает подчиненный shell
) Правая скобка: ограничивает подчиненный shell
| Вертикальная черта, или символ программного конвейера:
разделяет команды
^ Стрелка вверх, знак вставки: старый символ,
используемый в качестве |
> Правая угловая скобка (знак больше): переназначает
стандартный вывод
< Левая угловая скобка (знак меньше): переназначает
стандартный ввод
& Амперсанд: вызывает асинхронное (фоновое) выполнение
{ Левая фигурная скобка: очерчивает слово для
первоначального разбора слова
} Правая фигурная скобка: завершает знак очерчивания
слова
СПЕЦИАЛЬНЫЕ СИМВОЛЫ SHELL-ОПЕРАТОРОВ
Эти символы встречаются в синтаксисе операторов языка shell. Их
следует рассматривать как зарезервированные. Отдельные символы могут
использоваться по-разному. Например, символ # является комментарием в
операторе, а также может быть параметром, как в записи $#, означающей
количество аргументов в командной строке.
&& Двойной амперсанд: выполнить список, если программный
конвейер отработал успешно
|| Двойная вертикальная черта: выполнить список в случае
неудачи программного конвейера
` Знак ударения: перехватить стандартный вывод в команде
* При использовании в качестве параметра соответствует
всем позиционным параметрам; является также символом
генерации имен файлов, соответствующим любой строке
# Комментарий до конца строки; соответствует также
количеству позиционных параметров в командной строке
? При использовании в качестве параметра соответствует
статусу завершения последней синхронно выполненной
команды; используется также при генерации имен файлов
и означает при этом любой одинарный символ
- Обозначает флаги, влияющие на функционирование
интерпретатора shell
$ Вводит заменяемые параметры; соответствует также
идентификатору процесса
! При использовании в качестве параметра соответствует
идентификатору процесса последнего фонового задания;
применяется также в команде проверки, где означает "не"
" Двойная кавычка: окаймляет символы и разрешает
производить подстановку параметров
' Одинарная кавычка: окаймляет символы, но запрещает
подстановку параметров
\ Обратная наклонная черта: экранирует одиночный символ,
чтобы снять его специальное значение
[] Альтернативное использование для вызова команды
проверки. Применяется также при генерации имен файлов,
означая при этом диапазон символов
@ Соответствует каждому позиционному параметру
командной строки
>> Дополнить стандартный вывод
<< Переназначить стандартный ввод на вводимые строки
текста
& Используется как символ фонового процесса;
соответствует также "файловому дескриптору",
если используется в переадресации
ВСТРОЕННЫЕ ОПЕРАТОРЫ ЯЗЫКА SHELL
Перечисленные ниже команды употребляются в программах на языке
shell. Здесь имеется в виду System V Bourne shell.
В System V.2 - более новой версии System V - интерпретатор shell
имеет некоторые дополнительные команды, перечисленные в отдельном
списке.
Имеется также интерпретатор ksh (фактически это улучшенный
Bourne shell), обладающий возможностями командных строк, характерными
для csh (Си-shell). Интерпретатор ksh здесь не рассматривается.
ПРИМЕЧАНИЕ. Не позволяйте команде exec сбить вас с толку. Это не
то же самое, что команда exec(2). Данная команда exec обрабатывается
интерпретаторм shell, а exec(2) является системным вызовом.
КОМАНДЫ System V Bourne Shell
. Точка: запустить данную команду из текущего
интерпретатора shell, а не из порождаемого
: Двоеточие: ничего не делать, а только возвратить
успешный статус (0)
{} Фигурные скобки: запустить последовательный список
команд
break Оборвать следующую итерацию текущего цикла
case Многократный выбор if-then-else
cd Сменить каталог
continue Перейти на следующую итерацию цикла for, while
или until
eval Выполнить еще раз этап подстановки переменных
exec Выполнить команду с аргументами, перекрывая
текущий shell
exit Остановить выполнение текущего командного файла
export Отправить значение переменной всем подчиненным
интерпретаторам shell
for Управляющее слово в цикле for-do-done
if Управляющее слово в последовательности if-then-else
newgrp Изменить текущий идентификатор группы
read Одну строку стандартного ввода присвоить переменной
в качестве значения
readonly Объявить переменную только для чтения, ее значение
изменять нельзя
set Включение и выключение флагов конфигурации shell
shift Убрать позиционный параметр из командной строки
test Вычислить взаимосвязи между строками и целыми числами
times Печатать время работы процессов, запущенных
из shell
trap Определить обработчики прерываний для конкретных
сигналов
ulimit Установить предел размера файлов в 512-байтных блоках
umask Маска прав доступа к файлам, используемая при их
создании
until Управляющее слово в цикле until-do-done
wait Shell ждет завершения указанных порожденных
процессов
while Управляющее слово в цикле while-do-done
ДОПОЛНИТЕЛЬНЫЕ КОМАНДЫ System V.2
hash При поиске команд использовать хэширование
name Определить имя shell-функции
pwd Сообщить текущий каталог; теперь это встроенная
команда для ускорения
return Выйти из shell-функции и возвратить значение
set -f Запретить фазу генерации имен файлов
set -h Сохранить, а не выполнять функциональные команды,
если они определены
type Определить, каким образом можно интерпретировать
имя в качестве команды
unset Удалить shell-переменные и функции>-!
>