Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Справочный материал / Advanced-Bash-Scripting-Guide.pdf
Скачиваний:
717
Добавлен:
25.02.2015
Размер:
13.03 Mб
Скачать

then

let "t1 = $column - $row" let "t2 = $column"

else

let "t1 = $column"

filet "t2 = $column + $row"

filter $t1 $t2 # Отфильтровать отрицательный индекс. done

echo; echo done

# Поворот массива выполнен на основе примеров (стр. 143-146)

# из книги "Advanced C Programming on the IBM PC", автор Herbert Mayer

# (см. библиографию).

}

#-----------------------------------------------------

 

 

#

load_alpha

# Инициализация массива.

print_alpha

# Вывод на экран.

rotate

# Повернуть на 45 градусов против часовой стрелки.

#-----------------------------------------------------

 

 

#

# Упражнения:

 

 

# -----------

Сделайте

инициализацию

и вывод массива на экран

# 1)

#

+ более простым и

элегантным способом.

#

Объясните

принцип работы функции rotate().

# 2)

exit

0

 

 

По существу, двумерный массив эквивалентен одномерному, с тем лишь различием, что для индексации отдельных элементов используются два индекса -- "строка" и "столбец".

Более сложный пример эмуляции двумерного массива вы найдете в Пример A-11.

Глава 26. Файлы

сценарии начальной загрузки

Эти файлы содержат объявления псевдонимов и переменных окружения, которые становятся доступны Bash после загрузки и инициализации системы.

/etc/profile

Настройки системы по-умолчанию, главным образом настраивается окружение командной оболочки (все Bourne-подобные оболочки, не только Bash [55])

/etc/bashrc

функции и псевдонимы Bash

$HOME/.bash_profile

пользовательские настройки окружения Bash, находится в домашнем каталоге у каждого пользователя (локальная копия файла /etc/profile)

$HOME/.bashrc

пользовательский файл инициализации Bash, находится в домашнем каталоге у каждого

311

пользователя (локальная копия файла /etc/bashrc). См. Приложение Iпример файла .bashrc.

Сценарий выхода из системы (logout)

$HOME/.bash_logout

Этот сценарий отрабатывает, когда пользователь выходит из системы.

Глава 27. /dev и /proc

Как правило, Linux или Unix система имеет каталоги специального назначения: /dev и /proc.

27.1. /dev

Каталог /dev содержит файлы физических устройств, которые могут входить в состав аппаратного обеспечения компьютера. [56] Каждому из разделов не жестком диске соответствует свой файл-устройство в каталоге /dev, информация о которых может быть получена простой командой df.

bash$ df

1k-blocks

Used Available Use%

 

Filesystem

 

Mounted on

495876

222748

247527

48%

/

/dev/hda6

/dev/hda1

50755

3887

44248

9% /boot

/dev/hda8

367013

13262

334803

4% /home

/dev/hda5

1714416

1123624

503704

70%

/usr

Кроме того, каталог /dev содержит loopback-устройства ("петлевые" устройства), например /dev/loop0. С помощью такого устройства можно представить обычный файл как блочное устройство ввода/вывода. [57] Это позволяет монтировать целые файловые системы, находящиеся в отдельных больших файлах. См. Пример 13-7 и Пример 13-6.

Отдельные псевдоустройства в /dev имеют особое назначение, к таким устройствам можно отнести

/dev/null, /dev/zero, /dev/urandom, и /dev/tcp.

Пример 27-1. Пример работы с псевдоустройством /dev/tcp

#!/bin/bash

# dev-tcp.sh: Пример перенаправления на псевдоустройство /dev/tcp

#

Автор: Troy

Engel.

#

Используется с разрешения автора.

TCP_HOST=www.slashdot.org

TCP_PORT=80

# 80-й порт -- это стандартный порт службы http.

# Попытка выполнить соединение. (Своего рода 'ping.') echo "HEAD / HTTP/1.0" >/dev/tcp/${TCP_HOST}/${TCP_PORT} MYEXIT=$?

