Главная страница
Навигация по странице:

  • Команда test или [

  • Управляющие структуры

  • Оператор разветвления if

  • Конструкция elif

  • Результат, возвращаемый обоими этими списками

  • Операторные блоки

  • Оператор цикла for

  • ЛАБОРАТОРНЫЕ РАБОТЫ ОС (Для допуска необходимо сделать 1 или 6 л. Практикум по дисциплине Операционные системы (ОС). Цели лабораторных занятий это формирование у будущих бакалавров направлений подготовки 09. 03. 01


    Скачать 2.71 Mb.
    НазваниеПрактикум по дисциплине Операционные системы (ОС). Цели лабораторных занятий это формирование у будущих бакалавров направлений подготовки 09. 03. 01
    Дата15.10.2022
    Размер2.71 Mb.
    Формат файлаpdf
    Имя файлаЛАБОРАТОРНЫЕ РАБОТЫ ОС (Для допуска необходимо сделать 1 или 6 л.pdf
    ТипПрактикум
    #735270
    страница20 из 21
    1   ...   13   14   15   16   17   18   19   20   21
    Условия
    Основа всех языков программирования — средства проверки условий и выполнение различных действий с учетом результатов этой проверки. Рассмотрим условные конструкции, которые можно применять в сценариях командной оболочки, а затем познакомимся с использующими их управляющими структурами.
    Сценарий командной оболочки может проверить код завершения любой команды, вызванной из командной строки, включая сценарии, написанные пользователями.
    Команда test или [
    На практике в большинстве сценариев широко используется команда
    [ или test -логическая проверка командной оболочки. В некоторых системах команды [ и test - синонимы, за исключением того, что при использовании команды [ для удобочитаемости применяется и завершающая часть ]. В программном коде команда [ упрощает синтаксис и делает его более похожим на другие языки программирования.
    Поскольку команда test не часто применяется за пределами сценариев командной оболочки, многие пользователи ОС Linux, никогда раньше не писавшие сценариев пытаются создавать простые программы и называют их test. Если такая программа не работает, вероятно, она конфликтует с командой оболочки test.
    Представим команду test на примере одного простейшего условия: проверки наличия файла. Для нее понадобится следующая команда: test -f
    <имя_файла>, поэтому в сценарии можно написать if test -f fred.c then fi
    To же самое можно записать следующим образом: if [ -f fred.c ] then fi
    Код завершения команды test (выполнено ли условие) определяет, будет ли выполняться условный программный код.
    Необходимо вставлять пробелы между квадратной скобкой [ и про- веряемым условием. Это легко усвоить, если запомнить, что вставить символ [ — это все равно, что написать test, а после имени команды всегда нужно вставлять пробел.
    Если слово then записано в той же строке, что и if, нужно добавить точку с запятой для отделения команды test от then: if [ -f fred.c ]; then fi
    Варианты условий, которые используются в команде test, делятся на три типа:
     строковые сравнения,
     числовые сравнения,

    193
     проверка файловых флагов.
    Эти условия описаны в (табл. 2).
    Таблица 2.
    Условия
    Варианты условий
    Результат
    Сравнения строк
    Строка1 = Строка 2
    True (истина), если строки одинаковы
    Строка1 != Строка2
    True (истина), если строки разные
    -n Строка
    True (истина), если Строка не null
    -z Строка
    True (истина), если Строка null (пустая строка)
    Сравнения чисел
    Выр1 -eq Выр2
    True (истина), если выражения равны
    Выр1 -nе Выр2
    True (истина), если выражения не равны
    Выр1 -gt Выр2
    True (истина), если Выр1 больше, чем Выр2
    Выр1 -gе Выр2
    True (истина), если Выр1 не меньше Выр2
    Выр1 -lt Выр2
    True (истина), если Выр1 меньше, чем Выр2
    Выр1 -le Выр2
    True (истина), если Выр1 не больше Выр2
    !Выражение
    True (истина), если Выражение ложно, и наоборот
    Файловые флаги
    -d файл
    True (истина), если файл— каталог
    -е файл
    True (истина), если файл существует.
    -f файл
    True (истина), если файл— обычный файл
    -r файл
    True (истина), если файл доступен для чтения
    -s файл
    True (истина), если файл ненулевого размера
    -w файл
    True (истина), если файл доступен для записи
    -х файл
    True (истина), если файл— исполняемый файл
    Пример 2: тестирования состояния файла /bin/bash.
    #!/bin/sh if [ -f /bin/bash ] then echo "file /bin/bash exists" fi if [ -d /bin/bash ] then echo "/bin/bash is a directory" else echo "/bin/bash is NOT a directory" fi
    Для того чтобы тест мог оказаться истинным, предварительно, для

    194 проверки всех файловых флагов требуется наличие файла. Данный перечень включает только самые широко используемые опции команды test, полный список можно найти в интерактивном справочном руководстве.
    Управляющие структуры
    В командной оболочке есть ряд управляющих структур или конструкций, похожих на аналогичные структуры в других языках программирования.
    В следующих разделах элемент синтаксической записи операторы— это последовательности команд, которые выполняются, когда или пока условие удовлетворяется или пока оно не удовлетворяется.
    Оператор разветвления if
    Оператор if очень прост: он проверяет результат выполнения команды и затем в зависимости от условия выполняет ту или иную группу операторов. if условие then операторы else операторы fi
    Наиболее часто оператор if применяется, когда задается вопрос, и решение принимается в зависимости от ответа.
    Пример 3:
    #!/bin/sh echo "Сейчас утро? Ответьте yes или no" read timeofday if [ $timeofday = "yes" ]; then echo "Доброе утро" else echo "Добрый вечер" fi exit 0
    В результате будет получен следующий вывод на экран:
    Сейчас утро? Ответьте yes или no yes yes
    Доброе утро
    $
    В этом сценарии для проверки содержимого переменной timeofday применяется команда [. Результат оценивается оператором if, который затем разрешает выполнять разные строки программного кода.
    Дополнительные пробелы, используемые для формирования отступа

    195 внутри оператора if нужны только для удобства читателя; командная оболочка их игнорирует.
    Конструкция elif
    К сожалению, с этим простым сценарием связано несколько проблем. Во-первых, он принимает в значении nо (нет) любой ответ за исключением yes
    (да).
    Можно усовершенствовать сценарий, воспользовавшись конструкцией elif, которая позволяет добавить второе условие, проверяемое при выполнении части else оператора if (пример 4).
    Можно откорректировать предыдущий сценарий так, чтобы он выводил сообщение об ошибке, если пользователь вводит что-либо отличное от yes или nо. Для этого следует заменить ветку else веткой elif и добавить еще одно условие:
    Пример 4:
    #!/bin/sh echo "Сейчас утро? Ответьте yes или no" read timeofday if [ $timeofday = "yes" ] then echo "Доброе утро" elif [ $timeofday = "no" ]; then echo "Добрый вечер " else echo "Извините, $timeofday не распознается. Ответьте yes или no " exit 1 fi exit 0
    Пример 4 очень похож на предыдущий, но теперь, если первое условие не равно true, оператор командной оболочки elif проверяет переменную снова. Если обе проверки не удачны, выводится сообщение об ошибке, и сценарий завершается со значением 1, которое в вызывающей программе можно использовать для проверки успешного выполнения сценария.
    Проблема, связанная со значением переменной
    Данный сценарий исправляет наиболее очевидный дефект, а более тонкая проблема остается незамеченной. Запустите новый вариант сценария, но вместо ответа на вопрос просто нажмите клавишу .
    Вы получите сообщение об ошибке:
    [: = : unary operator expected
    Что же не так? Проблема в первой ветви оператора if. Когда проверялась переменная timeofday, она состояла из пустой строки.
    Следовательно, ветвь оператора if выглядела следующим образом: if [ =
    "yes" ] и не представляла собой верное условие. Во избежание этого

    196 следует заключить имя переменной в кавычки: if [ "$timeofday" = "yes" ]
    Теперь проверка с пустой переменной будет корректной: if [ "" = "yes" ]
    Новый сценарий будет таким:
    Пример 5:
    #!/bin/sh echo " Сейчас утро? Ответьте yes или no " read timeofday if [ "$timeofday " = "yes" ] then echo "Доброе утро" elif [ "$timeofday" = "no" ]; then echo "Добрый вечер " else echo "Извините, $timeofday не распознается. Ответьте yes или no " exit 1 fi exit 0
    Этот вариант безопасен, даже если пользователь в ответ на вопрос просто нажмет клавишу .
    Примечание. Если вы хотите, чтобы команда echo не переходила на новую строку, наиболее переносимый вариант— применить команду printf
    (см. раздел "printf" далее) вместо команды echo. В оболочке bash для запрета перехода на новую строку допускается команда echo –n. Поэтому можно написать: echo -n " Сейчас утро? Ответьте yes или no: "
    Нужно оставлять дополнительный пробел перед закрывающими кавычками для формирования зазора перед вводимым пользователем ответом.
    Проверка выполнения нескольких условий (выполнение нескольких команд):
    Иногда необходимо выполнить оператор, только если удовлетворяется несколько условий, например if [ -f this_file ]; then if [ -f that_file ]; then if [ -f other_file ]; then echo "All files present" fi fi fi
    В другом случае может потребоваться, чтобы хотя бы одно условие из последовательности условий было истинным. if [ -f this_file ]; then

    197 foo="True" elif [ -f that_file ]; then foo="True" elif [ -f the_other_file ]; then foo="True" else foo="False" fi if [ "$foo" = "True" ]; then echo "One of the files exists" fi
    Несмотря на то, что это можно реализовать с помощью нескольких операторов if, результаты получаются очень громоздкими. В командной оболочке есть пара специальных конструкций для работы со списками условий: И-список (AND list) и ИЛИ-список (OR list). Обе они часто применяются вместе, но мы рассмотрим синтаксическую запись каждой из них отдельно.
    И-список
    Эта конструкция позволяет выполнять последовательность команд, причем каждая последующая выполняется только при успешном завершении предыдущей. Синтаксическая запись такова: оператор1 &&
    оператор2 && оператор3 && ...
    Выполнение операторов начинается с самого левого, если он возвращает значение true (истина), выполняется оператор, расположенный справа от первого оператора. Выполнение продолжается до тех пор, пока очередной оператор не вернет значение false (ложь), после чего никакие операторы списка не выполняются. Операция && проверяет условие предшествующей команды.
    Каждый оператор выполняется независимо, позволяя соединять в одном списке множество разных команд, как показано в приведенном далее сценарии. И-список успешно обрабатывается, если все команды выполнены успешно, в противном случае его обработка заканчивается неудачно.
    Пример 6: И-список
    В следующем сценарии выполняется обращение к файлу file_one
    (для проверки его наличия, и если файл не существует, он создается) и затем удаляется файл file_two. Далее И-список проверяет наличие каждого файла и между делом выводит на экран кое-какой текст.
    #!/bin/sh touch file_оnе rm -f file_two if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo "there" then

    198 echo "in if" else echo "in else" fi exit 0
    Результат выполнения сценария hello in else
    В примере 6 команды touch и rm гарантируют, что файл file_оnе в текущем каталоге существует, а файл file_two отсутствует. И-список выполняет команду [ -f file_one ], которая возвращает значение true, потому что файл cуществует. Поскольку предыдущий оператор завершился успешно, теперь выполняется команда echo. Она тоже завершается успешно (echo всегда возвращает true). Затем выполняется третья проверка [ -f fiie_two ]. Она возвращает значение false, т. к. файл не существует. Поскольку последняя команда вернула false, заключительная команда echo не выполняется. В результате И-список возвращает значение false, поэтому в операторе if выполняется вариант else.
    ИЛИ-список
    Эта конструкция позволяет выполнять последовательность команд до тех пор, пока одна из них не вернет значение true, и далее не выполняется ничего более. У нее следующая синтаксическая запись: оператор1 || оператор2 || оператор3 || ...
    Операторы выполняются слева направо. Если очередной оператор возвращает значение false, выполняется следующий за ним оператор. Это продолжается до тех пор, пока очередной оператор не вернет значение true, после этого никакие операторы уже не выполняются.
    ИЛИ-список очень похож на И-список, за исключением того, что правило для выполнения следующего оператора - выполнение предыдущего оператора со значением false.
    Пример 7:
    #!/bin/sh rm –f file_one if [ -f file_one ] || echo "hello" || echo "there" then echo "in if" else echo "in else" fi exit 0
    В результате выполнения данного сценария будет получен следующий вывод:

    199 hello in if
    В первых двух строках просто задаются файлы для остальной части сценария. Первая команда списка [ -f file one ] возвращает значение false, потому что файла в каталоге нет. Далее выполняется команда echo, она возвращает значение true, и больше в ИЛИ-списке не выполняются никакие команды. Оператор if получает из списка значение true, поскольку одна из команд ИЛИ-списка (команда echo) вернула это значение.
    Результат, возвращаемый обоими этими списками, — это результат последней выполненной команды списка.
    Описанные конструкции списков выполняются так же, как аналогичные конструкции в языке С, когда проверяются множественные условия. Для определения результата выполняется минимальное количество операторов. Операторы, не влияющие на конечный результат, не выполняются. Обычно этот подход называют оптимизацией вычислений (short circuit evaluation).
    Попробуйте проанализировать следующий список:
    [ -f file_one ] && команда в случае true || команда в случае false
    В нем будет выполняться первая команда в случае истинности проверки и вторая команда в противном случае. Всегда лучше всего поэкспериментировать с этими довольно необычными списками, и, как правило, придется использовать скобки для изменения порядка вычислений.
    Операторные блоки
    Если необходимо использовать несколько операторов в том месте программного кода, где разрешен только один, например в ИЛИ-списке или И-списке, то можете сделать это, заключив операторы в фигурные скобки {} и создав тем самым операторный блок. Например: get_confirm && { grep -v "$cdcatnum" $tracks_file > $temp_file cat $temp_file > $tracks_file echo add_record_tracks
    }
    Оператор выбора case
    Оператор case немного сложнее уже рассмотренных ранее операторов. Формат записи оператора следующий: саsе переменная in образец [ | образец] ...) операторы;; образец [ | образец] ...) операторы;;

    200 esас
    Конструкция оператора case позволяет сопоставлять содержимое переменной с образцами и затем выполнять разные операторы в зависимости от того, с каким образцом найдено соответствие. Это гораздо проще, чем проверять несколько условий, применяемых во множественных операторах if, elif и else.
    Каждая ветвь с образцами завершается удвоенным символом точка с запятой (;;). В каждой ветви оператора case можно поместить несколько операторов, поэтому сдвоенная точка с запятой необходима для отметки завершения очередного оператора и начала следующей ветви с новым образцом в операторе case.
    Оператор цикла for
    Цикл for предназначен для обработки в цикле ряда значений, которые могут представлять собой любое множество строк. Строки могут быть просто перечислены в программе или, что бывает чаще, представлять собой результат выполненной командной оболочкой подстановки имен файлов. Синтаксис оператора цикла: for переменная in значения do операторы done
    Пример 8:
    #!/bin/sh for foo in bar dog 413 do echo $foo done exit 0
    В результате будет получен следующий вывод: bar dog
    413
    Что произойдет, если изменить первую строку с for foo in bar dog 413 на for foo in "bar dog 413"? Напоминаем, что вставка кавычек заставляет командную оболочку считать все, что находится между ними, единой строкой. Это один из способов сохранения пробелов в переменной.
    Как работает цикл
    В данном примере создается переменная foo и ей в каждом проходе цикла for присваиваются разные значения. Поскольку оболочка считает по умолчанию все переменные строковыми, применять строку 413 так же допустимо, как и строку dog.

    201
    Пример 9:Применение цикла for с метасимволами
    Цикл for обычно используется в командной оболочке вместе с метасимволами или знаками подстановки для имен файлов. Это означает применение метасимвола для строковых значений и предоставление оболочке возможности подставлять все значения на этапе выполнения.
    Этот прием использован в первом примере first. В сценарии применялись средства подстановки командной оболочки — символ * для подстановки имен всех файлов из текущего каталога. Каждое из этих имен по очереди используется в качестве значения переменной $file внутри цикла for.
    Рассмотрим еще один пример подстановки с помощью метасимвола.
    Допустим, нужно вывести на экран все имена файлов сценариев в текущем каталоге, начинающиеся с буквы "f" , и имена всех сценариев заканчиваются символами .sh. Это можно сделать следующим образом:
    #!/bin/sh for file in $(ls f*.sh); do echo $file done echo $file exit 0
    В примере показано применение синтаксической конструкции
    $(команда). Обычно список параметров для цикла for задается выводом команды, включенной в конструкцию $(). Командная оболочка раскрывает f*.sh, подставляя имена всех файлов, соответствующих данному шаблону.
    Все подстановки переменных в сценариях командной оболочки делаются во время выполнения сценария, а не в процессе их написания, поэтому все синтаксические ошибки в объявлениях переменных обнаруживаются только на этапе выполнения, как было показано ранее, когда мы заключали в кавычки пустые переменные.
    Цикл while
    Поскольку по умолчанию командная оболочка считает все значения строками, оператор for хорош для циклической обработки наборов строк, но не слишком удобен, если не известно заранее, сколько раз придется его выполнить.
    Если нужно повторить выполнение последовательности команд, но заранее не известно, сколько раз следует их выполнить, применяется цикл while со следующей синтаксической записью: while условие do операторы done
    Пример 10: Программа проверки паролей.
    #!/bin/sh

    202 echo "Enter password" read trythis while [ "$trythis" ! = "secret" ]; do echo "Sorry, try again" read trythis done exit 0
    Следующие строки - пример вывода данного сценария:
    Enter password password
    Sorry, try again secret
    $
    Это небезопасный способ выяснения пароля, но он вполне подходит для демонстрации применения цикла while. Операторы, находящиеся между операторами do и done, выполняются бесконечное число раз до тех пор, пока условие остается истинным (true). В данном случае проверяетcя, равно ли значение переменной trythis строке secret. Цикл будет выполняться, пока $trythis не равно secret. Затем выполнение сценария продолжится с оператора, следующего сразу за оператором done.
    1   ...   13   14   15   16   17   18   19   20   21


    написать администратору сайта