Что такое shell процедура
Перейти к содержимому

Что такое shell процедура

  • автор:

Unix shell: абсолютно первые шаги

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

Здесь не будет пересказа манов (документации), и статья никак не отменяет и не заменяет их чтение. Вместо этого я расскажу о главных вещах (командах, приемах и принципах), которые надо осознать с самого начала работы в unix shell-е, чтобы работа происходила эффективно и приятно.

Статья касается полноценных unix-подобных окружений, с полнофункциональным шеллом (предпочтительно zsh или bash)и достаточно широким набором стандартных программ.

Что такое шелл

Shell (шелл, он же «командная строка», он же CLI, он же «консоль», он же «терминал», он же «черное окошко с белыми буковками») — это текстовый интерфейс общения с операционной системой (ну, строго говря, это программа, которая таковой интерфейс обеспечивает, но сейчас это различие несущественно).

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

типичный вид шелла

Типичный вид шелла:

Шелл — это основной способ для взаимодействия со всеми Unix-подобными серверными системами.

Где встречаются системы с командной строкой?

  • MacOS (bash);
  • удаленный доступ на сервер по работе или для личного веб-проекта;
  • домашний файл-сервер с удаленным доступом;
  • Ubuntu, PC-BSD на ноутбуке/десктопе — unix-подобные системы сегодня просты в установке и использовании.

