Категории
Самые читаемые
PochitayKnigi » Компьютеры и Интернет » Программирование » Искусство программирования на языке сценариев командной оболочки - Мендель Купер

Искусство программирования на языке сценариев командной оболочки - Мендель Купер

Читать онлайн Искусство программирования на языке сценариев командной оболочки - Мендель Купер

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 21 22 23 24 25 26 27 28 29 ... 96
Перейти на страницу:

done

# Список аргументов не задан, поэтому цикл работает с переменной '[email protected]'

#+ (список аргументов командной строки, включая пробельные символы).

echo

exit 0

При создании списка аргументов, в цикле for допускается пользоваться подстановкой команд. См. Пример 12-39, Пример 10-10 и Пример 12-33.

Пример 10-6. Создание списка аргументов в цикле for с помощью операции подстановки команд

#!/bin/bash

# уЩЫЬ for гЯ [гаЩгЫЯЭ], гЯкФСЮЮйЭ г аЯЭЯниР аЯФгдСЮЯзЫЩ ЫЯЭСЮФ.

NUMBERS="9 7 3 8 37.53"

for number in `echo $NUMBERS` # for number in 9 7 3 8 37.53

do

echo -n "$number "

done

echo

exit 0

Более сложный пример использования подстановки команд при создании списка аргументов цикла.

Пример 10-7. grep для бинарных файлов

#!/bin/bash

# bin-grep.sh: Поиск строк в двоичных файлах.

# замена "grep" для бинарных файлов.

# Аналогично команде "grep -a"

E_BADARGS=65

E_NOFILE=66

