Мелешко Е.А., Лозицкая Л.Г., Пидопрыгора Г.А

Национальный Авиационный университет

Ошибки Unix Shell

Командный язык shell (в переводе - раковина, скорлупа) фактически есть язык программирования очень высокого уровня. Shell как язык команд и язык программирования, который обеспечивает интерфейс для операционной системы UNIX. Его функции включают управление потоком примитивов, передачи параметров, переменных и подстановки строк. Имеются конструкции, такие как while, if then else, case и for. Возможна двусторонняя связь между shell и командами. Значения параметров String, как правило, имена файлов или флаги, может быть переданы команде. Код возврата определяет команды, которые могут быть использованы для определения управления потоком, а стандартный вывод команды может быть использован в качестве оболочки входа.Shell может изменить среду, в которой команды выполняются. Вход и выход могут быть перенаправлены на файлы и процессы, которые общаются через "трубы". Команды находятся в поиске каталогов файловой системы в последовательности, которые могут быть определены пользователем. Команды могут быть прочитаны как с терминала так и из файла, что позволяет команде процедур храниться для последующего использования. На этом языке пользователь осуществляет управление компьютером. Обычно, после входа в систему начинаем взаимодействовать с командной оболочкой. Признаком того, что оболочка (shell) готова к приему команд служит выдаваемый ею на экран промптер. В простейшем случае это один доллар ("$").

Shell не является необходимым и единственным командным языком (хотя именно он стандартизован в рамках POSIX [POSIX 1003.2] - стандарта мобильных систем). Например, немалой популярностью пользуется язык cshell, есть также kshell, bashell и другие. Более того, каждый пользователь может создать свой командный язык. Может одновременно на одном экземпляре операционной системы работать с разными командными языками.

Shell - это одна из многих команд UNIX. То есть в набор команд оболочки (интерпретатора) "shell" входит команда "sh" - вызов интерпретатора "shell". Первый "shell" вызывается автоматически при вашем входе в систему и выдает на экран промтер. После этого вы можете вызывать на выполнение любые команды, в том числе и снова сам "shell", который вам создаст новую оболочку внутри прежней.

Рассматривая уязвимости языка, нужно отметить, что обработка ошибок обнаруженных Shell зависит не только от типа ошибки, но и от того, является ли Shell используваемым в интерактивном режиме или нет. В интерактивном Shell ввод и вывод связан с терминалом (Shell вызывающийся флагом является также интерактивным).

Исполнение команды может выдать ошибку по любой из следующих причин:

-         Ввод - перенаправление вывода может потерпеть неудачу. Например, если файл не существует или не может быть создан.

-         Команда сама по себе не существует или не может быть выполнена.

-         Команда завершается аварийно, например, с " bus error “ или " memory fault"

-         Команда завершается нормально, но возвращает ненулевой статус выхода.

Во всех этих случаях оболочка будет переходить к выполнению следующей команды. За исключением последнего случая сообщение об ошибке будет напечатано Shell-ом. Все остальные ошибки вызываются Shell для выхода из команды процедуры.Интерактивный Shell вернется читать другую команду из терминала.

Такие ошибки включают следующее:

- Синтаксические ошибки. Например  if ... then ... done

- сигналы, такие как прерывание. Shell ждет текущей команды, если таковые имеются, для завершения выполнения, а затем либо выходит или возвращается на терминал.

- Невыполнение любой из встроенных команд, таких как cd

Shell флаг-E заставляет Shell прекратить если какая-то из этих ошибок обнаружена:

1) hangup(зависание),

2) interrupt(прерывание),

3) quit*(выход)

4) illegal instruction*(незаконная инструкция)

5) trace trap*(следом в ловушку)

6) IOT instruction*(IOT инструкция)

7) EMT instruction*(EMT инструкция),

8) floating point exception*(исключение плавающей точки),

9) kill (cannot be caught or ignored) ("убить"(если невозможно поймать либо игнорировать),

10) bus error *(ошибка шины),

11) segmentation violation*(нарушение сегмента)

12) bad argument to system call *(плохой аргумент для системного вызова)

13) write on a pipe with no one to read it(написать на трубе, на которой некому прочитать)

14) alarm clock(будильник)

15) software termination (прекращение программного обеспечения ).

Те сигналы, которые отмечены звездочкой приводят к свалке памяти, если не были пойманы. Тем не менее, сам shell игнорирует выход который является единственным внешним сигналом, который может привести к свалке. 1, 2, 3, 14 и 15сигналы в этом списке  представляют потенциальный интерес для shell программ. Shell процедуры обычно прекращаются, когда прерывание получено    от терминала. Команды ловушки используются, если требуются некоторые чистки такие как удаление временных файлов. Например,

trap 'rm /tmp/ps$$; exit' 2    устанавливает команду ловушку для сигнала 2 (терминал прерывания), и если этот сигнал получен будет выполнять команды

            rm /tmp/ps$$; exit

Выход - является другой встроенной командой, которая завершает выполнение shell процедуры. Выход требуется, в противном случае, после принятия ловушки, shell возобновит выполнение процедуры на месте, где она была прервана.

UNIX сигналы могут быть обработаны одним из трех способов. Они могут быть проигнорированы, и в этом случае сигнал никогда не отправится в этот процесс. Они могут быть пойманы, и в этом случае процесс должен решить, какие действия необходимо предпринять при получении сигнала. Наконец, они могут быть оставлены до прекращения процесса без необходимости принимать какие-либо дальнейшие действия. Если сигнал игнорируется при входе в shell процедуры, например, путем вызова его в фоновом режиме , то ловушка команд (и сигнал) игнорируются.

Использование ловушки иллюстрируется модифицированной версией Touch команды. Очищающее действие заключается в удалении нежелательных файлов junk$$.

Команда ловушка:

            flag=

            trap 'rm -f junk$$; exit' 1 2 3 15

            for i

            do case $i in

               -c)  flag=N ;;

               *)   if test -f $i

                        then    ln $i junk$$; rm junk$$

                        elif test $flag

                        then    echo file \'$i\' does not exist

                        else    >$i

                        fi

               esac

            done

Команда ловушка (trap) предстает перед созданием временного файла, в противном случае было бы возможно для процесса умереть без удаления файла.

Так как нет сигнала 0 в UNIX это используется shell-ом для обозначения команд, выполняемых на выходе из корпуса процедуры.

Процедура может, сама избирать игнорирование сигналов, указав пустую строку в качестве аргумента ловушки. Следующий фрагмент взят из NOHUP команды    trap '' 1 2 3 15   которые вызывают зависание, прерывание, выход и уничтожение, для игнорирования как процессом так и вызовом команды.

Ловушки могут быть сброшены             trap 2 3     которые сбрасывают ловушки для сигналов 2 и 3 к их значениям по умолчанию список текущих значений ловушек может быть получено в письменной форме trap Процедура сканирования (scan) является примером использования ловушки, в которой нет выхода в команду. Сканирование берет каждый каталог в текущем каталоге, подсказки со своим наименованием, а затем выполняет команды набранные в терминале пока конец файла или прерывание не будут получены. Прерывания игнорируются во время выполнения запрашиваемых команд, но вызывают прекращения когда сканирование ожидает ввода. Процедура сканирования:

            d=`pwd`

            for i in *

            do if test -d $d/$i

               then cd $d/$i

                        while echo "$i:"

                              trap exit 2

                              read x

                        do trap : 2; eval $x; done

               fi

            done

 read x (читать х)- является встроенной командой, которая читает одну строку из стандартного ввода и помещает результат в переменную x. Она возвращает ненулевой статус выхода, если считан конец файла или получено прерывание.