Какие задачи разумно решать шеллом?

  • интерактивная работа в терминале:
    • выполнение компиляции, запуск заданий через make;
    • сравнение текстовых файлов;
    • быстрый ad-hoc анализ данных (количество уникальных ip в логе, распределение записей по часам/минутам и т.п.);
    • разовые массовые действия (прибить много процессов; если работаете с системой контроля версий — ревертнуть или зарезолвить кучу файлов);
    • диагностика происходящего в системе (семафоры, локи, процессы, дескрипторы, место на диске и т.п.);
    • установочные скрипты, для выполнения которых нельзя рассчитывать на наличие других интерпретаторов — это не для новичков;
    • функции для кастомизации интерактивного шелла (влияющие на приглашение, меняющие каталог, устанавливающие переменные окружения) — тоже не совсем для новичков;
    • одноразовые скрипты типа массового перекодирования файлов;
    • makefile-ы.

    Абсолютно первые шаги

    Начинаем работу: войти и выйти

    Убедитесь, что точно знаете, как запустить шелл и как из него выйти.

    Если вы работаете за машиной, на которой установлена Ubuntu, вам надо запустить программу Terminal. По окончании работы можно просто закрыть окно.

    На MacOS — тоже запустить Terminal.

    Для доступа к удаленному серверу — воспользоваться ssh (если локально у вас MacOS, Ubuntu или другая unix-like система) или putty (если у вас Windows).

    Кто я, где я?

    • hostname — выводит имя машины (сервера), на которой вы сейчас находитесь;
    • whoami — выводит ваш логин (ваше имя в системе);
    • tree -d / |less — псевдографическое изображение дерева каталогов на машине; выход из пролистывания — q ;
    • pwd — выводит каталог, в котором вы сейчас находитесь; в командной строке вы не можете быть «просто так», вы обязательно находитесь в каком-то каталоге (=текущий каталог, рабочий каталог). Вероятно, текущий рабочий каталог выводится у вас в приглашении (prompt).
    • ls — список файлов в текущем каталоге; ls /home — список файлов в указанном каталоге;

    История команд (history)

    Важное свойство полноценной командной строки — история команд.

    Выполните несколько команд: hostname , ls , pwd , whoami . Теперь нажмите клавишу «вверх». В строке ввода появилась предыдущая команда. Клавишами «вверх» и «вниз» можно перемещаться вперед и назад по истории. Когда долистаете до hostname , нажмите Enter — команда выполнится еще раз.

    Команды из истории можно не просто выполнять повторно, а еще и редактировать. Долистайте историю до команды ls , добавьте к ней ключ -l (получилось ls -l , перед минусом пробел есть, а после — нет). Нажмите Enter — выполнится модифицированная команда.

    Пролистывание истории, редактирование и повторное выполнение команд — самые типичные действия при работе в командной строке, привыкайте.

    Copy-paste

    Командная строка очень текстоцентрична: команды — это текст, входные данные для большинства стандартных программ — текст, результат работы — чаще всего тоже текст.

    Прекрасной особенностью текста является то, что его можно копировать и вставлять, это верно и для командной строки.

    Попробуйте выполнить команду date +»%y-%m-%d, %A»
    Вводили ли вы ее целиком руками или скопировали из статьи? Убедитесь, что вы можете ее скопировать, вставить в терминал и выполнить.

    После того, как научитесь пользоваться man ‘ом, убедитесь, что можете скопировать и выполнить примеры команд из справки. Для проверки найдите в справке по программе date раздел EXAMPLES , скопируйте и выполните первый приведенный пример (на всякий случай: знак доллара не является частью команды, это условное изображение приглашения к вводу).

    Как именно копировать текст из терминала и вставлять его в терминал — зависит от вашей системы и от ее настроек, поэтому дать универсальную инструкцию, к сожалению, не получится. На Ubuntu попробуйте так: копирование — просто выделение мышью, вставка — средняя кнопка мыши. Если не работает, или если у вас другая система — поищите в Интернете или спросите более опытных знакомых.

    Ключи и опции

    При исследовании истории команд вы уже столкнулись с тем, что у команды ls есть по крайней мере два варианта. Если вызвать ее просто так, она выводит простой список:

    [22:26]akira@latitude-e7240: ~/shell-survival-quide> ls Makefile shell-first-steps.md shell-first-steps.pdf shell-survival-quide.md shell-survival-quide.pdf 

    Если же добавить ключ -l , к каждому файлу выводится подробная информация:

    [22:28]akira@latitude-e7240: ~/shell-survival-quide> ls -l total 332 -rw-rw-r-- 1 akira akira 198 Feb 13 11:48 Makefile -rw-rw-r-- 1 akira akira 15107 Feb 14 22:26 shell-first-steps.md -rw-rw-r-- 1 akira akira 146226 Feb 13 11:49 shell-first-steps.pdf -rw-rw-r-- 1 akira akira 16626 Feb 13 11:45 shell-survival-quide.md -rw-rw-r-- 1 akira akira 146203 Feb 13 11:35 shell-survival-quide.pdf 

    Это очень типичная ситуация: если к вызову команды добавлять специальные модификаторы (ключи, опции, параметры), поведение команды меняется. Сравните: tree / и tree -d / , hostname и hostname -f .

    Кроме того, команды могут принимать в качестве параметров имена файлов, каталогов или просто текстовые строки. Попробуйте:

    ls -ld /home ls -l /home grep root /etc/passwd 

    man

    man — справка по командам и программам, доступным на вашей машине, а также по системным вызовам и стандартной библиотеке C.

    Попробуйте: man grep , man atoi , man chdir , man man .

    Пролистывание вперед и назад делается кнопками «вверх», «вниз», «PageUp», «PageDown», выход из просмотра справки — кнопкой q . Поиск определенного текста в справочной статье: нажимите / (прямой слеш), введите текст для поиска, нажимите Enter. Перемещение к следующим вхождениям — клавиша n .

    • 1 — исполняемые программы и шелльные команды ( wc , ls , pwd и т.п.);
    • 2 — системные вызовы ( fork , dup2 и т.п.)
    • 3 — библиотечные функции ( printf , scanf , cos , exec ).

    Посмотреть список всех доступных на машине справочных статей можно с помощью команды man -k . (точка — тоже часть комады).

    less

    Когда в небольшом окне терминала надо просмотреть очень длинный текст (содержимое какого-то файла, длинный man и т.п.), используют специальные программы-«пейджеры» (от слова page/страница, то есть постраничные листатели). Самый популярный листатель — less , и именно он обеспечивает вам пролистывание, когда вы читаете man-ы.

    Попробуйте и сравните поведение:

    cat /etc/bash.bashrc cat /etc/bash.bashrc |less 

    Можно передать файл в пролистыватель сразу в параметрах:

    less /etc/bash.bashrc 

    Пролистывание вверхи и вниз — кнопки «вверх», «вниз», «PageUp», «PageDown», выход — кнопка q . Поиск определенного текста: нажимите / (прямой слеш), введите текст для поиска, нажимите Enter. Перемещение к следующим вхождениям — клавиша n . (Узнаете инструкцию про man ? Ничего удивительного, для вывода справки тоже используется less .)

    Права

    С любым файлом или каталогом связан набор «прав»: право на чтение файла, право на запись в файл, право исполнять файл. Все пользователи делятся на три категории: владелец файла, группа владельца файла, все прочие пользователи.

    Посмотреть права на файл можно с помощью ls -l . Например:

    > ls -l Makefile -rw-r--r-- 1 akira students 198 Feb 13 11:48 Makefile 

    Этот вывод означает, что владельцу (akira) можно читать и писать файл, группе (students) — только читать, всем прочим пользователя — тоже только читать.

    Если при работе вы получаете сообщение permission denied , это значит, что у вас недостаточно правна объект, с которым вы хотели работать.

    Подробнее читайте в man chmod .

    STDIN, STDOUT, конвейеры (пайпы)

    С каждой исполняющейся программой связаны 3 стандартных потока данных: поток входных данных STDIN , поток выходных данных STDOUT , поток для вывода ошибок STDERR .

    Запустите программу wc , введите текст Good day today , нажмите Enter, введтие текст good day , нажмите Enter, нажмите Ctrl+d. Программа wc покажет статистику по количеству букв, слов и строк в вашем тексте и завершится:

    > wc good day today good day 2 5 24 

    В данном случае вы подали в STDIN программы двухстрочный текст, а в STDOUT получили три числа.

    Теперь запустите команду head -n3 /etc/passwd , должно получиться примерно так:

    > head -n3 /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin 

    В этом случае программа head ничего не читала из STDIN , а в STDOUT написала три строки.

    Можно представить себе так: программа — это труба, в которую втекает STDIN , а вытекает STDOUT .

    Важнейшее свойство юниксовой командной строки состоит в том, что программы-«трубы» можно соединять между собой: выход ( STDOUT ) одной программы передавать в качестве входных данных ( STDIN ) другой программе.

    Такая конструкция из соединенных программ называется по-английски pipe (труба), по-русски — конвейер или пайп.

    Объединение программ в конвейер делается символом | (вертикальная черта)

    Выполните команду head -n3 /etc/passwd |wc , получится примерно следующее:

    > head -n3 /etc/passwd |wc 3 3 117 

    Произошло вот что: программа head выдала в STDOUT три строки текста, которые сразу же попали на вход программе wc , которая в свою очередь подсчитала количество символов, слов и строк в полученном тексте.

    В конвейер можно объединять сколько угодно программ. Например, можно добавить к предыдущему конвейеру еще одну программу wc , которая подсчитает, сколько слов и букв было в выводе первой wc :

    > head -n3 /etc/passwd |wc |wc 1 3 24 

    Составление конвейеров (пайпов) — очень частое дело при работе в командной строке. Пример того, как это делается на практике, читайте в разделе «Составление конвейера-однострочника».

    Перенаправление ввода-вывода

    Вывод ( STDOUT ) програмы можно не только передать другой программе по конвейеру, но и просто записать в файл. Такое перенаправление делается с помощью > (знак «больше»):

    date > /tmp/today.txt 

    В результате выполнения этой команды на диске появится файл /tmp/today.txt . Посмотрите его содержимое с помощью cat /tmp/today.txt

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

    Если надо не перезаписать файл, а добавить вывод в его конец, используйте >> :

    date >> /tmp/today.txt 

    Проверьте, что теперь записано в файле.

    Кроме того, программе можно вместо STDIN передать любой файл. Попробуйте:

    Что делать, когда что-то непонятно

    Если вы сталкиваетесь с поведением системы, которое не понимаете, или хотите добиться определенного результата, но не знаете, как именно, советую действовать в следующем порядке (кстати, это относится не только к шеллам):

    • насколько возможно четко сформулируйте вопрос или задачу — нет ничего сложнее, чем решать «то, не знаю что»;
    • вспомните, сталкивались ли вы уже с такой же или подобной проблемой — в этом случае стоит попробовать решение, которое сработало в прошлый раз;
    • почитайте подходящие man-ы (если понимаете, какие man-ы подходят в вашем случае) — возможно, вы найдете подходящие примеры использования команд, нужные опции или ссылки на другие команды;
    • подумайте: нельзя ли немного поменять задачу? — возможно, чуть-чуть изменив условия, вы получите задачу, которую уже умеете решать;
    • задайте свой четко сформулированный вопрос в поисковой системе — возможно, ответ найдется на Stack Overflow или других сайтах;

    Если вы разобрались со сложной проблемой (самостоятельно, с помощью Интернета или других людей) — запишите свое решение на случай, если такая же проблема снова возникнет у вас или ваших товарищей. Записывать можно в простой текстовый файл, в Evernote, публиковать в соц.сетях.

    Методы работы

    Скопировать-и-вставить — из man-ов, из статей на StackOverflow и т.п.Командная строка состоит из текста, пользуйтесь этим: копируйте и используйте примеры команд,записывайте удачные находки на память, публикуйте их в твиттерах и блогах.

    Читать man. Nuff said.

    Вытащить из истории предыдущую команду, добавить в конвейер еще одну команду, запустить, повторить.См. также раздел «Составление конвейера-однострочника».

    Базовые команды

    • переход в другой каталог: cd ;
    • просмотр содержимого файлов: саt , less , head , tail ;
    • манипуляции с файлами: cp , mv , rm ;
    • просмотр содержимого каталогов: ls , ls -l , ls -lS ;
    • структура каталогов: tree , tree -d (можно передать в качестве параметра каталог);
    • поиск файлов: find . -name . ;

    Аналитика

    • wc , wc -l ;
    • sort -k — сортировка по указанному полю;
    • sort -n — числовая соритровка;
    • diff — сравнение файлов;
    • grep , grep -v , grep -w , grep ‘\’ , grep -E — поиск текста;
    • uniq , uniq -c — уникализация строк;
    • awk — в варианте awk » , чтобы оставить только первое поле из каждой строки, $1 можно менять на $2 , $3 и т.д.;

    Диагностика системы

    • ps axuww — информация о процессах (запущенных программах), работающих на машине;
    • top — интерактивный просмотр самых ресурсоемких процессов;
    • df — занятое и свободное место на диске;
    • du — суммарный размер файлов в каталоге (рекурсивно с подкаталогами);
    • strace , ktrace — какие системные вызовы выполняет процесс;
    • lsof — какие файлы использует процесс;
    • netstat -na , netstat -nap — какие порты и сокеты открыты в системе.

    Некоторых программ у вас может не быть, их надо установить дополнительно. Кроме того, некоторые опции этих программ доступны только привилегированным пользователям ( root ‘у).

    Массовое и полуавтоматическое выполнение

    На первых порах пропускайте этот раздел, эти команды и конструкции понадобятся вам тогда, когда доберетесь до несложного шелльного скриптинга.

    • test — проврека условий;
    • while read — цикл по строчкам STDIN ;
    • xargs — подстановка строк из STDIN в параметры указанной программе;
    • seq — генерация последовательностей натуральных чисел;
    • () — объединить вывод нескольких команд;
    • ; — выполнить одно за другим;
    • && — выполнить при условии успешного завершения первой команды;
    • || — выполнить при условии неудачного завершения первой команды;
    • tee — продублировать вывод программы в STDOUT и в файл на диске.

    Разное

    • date — текущая дата;
    • curl — скачивает документ по указаному url и пишет результат на STDOUT ;
    • touch — обновить дату модификации файла;
    • kill — послать процессу сигнал;
    • true — ничего не делает, возвращает истину, полезна для организации вечных циклов;
    • sudo — выполнить команду от имени root ‘а.

    Составление конвейера-однострочника

    Давайте рассмотрим пример реальной задачи: требуется прибить все процессы task-6-server , запущенные от имени текущего пользователя.

    Шаг 1.
    Понять, какая программа выдает примерно нужные данные, хотя бы и не в чистом виде. Для нашей задачи стоит получить список всех процессов в системе: ps axuww . Запустить.

    Шаг 2.
    Посмотреть на полученные данные глазами, придумать фильтр, который выкинет часть ненужных данных. Часто это grep или grep -v . Клавишей «Вверх» вытащить из истории предыдущую команду, приписать к ней придуманный фильтр, запустить.

    ps axuww |grep `whoami` 

    — только процессы текущего пользователя.

    Шаг 3.
    Повторять пункт 2, пока не получатся чистые нужные данные.

    ps axuww |grep `whoami` | grep '\' 

    — все процессы с нужным именем (плюс, может быть, лишние вроде vim task-6-server.c и т.п.),

    ps axuww |grep `whoami` | grep '\' | grep -v vim ps axuww |grep `whoami` | grep '\' | grep -v vim |grep -v less 

    — только процессы с нужным именем

    ps axuww |grep `whoami` | grep '\' | grep -v vim |grep -v less |awk '' 

    — pid-ы нужных процессов, п. 3 выполнен

    Шаг 4.
    Применить подходящий финальный обработчик. Клавишей «Вверх» вытаскиваем из истории предыдущую команду и добавляем обработку, которая завершит решение задачи:

    • |wc -l чтобы посчитать количество процессов;
    • >pids чтобы записать pid-ы в файл;
    • |xargs kill -9 убить процессы.

    Задания для тренировки

    Хотите попрактиковаться в новых умениях? Попробуйте выполнить следующие задания:

    • получите список всех файлов и каталогов в вашем домашнем каталоге;
    • получите список всех man -статей из категории 2 (системные вызовы);
    • посчитайте, сколько раз в man-е по программе grep встречается слово grep;
    • посчитайте, сколько процессов запущено в данный момент от имени пользователя root ;
    • найдите, какая команда встречается в максимальном количестве категорий справки (man);
    • подсчитайте, сколько раз встречается слово var на странице ya.ru.

    Что изучать дальше?

    Если командная строка начинает вам нравиться, не останавливайтесь, продолжайте совершенствовать свои навыки.

    Вот некоторые программы, которые определенно вам пригодятся, если вы будете жить в командной строке:

    • awk
    • sed
    • find со сложными опциями
    • apropos
    • locate
    • telnet
    • netcat
    • tcpdump
    • rsync
    • screen
    • ssh
    • tar
    • zgrep , zless
    • visudo
    • crontab -e
    • sendmail

    Кому это надо?

    А стоит ли вообще изучать сегодня командную строку и шелльный скриптинг? Определенно стоит. Приведу только несколько примеров из требований Facebook к кандидатам, которые хотят поступить на работу в FB.

    Data Scientist, Economic Research: Comfort with the command line and with Unix core tools; preferred: adeptness with a scripting language such as Python, or previous software engineering experience.

    MySQL Database Engineer: High degree of proficiency in Shell scripting (Bash, Awk, etc); high degree of proficiency in Linux administration.

    Manufacturing Quality Engineer, Server: Scripting skills in Bash, Perl, or Python is desirable.

    Data Platform Engineer: 2 years experience with Unix/Linux systems.

    DevOps Engineer, Data: 2 years experience with Unix/Linux system administration and programming.

    Вопросы?

    Если у вас есть вопросы по этой статье или вообще по работе в юниксовой командной строке, задавайте их в комментариях или по емейлу liruoko (at) yandex (dot) ru .

    Что такое shell процедура

    Shell является не только интерпретатором команд, но и языком программирования на уровне команд. Это означает, что вместо того, чтобы использовать shell только как взаимосвязь между вами и компьютером, вы можете программировать с его помощью для автоматического повторения последовательности инструкций. Чтобы сделать это, нужно создать исполняемый файл, содержащий список этих команд. Эти файлы называются процедурами shell. Создав такую процедуру для определенной задачи, вы можете просто запросить shell прочитать и выполнить содержание процедуры.

    Подобно другими языкам программирования shell обеспечивает такие возможности как переменные, управление структурами, подпрограммы, передача параметров. С помощью этих возможностей вы можете создавать собственный инструментарий.

    Например, вы можете скомбинировать три команды системы UNIX (date, who, wc) в простой процедуре shell и назвать его users. Эта процедура отражает дату, время и количество пользователей, работающих в вашей системе. С помощью редактора vi создайте файл users:

    vi users

    Редактор выведет пустую страницу на вашем экране и будет ждать ввода текста. Введите три команды на одной строке:

    date; who | wc -l

    Затем запишите текст в файл и выйдите из файла, задав команду:

    Сделайте файл users исполняемым:
    chmod ug+x users

    Теперь попытайтесь запустить этот файл. На экране появится информация, подобная:

    $ users Sat Mar 11 16:40:32 EST 1989 4 $

    Команда распечатывает дату и количество пользователей (4).

    4.2.10. Программирование с помощью awk

    awk предлагает вам управлять задачами обработки данных и восстановления информации. В разд. 7 приводится концепция языка и структура программы awk.

    Типичная программа awk состоит из выражения «шаблон-действие». awk-программа находит во вводном файле строку, соответствующую шаблону и выполняет над ней указанное действие. Процесс продолжается до тех пор, пока весь вводной файл не будет прочитан.

    SH, Bourne Shell

    calls the shell to read commands from file. Such a file is called a command procedure or shell procedure. Arguments may be supplied with the call and are referred to in file using the positional parameters $1, $2, . For example, if the file wg contains

    who | grep $1
    sh wg fred

    is equivalent to

    who | grep fred

    UNIX files have three independent attributes, read, write and execute. The UNIX command chmod (1) may be used to make a file executable. For example,

    chmod +x wg

    will ensure that the file wg has execute status. Following this, the command

    wg fred

    is equivalent to

    sh wg fred

    This allows shell procedures and programs to be used interchangeably. In either case a new process is created to run the command.

    As well as providing names for the positional parameters, the number of positional parameters in the call is available as $#. The name of the file being executed is available as $0.

    A special shell parameter $* is used to substitute for all positional parameters except $0. A typical use of this is to provide some default arguments, as in,

    nroff -T450 -ms $*

    which simply prepends some arguments to those already given.

    Control flow — for

    A frequent use of shell procedures is to loop through the arguments ($1, $2, . ) executing commands once for each argument. An example of such a procedure is tel that searches the file /usr/lib/telnos that contains lines of the form

    . fred mh0123 bert mh0789 . 

    The text of tel is

    for i do grep $i /usr/lib/telnos; done

    The command

    tel fred

    prints those lines in /usr/lib/telnos that contain the string fred.

    tel fred bert

    prints those lines containing fred followed by those for bert.

    The for loop notation is recognized by the shell and has the general form

    for name in w1 w2 . do command-list done 

    A command-list is a sequence of one or more simple commands separated or terminated by a newline or semicolon. Furthermore, reserved words like do and done are only recognized following a newline or semicolon. name is a shell variable that is set to the words w1 w2 . in turn each time the command-list following do is executed. If in w1 w2 . is omitted then the loop is executed once for each positional parameter; that is, in $* is assumed.

    Another example of the use of the for loop is the create command whose text is

    for i do >$i; done

    The command

    create alpha beta

    ensures that two empty files alpha and beta exist and are empty. The notation >file may be used on its own to create or clear the contents of a file. Notice also that a semicolon (or newline) is required before done.

    Control flow — case

    A multiple way branch is provided for by the case notation. For example,

    case $# in 1) cat >>$1 ;; 2) cat >>$2 
    is an append command. When called with one argument as
    
    append file

    $# is the string 1 and the standard input is copied onto the end of file using the cat command.

    append file1 file2

    appends the contents of file1 onto file2. If the number of arguments supplied to append is other than 1 or 2 then a message is printed indicating proper usage.

    The general form of the case command is

    case word in pattern) command-list;; . esac 

    The shell attempts to match word with each pattern, in the order in which the patterns appear. If a match is found the associated command-list is executed and execution of the case is complete. Since * is the pattern that matches any string it can be used for the default case.

    A word of caution: no check is made to ensure that only one pattern matches the case argument. The first match found defines the set of commands to be executed. In the example below the commands following the second * will never be executed.

    case $# in *) . ;; *) . ;; esac

    Another example of the use of the case construction is to distinguish between different forms of an argument. The following example is a fragment of a cc command.

    for i do case $i in -[ocs]) . ;; -*) echo \'unknown flag $i\' ;; *.c) /lib/c0 $i . ;; *) echo \'unexpected argument $i\' ;; esac done

    To allow the same commands to be associated with more than one pattern the case command provides for alternative patterns separated by a |. For example,

    case $i in -x|-y) . esac

    is equivalent to

    case $i in -[xy]) . esac

    The usual quoting conventions apply so that

    case $i in \?) . 

    will match the character ?.

    Here documents

    The shell procedure tel in section 2.1 uses the file /usr/lib/telnos to supply the data for grep. An alternative is to include this data within the shell procedure as a here document, as in,

    for i do grep $i . fred mh0123 bert mh0789 . ! done

    In this example the shell takes the lines between and ! as the standard input for grep. The string ! is arbitrary, the document being terminated by a line that consists of the string following

    Parameters are substituted in the document before it is made available to grep as illustrated by the following procedure called edg.

    ed $3 
    
    edg string1 string2 file

    is then equivalent to the command

    ed file 
    

    and changes all occurrences of string1 in file to string2. Substitution can be prevented using \ to quote the special character $ as in

    ed $3 
    

    (This version of edg is equivalent to the first except that ed will print a ? if there are no occurrences of the string $1.) Substitution within a here document may be prevented entirely by quoting the terminating string, for example,

    grep $i . #

    The document is presented without modification to grep. If parameter substitution is not required in a here document this latter form is more efficient.

    Shell variables

    The shell provides string-valued variables. Variable names begin with a letter and consist of letters, digits and underscores. Variables may be given values by writing, for example,

    user=fred box=m000 acct=mh0000

    which assigns values to the variables user, box and acct. A variable may be set to the null string by saying, for example,

    null=

    The value of a variable is substituted by preceding its name with $; for example,

    echo $user

    will echo fred.

    Variables may be used interactively to provide abbreviations for frequently used strings. For example,

    b=/usr/fred/bin mv pgm $b

    will move the file pgm from the current directory to the directory /usr/fred/bin. A more general notation is available for parameter (or variable) substitution, as in,

    echo $
    which is equivalent to

    echo $user

    and is used when the parameter name is followed by a letter or digit. For example,

    tmp=/tmp/ps ps a >$a

    will direct the output of ps to the file /tmp/psa, whereas,

    ps a >$tmpa

    would cause the value of the variable tmpa to be substituted.

    Except for $? the following are set initially by the shell. $? is set after executing each command. $? The exit status (return code) of the last command executed as a decimal string. Most commands return a zero exit status if they complete successfully, otherwise a non-zero exit status is returned. Testing the value of return codes is dealt with later under if and while commands. $# The number of positional parameters (in decimal). Used, for example, in the append command to check the number of parameters. $$ The process number of this shell (in decimal). Since process numbers are unique among all existing processes, this string is frequently used to generate unique temporary file names. For example,

    ps a >/tmp/ps$$ . rm /tmp/ps$$

    $! The process number of the last process run in the background (in decimal). $- The current shell flags, such as -x and -v. Some variables have a special meaning to the shell and should be avoided for general use. $MAIL When used interactively the shell looks at the file specified by this variable before it issues a prompt. If the specified file has been modified since it was last looked at the shell prints the message you have mail before prompting for the next command. This variable is typically set in the file .profile, in the user's login directory. For example,

    MAIL=/usr/mail/fred

    $HOME The default argument for the cd command. The current directory is used to resolve file name references that do not begin with a /, and is changed using the cd command. For example,

    cd /usr/fred/bin

    makes the current directory /usr/fred/bin.

    cat wn

    will print on the terminal the file wn in this directory. The command cd with no argument is equivalent to

    cd $HOME

    This variable is also typically set in the the user's login profile. $PATH A list of directories that contain commands (the search path). Each time a command is executed by the shell a list of directories is searched for an executable file. If $PATH is not set then the current directory, /bin, and /usr/bin are searched by default. Otherwise $PATH consists of directory names separated by :. For example,

    PATH=:/usr/fred/bin:/bin:/usr/bin

    specifies that the current directory (the null string before the first :), /usr/fred/bin, /bin and /usr/bin are to be searched in that order. In this way individual users can have their own `private' commands that are accessible independently of the current directory. If the command name contains a / then this directory search is not used; a single attempt is made to execute the command. $PS1 The primary shell prompt string, by default, `$ '. $PS2 The shell prompt when further input is needed, by default, `> '. $IFS The set of characters used by blank interpretation (see section 3.4).

    The test command

    The test command, although not part of the shell, is intended for use by shell programs. For example,

    test -f file

    returns zero exit status if file exists and non-zero exit status otherwise. In general test evaluates a predicate and returns the result as its exit status. Some of the more frequently used test arguments are given here, see test (1) for a complete specification. test s true if the argument s is not the null string test -f file true if file exists test -r file true if file is readable test -w file true if file is writable test -d file true if file is a directory

    Control flow - while

    The actions of the for loop and the case branch are determined by data available to the shell. A while or until loop and an if then else branch are also provided whose actions are determined by the exit status returned by commands. A while loop has the general form

    while command-list1 do command-list2 done 

    The value tested by the while command is the exit status of the last simple command following while. Each time round the loop command-list1 is executed; if a zero exit status is returned then command-list2 is executed; otherwise, the loop terminates. For example,

    while test $1 do . shift done

    is equivalent to

    for i do . done

    shift is a shell command that renames the positional parameters $2, $3, . as $1, $2, . and loses $1.

    Another kind of use for the while/until loop is to wait until some external event occurs and then run some commands. In an until loop the termination condition is reversed. For example,

    until test -f file do sleep 300; done commands 

    will loop until file exists. Each time round the loop it waits for 5 minutes before trying again. (Presumably another process will eventually create the file.)

    Control flow - if

    Also available is a general conditional branch of the form,

    if command-list then command-list else command-list fi 

    that tests the value returned by the last simple command following if.

    The if command may be used in conjunction with the test command to test for the existence of a file as in

    if test -f file then process file else do something else fi

    An example of the use of if, case and for constructions is given in section 2.10.

    A multiple test if command of the form

    if . then . else if . then . else if . . fi fi fi

    may be written using an extension of the if notation as,

    if . then . elif . then . elif . . fi

    The following example is the touch command which changes the `last modified' time for a list of files. The command may be used in conjunction with make (1) to force recompilation of a list of files.

    flag= 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

    The -c flag is used in this command to force subsequent files to be created if they do not already exist. Otherwise, if the file does not exist, an error message is printed. The shell variable flag is set to some non-null string if the -c argument is encountered. The commands

    ln . ; rm . 

    make a link to the file and then remove it thus causing the last modified date to be updated.

    if command1 then command2 fi

    may be written

    command1 && command2

    Conversely,

    command1 || command2

    executes command2 only if command1 fails. In each case the value returned is that of the last simple command executed.

    Command grouping

    Commands may be grouped in two ways,

     command-list ; > 
    ( command-list ) 

    In the first command-list is simply executed. The second form executes command-list as a separate process. For example,

    (cd x; rm junk )

    executes rm junk in the directory x without changing the current directory of the invoking shell.

    cd x; rm junk

    have the same effect but leave the invoking shell in the directory x.

    Debugging shell procedures

    The shell provides two tracing mechanisms to help when debugging shell procedures. The first is invoked within the procedure as

    set -v

    (v for verbose) and causes lines of the procedure to be printed as they are read. It is useful to help isolate syntax errors. It may be invoked without modifying the procedure by saying

    sh -v proc . 

    where proc is the name of the shell procedure. This flag may be used in conjunction with the -n flag which prevents execution of subsequent commands. (Note that saying set -n at a terminal will render the terminal useless until an end- of-file is typed.)

    set -x

    will produce an execution trace. Following parameter substitution each command is printed as it is executed. (Try these at the terminal to see what effect they have.) Both flags may be turned off by saying

    and the current setting of the shell flags is available as $-.

    The man command

    The following is the man command which is used to print sections of the UNIX manual. It is called, for example, as

    $ man sh $ man -t ed $ man 2 fork 

    In the first the manual section for sh is printed. Since no section is specified, section 1 is used. The second example will typeset (-t option) the manual section for ed. The last prints the fork manual page from section 2.

    cd /usr/man : 'colon is the comment command' : 'default is nroff ($N), section 1 ($s)' N=n s=1 for i do case $i in [1-9]*) s=$i ;; -t) N=t ;; -n) N=n ;; -*) echo unknown flag \'$i\' ;; *) if test -f man$s/$i.$s then $roff man0/$aa man$s/$i.$s else : 'look through all manual sections' found=no for j in 1 2 3 4 5 6 7 8 9 do if test -f man$j/$i.$j then man $j $i found=yes fi done case $found in no) echo \'$i: manual page not found\' esac fi esac done

    Что такое shell процедура

    КОМАНДНЫЙ ЯЗЫК SHELL

    Вы взаимодействуете с ОС UNIX с помощью языка shell. Программа shell переводит вводимые Вами команды в формат, который более понятен ОС UNIX.

    Одновременно shell является также интерпретирующим языком программирования. Процедура или программа на языке shell - это файл, содержащий команды и операторы. Можно создать собственную процедуру shell и выполнить ее тем же способом, как и стандартную команду ОС UNIX.

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

      1. Создавать простую процедуру shell.
      2. Помещать в нее пустые строки и комментарии.
      3. Выполнять эту процедуру.
      4. Определить термин процесс .
      5. Определить отношение между процессом-предком и процессом-потомком.
      6. Описать переменные, которые создаются shell автоматически.
      7. Выполнять команду set для вывода имен и значений всех переменных в Вашем входном shell.
      8. Выполнять команду env для вывода значений переменных среды.
      9. Использовать команду export , чтобы разрешить нескольким процессам shell одновременно использовать имена и значения переменных.
      10. Использовать оператор echo для вывода значений отдельных переменных.
      11. Определить типы переменных, допустимые в shell.
      12. Определить имена переменных, допустимые в shell.
      13. Использовать оператор присваивания и оператор read для присвоения переменным значений.
      14. Использовать подстановку команд для присвоения значения переменной.
      15. Использовать символы, завершающие значение переменной shell в операторе присваивания.
      16. Защищать оператор присваивания значения переменной от действий специальных символов (метасимволов).
      17. Соединять значения переменных.
      18. Использовать позиционные параметры.
      19. Использовать специальную переменную параметров $* .
      20. Определить процессы, выполняемые программой входа login .
      21. Описывать и создавать файл .profile.
      22. Выполнять файл .profile с помощью команды "точка" (dot).
      23. Устанавливать режимы терминала с помощью команды stty .
      24. Назначать Вашу клавишу стирания для исправления одного символа.
      25. Перечислить метасимволы, имеющие специальное значение в shell.
      26. Использовать символ обратной косой черты (backslash) для буквализации (отмены специального значения) одного метасимвола.
      27. Буквализовывать (отменять специальное значение) все метасимволы, заключенные между символами одинарных кавычек.
      28. Перечислить метасимволы, сохраняющие специальное значение между символами двойных кавычек.
      29. Использовать символы двойных кавычек для буквализации (отмены специального значения) заключенных в них метасимволов.
      30. Применять более чем один метод буквализации внутри одной и той же командной строки.
      1. Создавать простую процедуру shell.
      2. Помещать в нее пустые строки и комментарии.
      3. Выполнять эту процедуру.
      4. Определить термин процесс .
      5. Определить отношение между процессом-предком и процессом-потомком.

    Создание процедуры Shell

    Процедура Shell - это файл, содержащий команды shell (командный файл). Эти процедуры имеют большое значение поскольку они:

    • освобождают от набора на клавиатуре часто используемых команд
    • упрощают задачу запуска (submit) сложных команд
    • позволяют настроить стандартные команды ОС UNIX
    • позволяют создавать новые команды

    Создание процедуры shell и C -программы в ОС UNIX похожи . В обоих случаях в файл редактором вводятся команды Для запуска как процедуры shell, так и C-программы необходим выполняемый файл.

    В отличие от языка C , shell - интерпретирующий язык и процедуры shell не нужно компилировать. Исходный файл является выполняемым и должен иметь права доступа читать (read) и выполнять (execute) . Право доступа выполнять присваивает файлу команда chmod . Для выполнения файла, нужно, в ответ на подсказку, набрать на клавиатуре его имя и нажать клавишу .

    В этом курсе Вы выполняете процедуры shell неявно. Неявное выполнение процедур или программ shell означает, что Вы:

    1. Создаете процедуру используя текстовый редактор.

    2. Присваиваете командному файлу право доступа выполнять командой chmod .

    3. Выполняете командный файл, набирая на клавиатуре его имя, как имя команды.

    На примере 1 справа процедура c именем nfiles выводит число строк в листинге Вашего текущего каталога. Ее можно создать любым редактором, например, vi . Затем присвойте файлу право доступа выполнять командой chmod . Для выполнения наберите, в ответ на подсказку $, имя файла nfiles и .

    Имена файлов процедур shell можно выбирать произвольно, но имена стандартных команд ОС UNIX , такие как cat, ls, pwd, применять не следует.

    Если Вы не присвоили файлу право доступа выполнять с помощью команды chmod , выводится сообщение об ошибке. Например:

    $nfiles
    nfiles: execute permission denied
    $

    Это значит, что файл nfiles не имеет право доступа выполнять . Команда ls -l выведет текущие права доступа. Измените их командой chmod и выполните файл.

    СОЗДАНИЕ ПРОЦЕДУРЫ SHELL

    (текст файла nfiles был создан с помощью редактора vi)

    nfiles: execute permission denied

    $ chmod 755 nfiles
    $

    -rwxr-xr-x 1 slf train 4 Dec 7 08:35 nfiles
    $

    Комментарии и пустые строки

    Выполняя процедуру, shell читает и выполняет каждую строку содержащего ее файла. Строки, начинающиеся с символа # или любые символы, следующие за #, shell интерпретирует как комментарий. Комментарии завершаются символом в конце строки. Кроме того интерпретатор shell игнорирует пустые строки.

    Это очень полезная привычка - помещать комментарии в процедуру shell чтобы облегчить понимание ее текста. Пустые и начинающиеся с символа # строки облегчают чтение процедуры.

    КОММЕНТАРИИ И ПУСТЫЕ СТРОКИ

     

    # Эта процедура shell с именем nfiles выводит количество # # строк в листинге Вашего текущего рабочего каталога # ls | wc -l # вывести листинг текущего каталога # и связать в конвейер эту команду ls # с командой вывода количества строк wc -(lines) pwd # вывести имя каталога, # в котором только что подсчитали строки

    ################################################################# # # # Комментарии легче читать, если они окружены этими символами # # Это хорошая привычка для выделения информации # # # #################################################################

    Создание нового процесса

    При входе в ОС UNIX выполняется интерактивная процедура shell, выводящая подсказку $. Выполняющаяся в текущий момент процедура называется процессом . В отличие от процедуры или программы, находящихся в файле на диске, процесс выполняется в оперативной памяти. При вызове программы ОС UNIX читает ее с диска, загружает в оперативную память и затем выполняет.

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

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

    Например входной процесс shell интерпретирует строку команды, введенную с терминала:

    При этом он выполняет генерацию имени файла, согласно указанию в параметре file* . Другой процесс shell интерпретирует строки команд в файле nfiles этой процедуры.

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

    Каждый процесс имеет уникальный номер идентификации, называемый PID (Process Identification Number). Несмотря на то, что у родительского процесса и его потомка данные образа процесса совпадают, и номера идентификации различны. Команда ps - статус процессов, выводит PID всех выполняющихся в этот момент процессов, она обсуждается в разделе 8.

    СОЗДАНИЕ НОВОГО ПРОЦЕССА

    - Выводит подсказку shell: $ nfiles

    - Передает образ процесса

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *