Выбрать главу

# Западня в подоболочке.

outer_variable=внешняя_переменная

echo

echo "outer_variable = $outer_variable"

echo

(

# Запуск в подоболочке

echo "внутри подоболочки outer_variable = $outer_variable"

inner_variable=внутренняя_переменная # Инициализировать

echo "внутри подоболочки inner_variable = $inner_variable"

outer_variable=внутренняя_переменная # Как думаете? Изменит внешнюю переменную?

echo "внутри подоболочки outer_variable = $outer_variable"

# Выход из подоболочки

)

echo

echo "за пределами подоболочки inner_variable = $inner_variable" # Ничего не выводится.

echo "за пределами подоболочки outer_variable = $outer_variable" # внешняя_переменная.

echo

exit 0

Передача вывода от echo по конвейеру команде read может давать неожиданные результаты. В этом сценарии, команда read действует так, как будто бы она была запущена в подоболочке. Вместо нее лучше использовать команду set (см. Пример 11-14).

Пример 31-2. Передача вывода от команды echo команде read, по конвейеру

#!/bin/bash

# badread.sh:

# Попытка использования 'echo' и 'read'

#+ для записи значений в переменные.

a=aaa

b=bbb

c=ccc

echo "один два три" | read a b c

# Попытка записать значения в переменные a, b и c.

echo

echo "a = $a" # a = aaa

echo "b = $b" # b = bbb

echo "c = $c" # c = ccc

# Присваивания не произошло.

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

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

var=`echo "один два три"`

set -- $var

a=$1; b=$2; c=$3

echo "-------"

echo "a = $a" # a = один

echo "b = $b" # b = два

echo "c = $c" # c = три

# На этот раз все в порядке.

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

# Обратите внимание: в подоболочке 'read', для первого варианта, переменные присваиваются нормально.

# Но только в подоболочке.

a=aaa # Все сначала.

b=bbb

c=ccc

echo; echo

echo "один два три" | ( read a b c;

echo "Внутри подоболочки: "; echo "a = $a"; echo "b = $b"; echo "c = $c" )

# a = один

# b = два

# c = три

echo "-------"

echo "Снаружи: "

echo "a = $a" # a = aaa

echo "b = $b" # b = bbb

echo "c = $c" # c = ccc

echo

exit 0

Огромный риск, для безопасности системы, представляет использование в скриптах команд, с установленным битом "suid"[ 61 ].

Использование сценариев в качестве CGI-приложений может приводить к серьезным проблемам из-за отсутствия контроля типов переменных. Более того, они легко могут быть заменены взломщиком на его собственные сценарии.

Bash не совсем корректно обрабатывает строки, содержащие двойной слэш (//).

Сценарии на языке Bash, созданные для Linux или BSD систем, могут потребовать доработки, перед тем как они смогут быть запущены в коммерческой версии UNIX. Такие сценарии, как правило, используют GNU-версии команд и утилит, которые имеют лучшую функциональность, нежели их аналоги в UNIX. Это особенно справедливо для таких утилит обработки текста, как tr.

Danger is near thee --

Beware, beware, beware, beware.

Many brave hearts are asleep in the deep.

So beware --

Beware.

A.J. Lamb and H.W. Petrie

Глава 32. Стиль программирования

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

Ниже приводится несколько рекомендаций по оформлению сценариев, однако их не следует рассматривать как Официальное Руководство.

32.1. Неофициальные рекомендации по оформлению сценариев

 Комментируйте свой код. Это сделает ваши сценарии понятнее для других, и более простыми, в обслуживании, для вас.

 PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"

 # Эта строка имела некоторый смысл в момент написания,

 # но через год-другой будет очень тяжело вспомнить -- что она делает.

 # (Из сценария "pw.sh", автор: Antek Sawicki)

Добавляйте заголовочные комментарии в начале сценария и перед функциями.

#!/bin/bash

#************************************************#

# xyz.sh #

# автор: Bozo Bozeman #

# Июль 05, 2001 #

# #

# Удаление файлов проекта. #

#************************************************#

BADDIR=65 # Нет такого каталога.

projectdir=/home/bozo/projects # Каталог проекта.

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

# cleanup_pfiles () #

# Удаляет все файлы в заданном каталоге. #

# Параметры: $target_directory #

# Возвращаемое значение: 0 -- в случае успеха, #

вернуться

61

Установка этого бита на файлы сценариев не имеет никакого эффекта.