: << EXPLANATION

Если bash собран с ключом --enable-net-redirections, то он имеет возможность использовать специальное символьное устройство для перенаправления TCP и UDP. Оно практически идентично стандартным устройствам STDIN/STDOUT/STDERR.

Создать это устройство (если его еще нет в системе) можно командой (разумеется, что при этом вы должны обладать правами root):

312

mknod /dev/tcp c 30 36

>Из руководства к bash: /dev/tcp/host/port

Если host является верным именем сетевого узла или IP-адресом, а port -- целое число или название сетевой службы, то Bash попытается открыть TCP-соединение

с соответствующим узлом. EXPLANATION

if [ "X$MYEXIT" = "X0" ]; then

echo "Соединение установлено. Код завершения: $MYEXIT" else

fiecho "Ошибка при попытке установить соединение. Код завершения: $MYEXIT" exit $MYEXIT

27.2. /proc

Фактически, каталог /proc -- это виртуальная файловая система. Файлы, в каталоге /proc, содержат информацию о процессах, о состоянии и конфигурации ядра и системы.

bash$

cat

/proc/devices

Character

devices:

1

mem

 

2

pty

 

3

ttyp

 

4

ttyS

 

5

cua

 

7

vcs

 

10

misc

 

14

sound

 

29

fb

 

36

netlink

128

ptm

 

136

pts

 

162

raw

 

254

pcmcia

Block devices:

1

ramdisk

2

fd

 

3

ide0

 

9

md

 

bash$

cat /proc/interrupts

 

 

0:

CPU0

XT-PIC

timer

84505

1:

3375

XT-PIC

keyboard

2:

0

XT-PIC

cascade

5:

1

XT-PIC

soundblaster

8:

1

XT-PIC

rtc

12:

4231

XT-PIC

PS/2 Mouse

14:

109373

XT-PIC

ide0

NMI:

0

 

 

ERR:

0

 

 

bash$

cat

/proc/partitions

rio rmerge rsect ruse wio wmerge wsect wuse running use aveq

major

minor

#blocks

name

3

 

0

3007872

hda 4472 22260 114520 94240 3551 18703 50384 549710 0 111550 644030

3

 

1

52416

hda1 27 395 844 960 4 2 14 180 0 800 1140

3

 

2

1 hda2 0 0 0 0 0 0 0 0 0 0 0

3

 

4

165280

hda4

10 0 20 210 0 0 0 0 0 210 210

...

 

 

 

 

bash$

cat

/proc/loadavg

 

313

0.13 0.42 0.27 2/44 1119

Сценарии командной оболочки могут извлекать необходимую информацию из соответствующих файлов в каталоге /proc. [58]

bash$ cat /proc/filesystems | grep iso9660 iso9660

kernel_version=$( awk '{ print $3 }' /proc/version )

CPU=$( awk '/model name/ {print $4}' < /proc/cpuinfo )

if [ $CPU = Pentium ] then

выполнить_ряд_специфичных_команд

...

else

выполнить_ряд_других_специфичных_команд

fi...

В каталоге /proc вы наверняка заметите большое количество подкаталогов, с не совсем обычными именами, состоящими только из цифр. Каждый из них соответствует исполняющемуся процессу, а имя каталога -- это ID (идентификатор) процесса. Внутри каждого такого подкаталога находится ряд файлов, в которых содержится полезная информация о соответствующих процессах. Файлы stat и status хранят статистику работы процесса, cmdline -- команда, которой был запущен процесс, exe -- символическая ссылка на исполняемый файл программы. Здесь же вы найдете ряд других файлов, но, с точки зрения написания сценариев, они не так интересны, как эти четыре.

Пример 27-2. Поиск файла программы по идентификатору процесса

#!/bin/bash

 

 

# pid-identifier.sh: Возвращает полный путь к исполняемому файлу программы по идентификатору

процесса

(pid).

 

 

ARGNO=1

# Число, ожидаемых из командной строки, аргументов.

E_WRONGARGS=65

 

 

E_BADPID=66

 

 

E_NOSUCHPROCESS=67

 

 

E_NOPERMISSION=68

 

 

PROCFILE=exe

 

 

if [ $# -ne $ARGNO ]

 

 

then

 

 

$0` PID-процесса" >&2 # Сообщение об ошибке на >stderr.

echo "Порядок использования: `basename

fiexit $E_WRONGARGS

 

 

ps ax

 

 

 

pidno=$(

ps ax | grep $1 | awk '{ print

$1 }' | grep $1 )

# Проверка наличия процесса

с заданным pid в списке, выданном командой "ps", поле #1.

# Затем

следует убедиться, что этот процесс не был запущен этим сценарием ('ps').

# Это делает последний "grep

$1".

 

314

if [ -z "$pidno"

] # Если после фильтрации получается пустая строка,

then

 

# то это означает, что в системе нет процесса с заданым pid.

echo "Нет такого процесса."

fiexit $E_NOSUCHPROCESS

# Альтернативный

вариант:

#

if ! ps $1 > /dev/null 2>&1

#

then

# в системе нет процесса с заданым pid.

#

echo "Нет такого процесса."

#

exit $E_NOSUCHPROCESS

#

fi

 

if [ ! -r "/proc/$1/$PROCFILE" ]

# Проверить право на чтение.

then

 

 

 

echo "Процесс $1 найден, однако..."

echo "у вас нет права на чтение файла /proc/$1/$PROCFILE."

exit $E_NOPERMISSION

# Обычный пользователь не имеет прав

fi

 

# на доступ к некоторым файлам в каталоге /proc.

 

 

 

# Последние две проверки могут быть заменены на:

#

if ! kill -0 $1 > /dev/null

2>&1 # '0' -- это не сигнал, но

 

 

 

# команда все равно проверит наличие

#

 

 

# процесса-получателя.

then echo "Процесс с данным PID не найден, либо вы не являетесь его владельцем" >&2

#

exit $E_BADPID

 

 

#

fi

 

 

exe_file=$( ls -l /proc/$1 | grep

"exe" | awk '{ print $11 }' )

# Или

exe_file=$( ls -l /proc/$1/exe | awk '{print $11}' )

#

 

 

 

# /proc/pid-number/exe -- это символическая ссылка

# на исполняемый файл работающей программы.

if [ -e "$exe_file" ]

# Если файл /proc/pid-number/exe существует...

then

# то существует и соответствующий процесс.

echo "Исполняемый файл процесса #$1: $exe_file."

else

 

 

 

fiecho "Нет такого процесса."

 

# В большинстве случаев, этот, довольно сложный сценарий, может быть заменен командой

# ps ax | grep $1 | awk '{ print $5 }'

# В большинстве, но не всегда...

# поскольку пятое поле листинга,выдаваемого командой 'ps', это argv[0] процесса,

# а не путь к исполняемому файлу.

#

# Однако, оба следующих варианта должны работать безотказно.

# find /proc/$1/exe -printf '%l\n'

# lsof -aFn -p $1 -d txt | sed -ne 's/^n//p'

# Автор последнего комментария: Stephane Chazelas. exit 0

Пример 27-3. Проверка состояния соединения

#!/bin/bash

 

 

PROCNAME=pppd

# демон

ppp

PROCFILENAME=status

# Что смотреть.

NOTCONNECTED=65

# Период проверки -- раз в 2 секунды.

INTERVAL=2

pidno=$( ps ax | grep -v "ps

ax" | grep -v grep | grep $PROCNAME | awk '{ print $1 }' )

# Найти идентификатор процесса 'pppd', 'ppp daemon'.

# По пути убрать из листинга записи о процессах, порожденных сценарием.

#

Однако, как отмечает Oleg

Philon,

#

#+ Эта последовательность команд может быть заменена командой "pidof".

#

pidno=$( pidof $PROCNAME )

 

#

Мораль:

 

 

#

 

 

315

Соседние файлы в папке Справочный материал