if [ $# -ne 2 ]

then

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

exit $E_BADARGS

fi

if [ ! -f "$2" ]

then

echo "Файл "$2" не найден."

exit $E_NOFILE

fi

for word in $( strings "$2" | grep "$1" )

# Инструкция "strings" возвращает список строк в двоичных файлах.

# Который затем передается по конвейеру команде "grep", для выполнения поиска.

do

echo $word

done

# Как указывает S.C., вышепрведенное объявление цикла for может быть упрощено

# strings "$2" | grep "$1" | tr -s "$IFS" '[n*]'

# Попробуйте что нибудь подобное: "./bin-grep.sh mem /bin/ls"

exit 0

Еще один пример.

Пример 10-8. Список всех пользователей системы

#!/bin/bash

# userlist.sh

PASSWORD_FILE=/etc/passwd

n=1 # Число пользователей

for name in $(awk 'BEGIN{FS=":"}{print $1}' < "$PASSWORD_FILE" )

# Разделитель полей = : ^^^^^^

# Вывод первого поля ^^^^^^^^

# Данные берутся из файла паролей ^^^^^^^^^^^^^^^^^

do

echo "Пользователь #$n = $name"

let "n += 1"

done

# Пользователь #1 = root

# Пользователь #2 = bin

# Пользователь #3 = daemon

# ...

# Пользователь #30 = bozo

exit 0

И заключительный пример использования подстановки команд при создании [списка].

Пример 10-9. Проверка авторства всех бинарных файлов в текущем каталоге

#!/bin/bash

# findstring.sh:

# Поиск заданной строки в двоичном файле.

directory=/usr/local/bin/

fstring="Free Software Foundation" # Поиск файлов от FSF.

for file in $( find $directory -type f -name '*' | sort )

do

strings -f $file | grep "$fstring" | sed -e "s%$directory%%"

# Команде "sed" передается выражение (ключ -e),

#+ для того, чтобы изменить обычный разделитель "/" строки поиска и строки замены

#+ поскольку "/" - один из отфильтровываемых символов.

# Использование такого символа порождает сообщение об ошибке (попробуйте).

done

exit 0

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

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

# Измените сценарий таким образом, чтобы он брал

#+ $directory и $fstring из командной строки.

Результат работы цикла for может передаваться другим командам по конвейеру.

Пример 10-10. Список символических ссылок в каталоге

#!/bin/bash

# symlinks.sh: Список символических ссылок в каталоге.

directory=${1-`pwd`}

# По-умолчанию в текущем каталоге,

# Блок кода, который выполняет аналогичные действия.

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

# ARGS=1 # Ожидается один аргумент командной строки.

#

# if [ $# -ne "$ARGS" ] # Если каталог поиска не задан...

# then

# directory=`pwd` # текущий каталог

# else

# directory=$1

# fi

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

echo "символические ссылки в каталоге "$directory""

for file in "$( find $directory -type l )" # -type l = символические ссылки

do

echo "$file"

done | sort # В противном случае получится неотсортированный список.

# Как отмечает Dominik 'Aeneas' Schnitzer,

#+ в случае отсутствия кавычек для $( find $directory -type l )

#+ сценарий "подавится" именами файлов, содержащими пробелы.

exit 0

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

Пример 10-11. Список символических ссылок в каталоге, сохраняемый в файле

#!/bin/bash

# symlinks.sh: Список символических ссылок в каталоге.

OUTFILE=symlinks.list # файл со списком

directory=${1-`pwd`}

# По-умолчанию -- текущий каталог,

echo "символические ссылки в каталоге "$directory"" > "$OUTFILE"

echo "---------------------------" >> "$OUTFILE"

for file in "$( find $directory -type l )" # -type l = символические ссылки

do

echo "$file"

done | sort >> "$OUTFILE" # перенаправление вывода

# ^^^^^^^^^^^^^ в файл.

exit 0

Оператор цикла for имеет и альтернативный синтаксис записи -- очень похожий на синтаксис оператора for в языке C. Для этого используются двойные круглые скобки.

Пример 10-12. C-подобный синтаксис оператора цикла for

#!/bin/bash

# Два вапианта оформления цикла.

echo

# Стандартный синтаксис.

for a in 1 2 3 4 5 6 7 8 9 10

do

echo -n "$a "

done

echo; echo

# +==========================================+

# А теперь C-подобный синтаксис.

LIMIT=10

for ((a=1; a <= LIMIT ; a++)) # Двойные круглые скобки и "LIMIT" без "$".

do

echo -n "$a "

done # Конструкция заимствована из 'ksh93'.

echo; echo

# +=========================================================================+

# Попробуем и C-шный оператор "запятая".

for ((a=1, b=1; a <= LIMIT ; a++, b++)) # Запятая разделяет две операции, которые выполняются совместно.

do

echo -n "$a-$b "

done

echo; echo

exit 0

См. так же Пример 25-10, Пример 25-11 и Пример A-7.

---

А сейчас пример сценария, который может найти "реальное" применение.

Пример 10-13. Работа с командой efax в пакетном режиме

#!/bin/bash

EXPECTED_ARGS=2

E_BADARGS=65

if [ $# -ne $EXPECTED_ARGS ]

# Проверка наличия аргументов командной строки.

then

echo "Порядок использования: `basename $0` phone# text-file"

exit $E_BADARGS

fi

if [ ! -f "$2" ]

then

echo "Файл $2 не является текстовым файлом"

exit $E_BADARGS

fi

fax make $2 # Создать fax-файлы из текстовых файлов.

for file in $(ls $2.0*) # Все файлы, получившиеся в результате преобразования.

# Используется шаблонный символ в списке.

do

fil="$fil $file"

done

efax -d /dev/ttyS3 -o1 -t "T$1" $fil # отправить.

# Как указывает S.C., в цикл for может быть вставлена сама команда отправки в виде:

# efax -d /dev/ttyS3 -o1 -t "T$1" $2.0*

# но это не так поучительно [;-)].

exit 0

while

Оператор while проверяет условие перед началом каждой итерации и если условие истинно (если код возврата равен 0), то управление передается в тело цикла. В отличие от циклов for, циклы while используются в тех случаях, когда количество итераций заранее не известно.

while [condition] do command... done

Как и в случае с циклами for/in, при размещении ключевого слова do в одной строке с объявлением цикла, необходимо вставлять символ ";" перед do.

1 ... 21 22 23 24 25 26 27 28 29 ... 96
Перейти на страницу:
Тут вы можете бесплатно читать книгу Искусство программирования на языке сценариев командной оболочки - Мендель Купер.
Комментарии