Файл shell что это
Shell: что это такое и зачем он нужен
Интерпретатор командной строки, или shell (shell -- оболочка) -- эта та программа, которая принимает команды от пользователя и исполняет их.
- Взаимодействие с пользователем (редактирование командной строки, история команд и т.д.).
- Обработка (расширение) шаблонов имен (" * ", " ? " и т.д.).
- Перенаправление ввода/вывода команд.
- Управление заданиями.
Кроме того, shell -- это специализированный язык программирования, в котором есть переменные, конструкции while, if, for и т.д., функции и много чего еще. Он позволяет писать как несложные сценарии для автоматизации повседневных задач, так и довольно сложные программы (например, запуск и останов большинства Unix'ов производятся сценариями на языке shell).
Хотя работа непосредственно в командной строке (а не в оболочке типа NortonCommander или какой-нибудь оконной) на первый взгляд не столь удобна, она обеспечивает более удобный доступ к таким функциям, как перенаправление ввода/вывода и управление заданиями -- оболочки типа Midnight Commander в этом случае будут только мешать.
Shell -- это не одна конкретная программа. Исторически существует несколько подвидов оболочек; "генеалогическое древо" представлено на Рис.1.
Рис.1: семейство интерпретаторов командной строки |
Не вдаваясь в подробности истории (краткое описание можно найти в разделе 3.10 книги "Unix: универсальная среда программирования" Кернигана и Пайка), стоит лишь заметить, что csh и tcsh не в полной мере реализуют командный язык sh, а zsh, являясь самой последней разработкой, умеет все, что и любой другой подвид, и плюс много чего еще.
Кроме того, поскольку командный интерпретатор имеет десятки параметров для настройки, не следует удивляться, увидев, что некая знакомая оболочка на другом компьютере выглядит и ведет себя по другому.
Изложение в данном разделе основано на zsh (которая и используется на практических занятиях), но большая часть описанного верно и для других оболочек.
| Совет: чтобы узнать, какой используется shell, надо выполнить команду
Перенаправление ввода/вывода file", "less file" 2. "cp src1 src2 dst" -- ошибка, "cat src1 src2 >dst" -- ok 3. "cat src >>dst" 4. "ls -l | less" 5. "sort log" -- ? : stderr! "ls -l >log 2>errlog", 2>/dev/null, 2>&1 7. zsh: "ls >file1 >file2" ---- 1.5 "ls -l >file" -- "file" войдет в список от ls! --> Представим себе ситуацию: хочется посмотреть листинг директории /bin (в которой лежат многие программы). Выполняем команду " ls -l /bin " и. Результат в экран не помещается. А ведь бывают директории еще большего объема. Что делать? Большинство команд выводят информацию на терминал, а некоторые (например, текстовый редактор) вводят данные с терминала. В Unix есть почти универсальное правило: терминал может быть заменен для ввода, вывода или и того, и другого, на файл . Так, чтобы сохранить вывод нашей команды в файл, надо написать: При этом весь вывод команды ls будет вместо терминала отправлен в файл. Символ " > " означает, что выходной поток должен быть помещен в указанный далее файл, а не выведен на терминал. Если в файле что-то было, то старое содержимое будет стерто. Получив таким образом список файлов, его можно просмотреть командой less . Еще один пример: можно слить содержимое нескольких файлов в один файл, "перехватив" выходной поток команды cat и отправив его в файл: Сделать то же самое при помощи команды cp нельзя: Символ " >> " действует подобно " > ", но указывает на необходимость добавить выходной поток к концу файла, вместо того, чтобы стереть старое содержимое. Например: Первая команда cat скопирует содержимое file1 в all , а вторая -- допишет к нему содержимое file2 и file3 . Использование " >> " очень удобно, если есть некий "долгоживущий" файл (например, протокол каких-то действий или результатов), к которому иногда надо дописывать данные в конец. Просто указать " >> " с какой-нибудь командой обычно намного быстрее, чем загружать файл в текстовый редактор и что-то дописывать. |
Теперь вернемся к нашему первому примеру: как посмотреть листинг большой директории. Мы отправили вывод команды ls в файл, а потом запустили less для его просмотра. Сам же временный файл не имеет никакого смысла -- потом он больше не нужен.
Можно обойтись без временного файла, воспользовавшись конвейером:
Большинство команд, выдающих информацию из файла на экран ( cat, more, less ) устроены так, что они будут читать входной поток, если не указан никакой файл -- вот почему less показывает то, что ему "пришло" от ls .
| В отличие от Dos, где тоже поддерживаются операторы перенаправления ввода/вывода, в Unix команды в конвейере запускаются одновременно, и данные передаются через программный канал (это специальное средство, предоставляемое ядром Unix) сразу от одной программы к другой, а не через скрытый временный файл. |
Можно заставить команду читать вместо терминала не только выходной поток другой команды, но и обычный файл. Это делается при помощи оператора " < ", который указывает, что вместо терминала надо брать входной поток из указанного далее файла. Пример (команда " sort " построчно сортирует входные данные):
Что будет, если мы попросим ls показать файлы, которых нет?
Файлы которые есть, ls покажет, а про остальные скажет, что их нет. А теперь перенаправим вывод ls в файл:
В чем же дело?! Казалось бы, на экране ничего не должно появиться.
| Такое перенаправление потока stderr невозможно в оболочках csh и tcsh -- в них для этого используется другой, более запутанный синтаксис. |
Этот способ работает и тогда, когда стандартный вывод отправляется по конвейеру другой программе.
Подробную информацию на эту тему можно найти в info-документации на zsh , набрав команду " info zsh redirection ".
Часто возникает задача: надо найти, в каком файле встречается некое слово или фраза. Для этого служит команда " grep ". Она ищет "образец" в указанных файлах (или в стандартном вводе, если файлы не указаны) и печатает все строки, на которых он встречается. Пример (найти строку " no "):
Каждая строка предваряется именем файла, в котором она найдена, и двоеточием; если указан только один файл (или стандартный ввод), то этого не делается -- просто печатается найденная строка.
С ключом " -i " grep ищет, не различая маленькие/заглавные буквы:
- " . " означает "любой символ".
- " * " -- любое количество повторений (0 и больше) предшествующего символа.
- "^" -- начало строки.
- "$" -- конец строки.
- Специальное значение имеют также символы ? , [ , ] , < , >, | , + , \ .
Поскольку большинство этих символов имеют специальное значение и для оболочки, то образец следует указывать в одинарных кавычках (прямых апострофах).
Пример (найти все символьные линки в директории /etc):
Здесь используется то, что для символьных линков ls первым символом строки (тип файла) выводит букву " l ".
Вообще говоря, в конвейере может участвовать сколько угодно команд. Так, команда
делает почти то же, что и в предыдущем примере, но отбирает только те директории, в имени которых есть "lib".
| Команда grep -- одна из самых полезных и частоиспользуемых в Unix. Она столь же важна для нахождения файлов с нужным содержимым, как ls -- для нахождения файлов с нужным именем. Поэтому стоит хорошо освоить grep -- умелое владение ей позволяет сэкономить массу времени и сил. Кроме того, регулярные выражения широко используются во многих других программах. |
Фоновое исполнение задач
Часто бывает нужно запустить "долгоиграющую" программу, которая все равно пишет данные только в файл (например, какие-либо вычисления), или графическое приложение, которое не пользуется окном терминала. Но ведь пока программа запущена, терминал "принадлежит" ей, и им больше ни для чего нельзя пользоваться!
Unix позволяет запускать задачи в "фоновом режиме": если в конце командной строки указать символ " & ", то после запуска команды терминал можно продолжать использовать для ввода других команд.
Пример (запустить графический калькулятор):
В квадратных скобках shell печатает номер задания, а за ним -- номер процесса (об этом подробнее в следующем разделе).
Таким образом можно запустить в фоновом режиме несколько задач -- например, калькулятор, текстовый редактор и "снежную зиму":
Посмотреть список запущенных задач можно командой " jobs ":
(Символы "+" и "-" означают "последняя запущенная задача" и "предпоследняя").
Если у программы не предусмотрено способа завершить исполнение, то ее можно "убить" командой " kill ":
Символ процента и следующий за ним номер являются ссылкой на конкретное задание.
Если задача случайно запущена без символа " & ", то ее можно или завершить комбинацией клавиш Ctrl+C и потом запустить правильно, или "заморозить", нажав Ctrl+Z , а потом перевести в фоновый режим командой " bg " (сокращение от BackGround):
Бывает и обратное: случайно интерактивная программа (например, текстовый редактор) запущена в фоновом режиме. Интерактивные программы при этом автоматически "замораживаются" (потому, что они пытаются читать с терминала, который ей "не принадлежит"). Перевести их в "основной режим" можно командой " fg " (сокращение от ForeGround):
| Если командам bg и fg не указывать задачу, то они работают с последней запущенной -- той, что помечена символом "+". |
Если попробовать набрать " exit " для выхода из системы (или из окна терминала) при исполняющихся в фоновом режиме задачах, то zsh не позволит выйти:
Повторная команда " exit " все же будет выполнена, но zsh постарается завершить фоновые задачи:
Чтобы zsh не считал своей обязанностью "убитие" фоновых задач при выходе, можно заставить его забыть про них:
| Другие оболочки (bash и tcsh) менее "заботливы", и завершают работу по первой же команде exit , оставляя фоновые задачи "беспризорными". |
Чтобы запустить фоновую задачу и заставить zsh сразу же забыть про нее, надо набрать всю команду (включая " & ") в круглых скобках:
Допустим, запустив задачу в фоновом режиме, пользователь выходит из системы, оставляя задачу работать дальше. Хорошо, если это была графическая программа -- у нее почти наверняка будет хотя бы команда "Выход". А если нет, если это какая-либо счетная задача?
В этом случае придется воспользоваться средствами более низкого (системного) уровня -- управлением процессами.
Здесь следует сразу понять разницу. Задача (job) -- это одна или несколько программ (например, конвейер), запущенных из оболочки, которыми можно управлять при помощи команд оболочки jobs , bg , fg и kill . Процесс (process) -- это любая программа, запущенная любым способом (из оболочки; другой программой -- например, из графического меню; самой операционной системой при запуске и т.д.).
Для просмотра списка процессов служит команда " ps ". У нее есть довольно много ключей, которые к тому же различаются в BSD и SystemV. Поэтому здесь приведем лишь несколько наиболее часто встречающихся вариантов ее использования. В основном изложение относится к BSD-версии команды ps (в том числе и Linux), эквиваленты для SysV-версии (Solaris, IRIX) приведены отдельно.
Команда ps без параметров выводит список почти всех процессов, принадлежащих запустившему ее пользователю.
Из всей информации, что выдает ps , для нас пока интересны поля PID и COMMAND.
PID (Process IDentifier) -- это число, уникальное для каждого процесса, которое используется, например, для того, чтобы приостановить или завершить его исполнение. COMMAND -- название программы и ее параметры.
"Почти" -- потому, что в список не включаются процессы "без терминала", т.е. те, которые запущены в фоновом режиме, а окно, из которого это было сделано, потом было закрыто. Чтобы эти процессы также отображались, надо указать ключ " -x "; в поле TTY у них стоит " ? ".
Ключ " -a " показывает процессы всех пользователей, а не только запустившего ps.
Ключ " -u " выдает более полную информацию о каждом процессе -- потребление процессорного времени, памяти, время запуска.
Ключ " -f " выдает список процессов "со связями", позволяя понять, какой из процессов является чьим "родителем" и чьим "потомком".
Следует заметить, что в получившийся список может попасть и сам grep -- в его командной строке тоже присутствует искомое слово, а поскольку ps и grep исполняются параллельно (а может и не попасть, в случае если команда ps отработает раньше, чем запустится grep ).
| Команда ps в последних версиях Linux при указании любых ключей выдает предупреждение типа На это надо просто не обращать внимания -- просто команда ps сейчас находится в процессе переделки со стандарта BSD на стандарт Unix98, и это предупреждение -- следствие попытки обеспечить совместимость. |
- " ps " без параметров выводит список процессов, запущенных в данной сессии (т.е. в том же окне, что и ps).
- " ps -u пользователь " выводит список всех процессов указанного пользователя.
- " ps -e " показывает все процессы (аналог " ps -a " в BSD)
- " ps -f " показывает более полную информацию (аналог " ps -u " в BSD)
Команде kill можно указывать не только номер задания, но и PID. Так, команда " kill 1206 " пошлет команду завершения процессу с номером 1206. Стоит напомнить, что при запуске задач оболочка кроме номера задания печатает также PID соответствующего процесса (или процессов, в случае конвейера):
Вообще говоря, " kill " не завершает процесс, а посылает ему сигнал . Процесс же, получив сигнал, может завершиться, а может и предпринять какое-либо другое действие, например, проигнорировать сигнал.
Есть несколько десятков сигналов, каждый из которых имеет свой смысл. Каждый сигнал имеет как имя, так и номер, но, поскольку номера разные в разных Unix'ах, то лучше использовать имена. Чтобы указать kill , какой сигнал послать, надо указать его имя (или номер), предваренное дефисом:
Вот список самых часто употребляемых сигналов:
Сигнал | Назначение |
---|---|
TERM | TERMinate -- завершить работу. Используется командой kill по умолчанию |
INT | INTerrupt. Посылается при нажатии пользователем Ctrl+C |
STOP | "замерзнуть" |
CONT | CONTinue -- "размерзнуть" |
HUP | HangUP -- "повесить трубку". Посылается при выходе пользователя из системы программам, запущенным в этой же сессии |
KILL | "умереть" |
Сигналы TERM, INT, HUP и KILL обычно приводят к завершению работы программы. Разница между ними в том, в каких случаях они посылаются и в том, что одни сигналы программа перехватывает, а другие -- нет.
Сигнал KILL программа перехватить не может, поэтому если она не реагирует больше ни на что, то остается использовать его. Номер KILL во всех Unix'ах -- 9, поэтому его часто указывают по номеру, а не по имени -- " kill -9 ". Сигнал KILL следует использовать только в крайних случаях, когда ничто другое не помогает. Дело в том, что перехватив, к примеру, сигнал TERM, программа может корректно завершить работу, при надобности сохранив данные в файлы и восстановив правильное состояние терминала, а KILL не дает ей такой возможности.
Вообще говоря, большая часть функций по управлению заданиями реализуется при помощи сигналов. Так, послав программе сигнал STOP, получим тот же эффект, что и при нажатии Ctrl+Z .
В большинстве современных Unix'ов есть возможность послать сигнал процессу, указав его не по номеру, а по имени программы. Для этого служит команда " killall " -- она посылает сигнал всем процессам с указанным именем. Пример:
Не стоит ей злоупотреблять -- эта команда мало того, что "убивает" все процессы с таким именем, она пытается "убить" даже процессы с таким именем у других пользователей (чего ей Unix, естественно, не позволяет сделать).
В большинстве современных клонов Unix есть программа, позволяющая оперативно отслеживать, какие процессы запущены в системе и какие из них потребляют больше всего процессорного времени. Эта программа называется " top ".
top показывает процессы по убыванию "потребления" процессора. ("top" -- верхушка, вверху показываются те процессы, которые потребляют больше). К сожалению, как видно из приведенного примера, сам top также потребляет немало -- на старых компьютерах типа 486 он иногда пожирал больше 10%.
Где брать информацию про shell
Поскольку команды jobs , bg и fg -- это внутренние команды оболочки, то их описание следует искать в описании оболочки. Информация про перенаправление ввода/вывода имеется там же.
Для оболочек bash и tcsh лучше всего смотреть man-страницы. Для zsh -- info-документацию:
И то, и другое — интерпретаторы командной строки в линуксе. То есть если вы откроете командную строку и введете любую команду, да хоть:
То именно интерпретатор ее расшифрует и скажет компьютеру «он хочет перейти в директорию /home». Компьютер ведь не понимает команды на русском / английском языке. Ему нужны байтики. Этим и занимается интерпретатор — переводом с «нашего» на «компьютерный» язык.
Так что «cd /home» — это shell-команда! Или bash. Смотря какой интерпретатор установлен в вашей системе. В каждой операционной системе установлен интерпретатор по умолчанию. У них есть какие-то различия, но есть и набор базовых команд, которые понимают все: cd, mv, cp, ls… (в винде эти команды немного другие)
А что такое shell-скрипт тогда? Это просто текстовый документ, внутри которого написан набор команд! Это не обязательно должны быть «сложные» команды, которые делают что-то супер-навороченное. Это любые команды, которые вы выполняете в консоли.
Например, создадим скриптик, который создаст директорию и в ней файлик:
Так, команды записали, осталось сохранить их в файлик. Скрипты хранят в файлах с расширением .sh, поэтому назовем файл first_script.sh. Но есть нюанс — линуксу плевать на ваше расширение файла. Его может вообще не быть, и все равно скрипт останется скриптом. Почему? Потому что у любого скрипта в первой строке должен содержаться путь к интерпретатору. Например:
Весь файл целиком:
И даже если у такого файла не будет расширения вовсе, его можно будет запустить как скрипт:
Расширение .sh ставится для понимания человеком. Зашел в директорию:
— Ага, что тут у нас? Файлы sh, скрипты какие-то лежат.
Скрипты могут быть простые, а могут быть сложные. Вот, например, в одном проекте мы вначале вручную обновляли тестовые платформы. Для обновления надо:
Переподложить war-файл с приложением (лежат они в директории /opt)
Сервиса два, допустим это test и cloud. Так что шагов уже 6.
Когда обновлять вручную надоело, мы положили на все линукс машины простой скриптик:
Собираешь приложение, подкладываешь к скриптику и запускаешь 1 команду вместо 6. Удобно! Это называется «автоматизация рутины» =)
Другой пример с того же проекта — мы делали серверное приложение. И во время установки приложения на сервере linux нужно выполнить пункты по настройке самой системы. Например, увеличить параметр max_map_count — сколько максимум памяти может использовать процесс.
Приложение в пике работы требует много памяти. Если не настроить параметр, то «тяжеловесная» задача просто упадет с ошибкой «Не хватает памяти». И если мы видим такую ошибку, то в первую очередь идем проверять настройки системы.
Вообще, если вы отдаете установку приложения на откуп «чужим» админам, лучше потом проверять — а всё ли настроено верно? Конечно, обычно на production (машина, с которой работают реальные пользователи) настраивают всё внимательно, это на тестовых стендах могут что-то пропустить. Но лучше перебдеть!
В итоге админы настраивают окружение, а потом мы даем им скрипт, просим запустить его и прислать результаты. Я запустила скрипт на «голой» системе, где, разумеется, параметры настроены не были, и вот ответ:
Видим, что все проверки провалились, статус failed. Если и от админов приходит похожая картина, направляем их в документацию по настройке системы. Если к нам приходят с проблемой падения из-за нехватки памяти, снова просим выполнить скрипт. Так проще локализовать ошибку: это в приложении косяк, или окружение настроено плохо?
Когда надо писать скрипт?
Когда надо выполнить больше 3 команд за раз — проще выполнить одну, запустить скрипт.
Когда одну и ту же команду надо выполнять чаще 3 раз — лучше автоматизировать эту работу.
По сути своей, bash-скрипты — это та же автоматизация. А когда нужна автоматизация? Когда мы хотим избавиться от рутины, от постоянного выполнения одного и того же действия вручную. Повторяете одно и то же каждый день / неделю? Напишите скрипт. Даже если он на 2-3 строчки будет, это правда удобнее. Поверьте, сама делала небольшие скрипты =)
В первой части статьи мы рассмотрели командные оболочки, профили, синонимы и первые команды. Под спойлером я также рассказал, как развернуть тестовую виртуальную машину.
В этой части речь пойдет о файлах скриптов, их параметрах и правах доступа. Также я расскажу про операторы условного выполнения, выбора и циклы.
Скрипты
Для выполнения нескольких команд одним вызовом удобно использовать скрипты. Скрипт – это текстовый файл, содержащий команды для shell. Это могут быть как внутренние команды shell, так и вызовы внешних исполняемых файлов.
Как правило, имя файла скрипта имеет окончание .sh, но это не является обязательным требованием и используется лишь для того, чтобы пользователю было удобнее ориентироваться по имени файла. Для интерпретатора более важным является содержимое файла, а также права доступа к нему.
Перейдем в домашнюю директорию командой cd ~ и создадим в ней с помощью редактора nano ( nano script.sh )файл, содержащий 2 строки:
Чтобы выйти из редактора nano после набора текста скрипта, нужно нажать Ctrl+X, далее на вопрос "Save modified buffer?" нажать Y, далее на запрос "File Name to Write:" нажать Enter. При желании можно использовать любой другой текстовый редактор.
Скрипт запускается командой ./ , т.е. ./ перед именем файла указывает на то, что нужно выполнить скрипт или исполняемый файл, находящийся в текущей директории. Если выполнить команду script.sh , то будет выдана ошибка, т.к. оболочка будет искать файл в директориях, указанных в переменной среды PATH, а также среди встроенных команд (таких, как, например, pwd):
Ошибки не будет, если выполнять скрипт с указанием абсолютного пути, но данный подход является менее универсальным: /home/user/script.sh . Однако на данном этапе при попытке выполнить созданный файл будет выдана ошибка:
Проверим права доступа к файлу:
Из вывода команды ls видно, что отсутствуют права на выполнение. Рассмотрим подробнее на картинке:
Права доступа задаются тремя наборами: для пользователя, которому принадлежит файл; для группы, в которую входит пользователь; и для всех остальных. Здесь r, w и x означают соответственно доступ на чтение, запись и выполнение.
В нашем примере пользователь (test) имеет доступ на чтение и запись, группа также имеет доступ на чтение и запись, все остальные – только на чтение. Эти права выданы в соответствии с правами, заданными по умолчанию, которые можно проверить командой umask -S . Изменить права по умолчанию можно, добавив вызов команды umask с нужными параметрами в файл профиля пользователя (файл ~/.profile), либо для всех пользователей в общесистемный профиль (файл /etc/profile).
Для того, чтобы установить права, используется команда chmod . Например, чтобы выдать права на выполнение файла всем пользователям, нужно выполнить команду:
Чтобы выдать права на чтение и выполнение пользователю и группе:
Чтобы запретить доступ на запись (изменение содержимого) файла всем:
Также для указания прав можно использовать маску. Например, чтобы разрешить права на чтение, запись, выполнение пользователю, чтение и выполнение группе, и чтение – для остальных, нужно выполнить:
Будут выданы права -rwxr-xr-- :
Указывая 3 цифры, мы задаем соответствующие маски для каждой из трех групп. Переведя цифру в двоичную систему, можно понять, каким правам она соответствует. Иллюстрация для нашего примера:
Символ – перед наборами прав доступа указывает на тип файла ( – означает обычный файл, d – директория, l – ссылка, c – символьное устройство, b – блочное устройство, и т. д.). Соответствие числа, его двоичного представления и прав доступ можно представить в виде таблицы:
Интерпретатор командной строки, или shell (shell -- оболочка) -- эта та программа, которая принимает команды от пользователя и исполняет их.
- Взаимодействие с пользователем (редактирование командной строки, история команд и т.д.).
- Обработка (расширение) шаблонов имен (" * ", " ? " и т.д.).
- Перенаправление ввода/вывода команд.
- Управление заданиями.
Кроме того, shell -- это специализированный язык программирования, в котором есть переменные, конструкции while, if, for и т.д., функции и много чего еще. Он позволяет писать как несложные сценарии для автоматизации повседневных задач, так и довольно сложные программы (например, запуск и останов большинства Unix'ов производятся сценариями на языке shell).
Хотя работа непосредственно в командной строке (а не в оболочке типа NortonCommander или какой-нибудь оконной) на первый взгляд не столь удобна, она обеспечивает более удобный доступ к таким функциям, как перенаправление ввода/вывода и управление заданиями -- оболочки типа Midnight Commander в этом случае будут только мешать.
Shell -- это не одна конкретная программа. Исторически существует несколько подвидов оболочек; "генеалогическое древо" представлено на Рис.1.
Рис.1: семейство интерпретаторов командной строки |
Не вдаваясь в подробности истории (краткое описание можно найти в разделе 3.10 книги "Unix: универсальная среда программирования" Кернигана и Пайка), стоит лишь заметить, что csh и tcsh не в полной мере реализуют командный язык sh, а zsh, являясь самой последней разработкой, умеет все, что и любой другой подвид, и плюс много чего еще.
Кроме того, поскольку командный интерпретатор имеет десятки параметров для настройки, не следует удивляться, увидев, что некая знакомая оболочка на другом компьютере выглядит и ведет себя по другому.
Изложение в данном разделе основано на zsh (которая и используется на практических занятиях), но большая часть описанного верно и для других оболочек.
Выпускаем серию статей о том, как писать скрипты Bash. Подойдет начинающим!
Что такое Bash/Shell/Scripting
Bash - это интерпретатор командного языка. Он широко доступен в различных операционных системах и является командным интерпретатором по умолчанию в большинстве систем GNU/Linux. Название является акронимом для 'Bourne-Again SHell'.
Shell - это макропроцессор, который позволяет выполнять команды в интерактивном или неинтерактивном режиме.
Скриптинг позволяет автоматически выполнять команды, которые в противном случае выполнялись бы интерактивно одна за другой.
Основы сценариев оболочки Bash
Не отчаивайтесь, если вы не поняли ни одного из приведенных выше определений. Это совершенно нормально, ведь именно поэтому вы читаете эту статью.
Если вы не знали, Bash Scripting является обязательным навыком для любой работы в Linux системного администрирования, даже если работодатель может не требовать этого в явном виде.
Что такое Shell
Скорее всего, в данный момент вы сидите за компьютером, открыли окно терминала и задаетесь вопросом: "Что же мне делать с этой штукой?".
Так вот, в окне терминала перед вами находится shell, а shell позволяет вам с помощью команд взаимодействовать с компьютером, следовательно, получать или хранить данные, обрабатывать информацию и выполнять различные другие простые или даже очень сложные задачи.
Попробуйте это прямо сейчас! Используйте клавиатуру и введите несколько команд, таких как date, cal, pwd или ls, после чего нажмите клавишу ENTER.
Вы только что сделали то, что с помощью команд и командной оболочки взаимодействовали с компьютером, чтобы получить текущую дату и время (date), просмотреть календарь (cal), проверить расположение текущего рабочего каталога (pwd) и получить список всех файлов и каталогов, расположенных в нем (ls).
*у нас в папке пока ничего нет, поэтому команда ls не дала вывода.
Что такое Bash
До сих пор мы рассматривали shell и сценарии. А что насчет Bash? Где находится bash? Как уже упоминалось, bash является интерпретатором по умолчанию во многих системах GNU/Linux, поэтому мы использовали его, даже не осознавая этого. Вот почему наш предыдущий сценарий оболочки работает даже без определения bash в качестве интерпретатора. Чтобы узнать, какой у вас интерпретатор по умолчанию, выполните команду echo $SHELL:
Существуют различные другие интерпретаторы оболочки, такие как Korn shell, C shell и другие. Поэтому хорошей практикой является явное определение интерпретатора оболочки, который будет использоваться для интерпретации содержимого скрипта.
Что такое скриптинг (сценарии Bash)
Теперь представьте, что выполнение всех вышеперечисленных команд является вашей ежедневной задачей. Каждый день вы должны безошибочно выполнять все вышеперечисленные команды, а также сохранять наблюдаемую информацию. Вскоре это станет чрезвычайно утомительной задачей, обреченной на провал. Поэтому очевидная идея - придумать способ выполнения всех команд вместе. Именно здесь скриптинг становится вашим спасением.
Чтобы понять, что подразумевается под сценариями, используйте shell в сочетании с вашим любимым текстовым редактором, например vi, чтобы создать новый файл task.sh, содержащий все вышеперечисленные команды, каждую в отдельной строке. После этого сделайте новый файл исполняемым с помощью команды chmod с опцией +x. И наконец, запустите новый скрипт, добавив к его имени ./.
Как видите, с помощью сценариев можно автоматизировать любое взаимодействие с оболочкой. Более того, теперь можно автоматически выполнять наш новый сценарий task.sh ежедневно в любое заданное время с помощью планировщика заданий cron и сохранять вывод сценария в файл при каждом его выполнении. Однако это уже другая история, а пока давайте сосредоточимся на предстоящей задаче.
Имена файлов и разрешения
Далее давайте кратко обсудим права доступа к файлам и имена файлов. Вы, наверное, уже заметили, что для выполнения сценария shell файл должен быть сделан исполняемым с помощью команды chmod +x FILENAME. По умолчанию все вновь созданные файлы не являются исполняемыми, независимо от суффикса расширения файла.
На самом деле, расширение файла в системах GNU/Linux не имеет никакого значения, кроме того, что при выполнении команды ls для перечисления всех файлов и каталогов сразу становится ясно, что файл с расширением .sh - это, скорее всего, сценарий оболочки, а файл с .jpg - сжатое с потерями изображение.
В системах GNU/Linux команда file может быть использована для определения типа файла. Как видно из приведенного ниже примера, расширение файла не имеет никакого значения, а интерпретатор оболочки, в данном случае, имеет больший вес.
Таким образом, имя shell-сценария 0_xyz вполне допустимо, но по возможности его следует избегать.
Выполнение скриптов Bash
Далее поговорим об альтернативном способе выполнения сценариев bash. В упрощенном виде сценарий bash - это не что иное, как текстовый файл, содержащий инструкции, которые должны быть выполнены в порядке сверху вниз. То, как интерпретируются инструкции, зависит от определенного shebang или способа выполнения скрипта. Рассмотрим следующий видеопример:
Другим способом выполнения сценариев bash является явный вызов интерпретатора bash, например, $ bash date.sh , что позволяет выполнить сценарий без необходимости делать сценарий оболочки исполняемым и без объявления shebang непосредственно в сценарии оболочки. При явном вызове исполняемого двоичного файла bash содержимое нашего файла date.sh загружается и интерпретируется как сценарий оболочки Bash.
Относительный и абсолютный путь
Наконец, прежде чем мы запрограммируем наш первый официальный сценарий оболочки bash, давайте кратко обсудим навигацию оболочки и разницу между относительным и абсолютным путем к файлу.
Наверное, лучшая аналогия для объяснения относительного и абсолютного пути к файлу - это представить файловую систему GNU/Linux как многоэтажное здание. Корневой каталог (входная дверь здания), обозначенный /, обеспечивает вход во всю файловую систему (здание), а значит, дает доступ ко всем каталогам (уровням/комнатам) и файлам (людям).
Чтобы перейти в комнату 1 на уровне 3, нам сначала нужно войти в главную дверь /, затем пройти на уровень 3 level3/ и оттуда войти в комнату 1. Следовательно, абсолютный путь к этой конкретной комнате в здании - /level3/room1. Отсюда, если мы хотим посетить комнату2 на уровне 3, нам сначала нужно покинуть наше текущее местоположение - комнату1, введя ../, а затем включить название комнаты room2. Мы взяли относительный путь к room2, который в данном случае будет ../room2. Мы уже находились на уровне 3, поэтому не было необходимости покидать все здание и идти по абсолютному пути через главный вход /level3/room2.
К счастью, в GNU/Linux есть простой инструмент компас, который поможет вам ориентироваться в файловой системе в виде команды pwd. Эта команда при выполнении всегда выводит ваше текущее местоположение. В следующем примере используются команды cd и pwd для навигации по файловой системе GNU/Linux с использованием абсолютных и относительных путей.
Быстрый совет:
Выполните команду cd без аргументов, чтобы мгновенно перейти в домашний каталог пользователя из любого места. Выполните команду cd - для переключения между двумя последними посещенными местами. В каком каталоге вы оказались после выполнения команд cd ~ и cd .
Навигация по файловой системе GNU/Linux - это простая, но для многих очень запутанная тема. Ознакомьтесь с навигацией по файловой системе GNU/Linux, прежде чем переходить к следующим разделам этого учебника.
Hello World Bash Shell Скрипт
Теперь пришло время написать наш первый, самый простой сценарий оболочки bash. Целью этого сценария является не что иное, как вывод "Hello World" с помощью команды echo на вывод терминала. Используя любой текстовый редактор, создайте новый файл с именем hello-world.sh, содержащий следующий код:
После этого сделайте ваш скрипт исполняемым с помощью командыchmod и запустите его, используя относительный путь ./hello-world.sh:
Следующий видеопример предлагает альтернативный способ создания приведенного выше сценария hello-world.sh. В нем используется команда which для вывода полного пути к интерпретатору bash. Этот вывод одновременно перенаправляется с помощью знака перенаправления > и одновременно создается новый файл hello-world.sh.
Читайте также: