HackWare.ru
Этичный хакинг и тестирование на проникновение, информационная безопасность
Азы работы в командной строке Linux (часть 1)
Возникло желание написать мануал о консоли, базовых командах и азах файловой системы Linux. Когда я начинал своё знакомство с Linux именно такой инструкции мне не хватало. Надеюсь, абсолютным новичкам, которых пугают консольные команды, она поможет «влиться» в число умеющих использовать командную строку Linux.
Командная строка Linux
В зависимости от вашего Linux, ярлык для открытия консоли может быть вынесен на рабочий стол,
добавлен в избранные команды,
доступен в контекстном меню при клике правой кнопкой мыши в области рабочего стола.
Либо вы для вызова эмулятора терминала вы можете воспользоваться сочетанием клавиш CTRL + ALT + t.
В приглашении командной строки отображается имя пользователя и имя хоста. Перед областью ввода команд может быть символ решётки (#) или символ доллара ($). Символ доллара означает, что вы работаете под обычным пользователем, а символ решётки – что под суперпользователем (root).
На скриншоте видно, что я открыл консоль как обычный пользователь (символ $), а затем вошёл как root (символ сменился на #).
В некоторых инструкциях перед командами пишут $ или # и новички, пытаясь выполнить команды копированием-вставкой, получают разнообразные ошибки. Если перед командной вы видите $ или #, то их не нужно печатать – они написаны только для информирования вас о том, нужны ли дополнительные привилегии для выполнения данной команды.
TAB для автодополнения
При вводе команды или имени файла, обязательно используйте клавишу TAB – она автоматически допишет для вас команду или имя файла. Если при нажатии на TAB ничего не происходит, то быстро нажмите TAB два раза, чтобы увидеть все доступные варианты. Если варианты не выводятся, то это верный признак того, что: 1) вы неправильно начали вводить имя команды, 2) программа, которую вы намереваетесь запустить, ещё не установлена.
ENTER для запуска выполнения команд
Набрав команду, нажмите ENTER и после этого она запустится.
CTRL + c для прерывания выполнения программы
Если вы хотите оборвать выполнение команды, то используйте для этого сочетание клавиш CTRL + c. Если вы ввели команду, но передумали её запускать, то вместо удаления строки, можете также нажать CTRL + c.
↑ (курсорная клавиша вверх) для просмотра истории команд
Если вы хотите повторить выполнение команды, то клавишами ↑ и ↓ вы можете пролистать историю ранее введённых команд, выбрать любую из них для повторного выполнения, отредактировать перед запуском.
Азы файловой системы Linux
Если нужно прочитать какие-то данные или сохранить информацию в файл из консоли, нужно уметь указывать путь до файла. В файловой система Linux нет такого понятия как буквы дисков. Там используется понятие «корень». Обозначается корень символом /
После корня указываются папки (в Linux они называются директориями) и файлы. Одни папки могут быть вложены в другие – точно также как в Windows. Вложенные папки и файлы разделяются символом / (точно таким же как корень).
Пример указания пути до файла:
Эта запись означает, что файл book.txt находится в папке mial, а папка mial находится в папке home.
Базовые команды Linux
pwd для показа текущей рабочей директории
Откройте консоль и введите туда
У меня вывелось:
Здесь / (первый слеш) – это корень, home – это название папки (директории), далее / (второй слеш) – отделяет название вложенной папки, mial – название второй вложенной папки.
Команда pwd показывает «текущую рабочую директорию». Текущую рабочую директорию нужно знать при указании относительных путей до файлов и папок, также некоторые программы сохраняют результаты своего выполнения в текущую директорию.
mkdir для создания новых директорий
После mkdir укажите название папки, которую вы хотите создать. Если вы укажите относительный путь, например, так:
То будет создана новая папка test1 в текущей рабочей директории, т.е. в моём случае путь до неё будет
Также можно указать абсолютный путь до папки:
ls для просмотра содержимого каталогов
Команда ls используется для вывода списка файлов и папок текущей рабочей директории:
Теперь мы можем убедиться, что папки test1 и test2 действительно были созданы.
Чтобы список выглядел лучше, можно использовать команду ls с опцией -l
После команды и опций можно указать путь до папки, содержимое которой вы хотим посмотреть. Чтобы увидеть содержимое директории /var/log нужно ввести:
Для просмотра содержимого корневой директории:
cd для перехода по папкам (смены текущей рабочей директории)
Для перехода по папкам используется команда cd после которой пишется директория, в которую вы хотите перейти. Можно указывать относительный путь или абсолютный:
Символ . (одна точка) означает текущую директорию, а символ .. (две точки) означаете родительскую директорию. Следовательно, для перехода на один уровень вверх нужно набрать
cp для копирования файлов
Если вам нужно скопировать файл в другую директорию, то используется команда cp. После неё указывается файл, который нужно скопировать и затем через пробел директория, куда вы хотите поместить файл, например:
Этой командой я скопировал файл test.sh в директорию test1. Проверим
mv для переименования и перемещения файлов.
После команды mv указывается имя файла, который вы хотите переименовать или переместить. Затем через пробел пишется директория, куда вы хотите переместить файл (тогда файл будет перемещён в неё с исходным именем), или директория и новое имя файла (тогда файл будет перемещён и переименован), или только новое имя файла (тогда файл будет переименован).
Файл test.sh из каталога test1 я переместил в каталог test2:
Файл test.sh в каталоге test2 я переименовал в test2.sh:
Файл test2.sh в каталоге test2 я переместил в каталог test1 и присвоил ему имя new.txt:
rm для удаления файлов и папок
Чтобы удалить наши тестовые директории, воспользуемся командой rm. После этой команды укажите путь до файла или папки, которые нужно удалить. Если вы собираетесь удалить директорию, то используйте также опцию -r, она означает рекурсивно удалять каталоги и их содержимое. Можно указать сразу несколько файлов и (или) каталогов:
Для понимания иерархии файловой системы рекомендуется ещё одна статья для новичков «Структура директорий Linux. Важные файлы Linux».
Как копировать текст в командной строке и как вставлять в командную строку Linux
Привычные сочетания клавиш Ctrl+c и Ctrl+v в терминале имеют другое действие. Для копирования нужно использовать Ctrl+Insert, а для вставки Shift+Insert.
codedokode / cli.md
Я не знаю, ты пользуешься Линуксом или Уиндоузом (обычно туториалы рассчитаны на линуксоидов и макосников, уиндоуз не модный среди молодежи). В макоси все практически так же как и в линуксе, в windows пошли своим путем и сделали все как в DOS.
Думаю, что в данном случае тебе поможет не рыба, а удочка, так что держи пасту. Если после прочтения у тебя будут какие-то вопросы, или по-прежнему непонятно, почему команды не работают, пиши в наш уютный тред, разберемся.
Краткий мануал чайника по командной строке:
Как попасть в командную строку?
- Windows XP: Пуск — Выполнить — набрать cmd — нажать [enter]
- Windows7: Пуск — набрать cmd — наждать [enter]
- MacOS: Запустить приложение Терминал (его можно найти поиском в той фигне которая справа вверху экрана)
- Ubuntu: Запустить приложение Терминал или нажать Alt + Ctrl + F1 (ааа как вернуться назад? Ctrl + F7)
- Linux: если ты линуксоид, ты и так знаешь
Во всех операционных системах
↑,↓ — стрелки вверх и вниз в командной строке позволяют смотреть предыдущие введенные команды, чтобы 2 раза не набирать. В Windows при закрытии окошка консоли вся история теряется, в других ОС — сохраняется.
[tab] — автодополняет имена файлов и команды. Если в текущем каталоге есть файл file.txt, ты наберешь fi и нажмешь [tab] то он автодополнит имя файла (или предложит варианты, если таких файлов несколько).
[ctrl+c] — прерывает выполнение команды, например, если она долго тупит
Важно: клавиша Esc не работает в командной строке. Клавиши Ctrl + C, V, X не работают как «копировать/вырезать/вставить» (иногда для вставки можно использовать Shift + Ins). Клавиша Ctrl + Q не работает как «выход».
В линуксе и маке, [ctrl+l] очищает экран, [ctrl+k] и [ctrl+u] удаляют все перед или после курсора, [ctrl+w] удаляет слово перед курсором, [ctrl+r] делает поиск по истории команд (для отмены поиска нажми [ctrl+c], escape в командной строке не работает, для завершения поиска нажми стрелку вправо/влево), [ctrl+d] завершает работу и закрывает консоль.
Еще в линуксе и маке иногда не работают Home и End, используй [ctrl+a] чтобы перейти в начала строки и [ctrl+e], чтобы в конец. [alt + b] (back) и [alt + f] (forward) двигают курсор на 1 слово назад/вперед.
В командной строке не работает ctrl+v,c,x для вставки, копирования и вырезания текста. Иногда (зависит от настроек системы) вставить текст можно через [shift+ins], иногда правой кнопкой мыши. Скопировать текст можно, выделив мышью (в Windows надо разрешить выделение текста сначала в настройках окна и нажать Enter после выделения).
В командной строке результат выполнения команд зависит от того, в каком каталоге и на каком диске ты находишься. Какой каталог текущий, в Windows написано в подсказке, а в linux можно узнать командой pwd (print working directory)
Чтобы перейти в другой каталог, в линуксе используют команду cd :
В Windows, сначала надо перейти на нужный диск командой c: , d: , e: и так далее. Потом использовать cd или chdir :
Обрати внимание, windows и linux используют разные виды слешей. Обрати внимание, .. обозначает «родительский каталог». Обрати внимание, только в линукс и мак
обозначает «домашний каталог» (это /home/username или /Users/username ). . (одна точка) обозначает текущий каталог и cd . никуда не перейдет. / (линукс) или \ (Windows) обозначает корневой каталог.
В linux — команда clear или клавиша [ctrl+L], в windows — команда cls (clear screen).
Посмотреть, какие файлы есть в текущем каталоге, можно командой dir в Windows и командой ls в линуксе ( ls -a — показывает все файлы, включая скрытые, ls -l — показывает не только имена, но и размер, дату создания файла, права на него).
Посмотреть права на файл в Линукс можно либо командой ls -l , либо stat file.txt
Команды и оболочка
Оболочка — это cmd.exe в Windows и bash в линукс, это та программа, которая собственно мигает курсором и выполняет твои команды. Ты набираешь команды, а она их выполняет. Команда обычно состоит из имени команды, и, иногда, дополнительных параметров, отделенных пробелом, вроде:
Почти у любой команды есть подсказки. Чтобы их увидеть, добавь к имени команды параметр ( —help или /? ):
В линукс: ls —help — выведет справку по команде ls
В линукс: man bash — выведет подробную длинную справку по команде bash (для выхода жми q, для прокрутки используй стрелки и PgUp/PgDn)
В Windows: dir /? — выведет справку по команде dir
В Windows: help выведет подсказку по основным командам
Команды бывают внутренние (это маленький список команд, встроенных в оболочку). Встроенные команды — это, например, cd в линукс или exit в Windows. Их мало.
Внешние команды — их большинство — это фактически программы, лежащие на диске. Оболочка ищет их не по всему диску, а только в заранее заданных папках. Список папок перечислен в специальной переменной PATH. Просмотреть эту переменную можно так:
В линуксе: echo $PATH
В windows: echo %PATH%
В linux PATH — это папки /bin, /usr/bin, /usr/local/bin, /sbin, /usr/sbin, именно в них в Линуксе хранятся почти все программы. В текущем каталоге програмы не ищутся, если это не указать явно.
В Windows PATH — это всякие системные папки вроде c:\windows и так далее + текущий каталог, в котором ты находишься. Заметь, что папки вроде c:\program files\autocad в PATH не добавлены и в Windows таким образом, из командной строки обычные программы и игры, установленные в Program Files, не запустить. Только то, что положено в системные папки.
Таким образом: если ты под линуксом, и ты набираешь команду php , то скорее всего файл php лежит в одной из *bin папок и эта команда запустит php. Если ты под Windows установил php допустим в c:\php, и не прописал этот путь в PATH, то набрав php , оболочка не найдет файл php.exe и ничего не запустит. И ты скажешь «что за кривой мануал, ничего не работает, ну его нафиг».
Что же делать? 1) добавить папку с php в PATH через мой компьютер — свойства и перезалогиниться в систему 2) писать вместо php полный путь c:\php\php.exe
Продолжаем. Допустим, ты хочешь запустить в командной строке файл my.php , который находится в текущем каталоге:
Допустим, ты хочешь запустить php-файл не из текущего каталога. Тогда надо написать путь к нему:
В общем, проще запускать файлы из текущег каталога, чем мучаться с путями.
Больше команд — linux
Попрактиковаться в линукс в командной строке можно на таких командах:
Подробнее о работе команд можно узнать с помощью параметра —help , дописанного после команды.
Больше команд — Windows
Попрактиковаться в комнадной строке в Windows можно так:
Подробнее о работе команд можно узнать с помощью параметра /? , дописанного после команды.
Команды для работы с сетью Интернет
В линукс показать информацию о настройке сети: ifconfig (или /sbin/ifconfig если у тебя в PATH нет /sbin)
В Windows показать информацию о сети: ipconfig
Пропинговать (проверить связь) с сервером: ping google.com
Узнать IP по имени домена: nslookup yandex.ru
Показать список открытых с компьютера соединений: netstat (в подсказке по команде указаны также параметры, с помощью которых, например, можно вывести какая программа установила это соединение) Проверить путь до какого-то сервера или узла сети:
Основные linux-команды для новичка
Linux — это операционная система. Как винда (windows), только более защищенная. В винде легко подхватить вирус, в линуксе это практически невозможно. А еще линукс бесплатный, и ты сам себе хозяин: никаких тебе неотключаемых автообновлений системы!
Правда, разобраться в нем немного посложнее… Потому что большинство операций выполняется в командной строке. И если вы видите в вакансии «знание linux» — от вас ожидают как раз умение выполнять простейшие операции — перейти в другую директорию, скопировать файл, создать папочку… В этой статье я расскажу про типовые операции, которые стоит уметь делать новичку. Ну и плюс пара полезняшек для тестировщиков.
Я дам кратенькое описание основных команд с примерами (примеры я все проверяла на cent os, red hat based системе) + ссылки на статьи, где можно почитать подробнее. Если же хочется копнуть еще глубже, то см раздел «Книги и видео по теме». А еще комментарии к статье, там много полезного написали)
Содержание
Где я? Как понять, где находишься
Очень полезная команда, когда у вас нет ничего, кроме командной строки под рукой. Расшифровывается как Print Working Directory. Запомните ее, пригодится.
Как понять, что находится в папке
Команда ls позволяет просмотреть содержимое каталога:
Хотя лучше использовать команду сразу с флагом «l»:
Такая команда выведет более читабельный список, где можно будет сразу увидеть дату создания файла, его размер, автора и выданные файлу права.
У команды есть и другие флаги, но чаще всего вы будете использовать именно «ls – l».
См также:
Команда ls Linux — подробнее о команде и всех ее флагах
Команда ls – просмотр каталога — о команде для новичков (без перечисления всех флагов)
Как перейти в другую директорию
С помощью команды cd:
Путь может быть абсолютным или относительным.
По абсолютному пути
Либо у вас где-то записан путь, «куда идти», либо вы подсмотрели его в графическом интерфейсе (например, в WinSCP).
Вставляем путь в командную строку после «cd»
Ну вот, мы переместились из домашней директории (обозначается как
) в /home/student/log.
По относительному пути
Относительный путь — относительно вашей текущей директории, где вы сейчас находитесь. Если я уже нахожусь в /home/student, а мне надо в /home/student/log, команда будет такой:
Если мне надо из /home/student/photo в /home/student/photo/city/msk/2017/cat_1, команда будет такой:
Я не пишу /home/student/photo, так как я уже там.
В линуксе можно задавать путь относительно домашней папки текущего пользователя. Домашняя директория обозначается
/. Дальше вы уже можете указывать подпапки:
Эта команда будет работать отовсюду. И переместит нас в /home/user/log.
Вот пример, где я вошла под пользователем students. Исходно была в директории /var, а попала в /home/students/log:
С автодополнением
Если вы начнете набирать название папки и нажмете Tab, система сама его подставит. Если просто нажмете Tab, ничего не вводя, система начнет перебирать возможные варианты:
— (cd tab) Может, ты имел в виду папку 1?
— (tab) Нет? Может, папку 2?
— (tab) Снова нет? Может, папку 3?
— (tab) Снова нет? Может, файл 1 (она перебирает имена всех файлов и директорий, которые есть в той, где вы сейчас находитесь)?
— (tab) У меня кончились варианты, поехали сначала. Папка 1?
cd lon(Tab) → cd long-long-long-long-name-folder — начали вводить название папки и система сама подставила имя (из тех, что есть в директории, где мы находимся).
cd (Tab)(Tab)(Tab) — система перебирает все файлы / папки в текущей директории.
Это очень удобно, когда перемещаешься в командной строке. Не надо вспоминать точное название папки, но можно вспомнить первую букву-две, это сократит количество вариантов.
Подняться наверх
Подняться на уровень выше:
Если нужно поднять на два уровня выше, то
И так до бесконечности =) Можно использовать файл, лежащий на уровне выше или просто сменить директорию.
Обратите внимание, что команда для линукса отличается от команды для винды — слеш другой. В винде это «cd ..\..», а в линуксе именно «cd ../..».
Как создать директорию
Используйте команду mkdir:
Можно и в другом месте создать папку:
Когда это нужно? Например, если вам надо сделать бекап логов. Создаете папку и сохраняете туда нужные логи. Или если вы читаете инструкцию по установке ПО и видите там «создать папку». Через командную строку это делается именно так.
Как создать файл
Командой touch:
Такая команда создаст пустой файл с названием «app.log». А потом уже можно открыть файл в редакторе и редактировать.
Как отредактировать файл
Вот честное слово, лучше делать это через графический интерфейс!
Но если такой возможности нет, чтож… Если использовать программы, которые есть везде, то у вас два варианта:
- nano — более простая программа, рассчитана на новичков
- vim — более сложная, но позволяет сделать кучу всего
Для перемещения по файлу используйте кнопки со стрелками. После того, как закончите редактировать файл, нажмите:
- Ctrl+O — чтобы сохранить
- Ctrl+X — для выхода
А вот с vim с этим сложнее. В него легко зайти:
Войти вошли, а как выйти то, аааа? Тут начинается легкая паника, потому что ни одна из стандартных комбинаций не срабатывает: Esc, ctrl + x, ctrl + q… Если под рукой есть второй ноутбук или хотя бы телефон / планшет с интернетом, можно прогуглить «как выйти из vim», а если у вас только одно окно с терминалом, которое вы заблокировали редактором?
Делюсь секретом, для выхода надо набрать:
- :q — закрыть редактор
- :q! — закрыть редактор без сохранения (если что-то меняли, то просто «:q» не проканает)
Исходно, когда мы открываем файл через vim, то видим его содержимое, а внизу информацию о файле:
Когда нажимаем двоеточие, оно печатается внизу:
Если не печатается, не паникуем! Тогда попробуйте нажать Esc (вернуться в нормальный режим), потом Enter (подтвердить команду), а потом снова печатайте. Фух, помогло, мы вышли оттуда.
На самом деле сейчас всё не так страшно. Даже если вас заслали работать в банк, где нет доступа в интернет, а вы вошли в vi и не знаете как выйти, всегда можно погулить выход с телефона. Слава мобильному интернету! Ну а если вы знаете логин-пароль от сервера, то можно просто закрыть терминал и открыть его снова.
Если нужно выйти, сохранив изменения, используйте команду
Ну а про возможности редактирования см статьи ниже =)
См также:
Как редактировать файлы в Ubuntu — подробнее о разных способах
Как пользоваться текстовым редактором vim — подробнее о vim и всех его опциях
Как выйти из редактора Vi или Vim? — зачем нажимать Esc
Как перенести / скопировать файл
Допустим, у нас в директории /opt/app/log находится app.log, который мы хотим сохранить в другом месте. Как перенести лог в нужное место, если нет графического интерфейса, только командная строка?
Скопировать файл
Если мы находимся в директории /opt/app/log:
В данном примере мы использовали относительный путь для «что копировать» — мы уже находимся рядом с логом, поэтому просто берем его. А для «куда копировать» используем абсолютный путь — копируем в /home/olga.
Можно сразу переименовать файл:
В этом случае мы взяли app.log и поместили его в папку /home/olga, переименовав при этом в app_test_2020_03_08.log. А то мало ли, сколько логов у вас в этом папке уже лежит, чтобы различать их, можно давать файлу более говорящее имя.
Если в «куда копировать» файл с таким именем уже есть, система не будет ничего спрашивать, просто перезапишет его. Для примера положим в папку log внутри домашней директории файл «app.log», который там уже есть:
Никаких ошибок, система просто выполнила команду.
Скопировать директорию
Команда остается та же, «cp», только используется ключ R — «копировать папку рекурсивно»:
Так в директории /home/olga появится папка «log».
Переместить файл
Если надо переместить файл, а не скопировать его, то вместо cp (copy) используем mv (move).
Можно использовать относительные и абсолютные пути:
Можно сразу переименовать файл:
Переместить директорию
Аналогично перемещению файла, команда mv
Как удалить файл
С помощью команды rm (remove):
Если нужно удалить все файлы в текущей директории (скажем, вычищаем старые логи перед переустановкой приложения), используйте «*»:
Если нужно удалить папку, надо добавить флаг -r (recursive):
Если вы пытаетесь удалить файлы, которые уже используются в программе или доступны только для чтения, система будет переспрашивать:
А теперь представьте, что вы чистите много файлов. И на каждый система переспрашивает, и надо постоянно отвечать «да, да, да. » (y – enter, y – enter, y – enter)… Чтобы удалить все без вопросов, используйте флаг -f (force):
Но учтите, что это довольно опасная команда! Вот так надоест подстверждать удаление и введешь «-rf», а директорию неправильно укажешь… Ну и все, прости-прощай нужные файлы. Аккуратнее с этой командой, особенно если у вас есть root-полномочия!
Опция -v показывает имена удаляемых файлов:
Тут вы хотя бы можете осознать, что натворили )))
Как изменить владельца файла
Если у вас есть root-доступ, то вы наверняка будете выполнять все действия под ним. Ну или многие… И тогда любой созданный файл, любая папка будут принадлежать root-пользователю.
Это плохо, потому что никто другой с ними работать уже не сможет. Но можно создать файл под root-ом, а потом изменить его владельца с помощью команды chown.
Допустим, что я поднимаю сервис testbase. И он должен иметь доступ к директории user и файлу test.txt в другой директории. Так как никому другому эти файлики не нужны, а создала я их под рутом, то просто меняю владельца:
В итоге был владелец root, а стал testbase. То, что надо!
Как установить приложение
Если вы привыкли к винде, то для вас установка приложения — это скачать некий setup файлик, запустить и до упора тыкать «далее-далее-далее». В линуксе все немного по-другому. Тут приложения ставятся как пакеты. И для каждой системы есть свой менеджер пакетов:
- yum — red hat, centos
- dpkg, apt — debian
Давайте посмотрим на примере, как это работает. В командной строке очень удобно работать с Midnight Commander (mc) — это как FAR на windows. К сожалению, программа далеко не всегда есть в «чистом» дистрибутиве.
И вот вы подняли виртуалку на centos 7, хотите вызвать Midnight Commander, но облом-с.
Ничего страшного, установите это приложение через yum:
Он там будет что-то делать, качать, а потом уточнит, согласны ли вы поставить программу с учетом ее размеров. Если да, печатаем «y»:
И система заканчивает установку.
Вот и все! Никаких тебе унылых «далее-далее-далее», сказал «установи», программа установилась! Теперь, если напечатать «mc» в командной строке, запустится Midnight Commander:
Как запустить приложение
Некоторые приложения запускаются через скрипты. Например, чтобы запустить сервер приложения WildFly, нужно перейти в папку bin и запустить там standalone.sh. Файл с расширением .sh — это скрипт.
Чтобы запустить скрипт, нужно указать полный путь к нему:
Это важно! Даже если вы находитесь в той папке, где и скрипт, он не будет найден, если просто указать название sh-скрипта. Надо написать так:
Поиск идет только в каталогах, записанных в переменную PATH. Так что если скрипт используется часто, добавляйте путь туда и вызывайте просто по названию:
См также:
Запуск скрипта sh в Linux — подробнее о скриптах
Если же приложение запускается как сервис, то все еще проще:
Чтобы сервис test запускался автоматически при рестарте системы, используйте команду:
Она добавит службу в автозапуск.
Как понять, где установлено приложение
Вот, например, для интеграции Jenkins и newman в Jenkins надо прописать полный путь к ньюману в параметре PATH. Но как это сделать, если newman ставился автоматически через команду install? И вы уже забыли, какой путь установки он вывел? Или вообще не вы ставили?
Чтобы узнать, куда приложение установилось, используйте whereis (без пробела):
Как создать архив
Стандартная утилита, которая будет работать даже на «голой» системе — tar. Правда, для ее использования надо запомнить флаги. Для создания архива стандартная комбинация cvzf:
В данном примере мы упаковали директорию /home/test, внутри которой было две картинки — 502.jpg и 504.jpg.
Для распаковки меняем флаг «c» на «x» и убираем «z»:
Хотя система пишет, что распаковала «/home/test», на самом деле папка «test» появляется там, где мы сейчас находимся.
Давайте разберемся, что все эти флаги означают:
- c — создать архив в linux
- x — извлечь файлы из архива
- v — показать подробную информацию о процессе работы (без него мы бы не увидели, какие файлики запаковались / распаковались)
- f — файл для записи архива
- z — сжатие
Если очень хочется использовать rar, то придется изгаляться. Через yum установка не прокатит:
Говорит, нет такого пакета:
Придется выполнить целую пачку команд! Сначала скачиваем, разархивируем и компилируем:
Как посмотреть использованные ранее команды
Вот, допустим, вы выполняли какие-то сложные действия. Или даже не вы, а разработчик или админ! У вас что-то сломалось, пришел коллега, вжух-вжух ручками, magic — работает. А что он делал? Интересно же!
Или, может, вы писали длинную команду, а теперь ее надо повторить. Снова набирать ручками? Неохота! Тем более что есть помощники:
Если надо «отмотать» недалеко, проще через стрелочку пролистать команды. Один раз нажали — система показала последнюю команду. Еще раз нажали — предпоследнюю. И так до 1000 раз (потому что именно столько хранится в истории).
Большой бонус в том, что линукс хранит историю даже при перезапуске консоли. Это вам не как в винде — скопировал текст, скопировал другой, а первый уже потерялся. А при перезагрузке системы вообще все потерялось.
Если тыкать в стрелочку не хочется, или команды была давно, можно напечатать «history» и внимательно изучить команды.
См также:
История команд Linux — больше о возможностях history
Как посмотреть свободное место
Сколько места свободно на дисках
Сколько весит директория
Как узнать IP компьютера
Если у вас настроены DNS-имена, вы подключаетесь к linux-машине именно по ним. Ведь так проще запомнить — это testbase, это bugred… Но иногда нужен именно IP. Например, если подключение по DNS работает только внутри рабочей сети, а коллега хочет подключиться из дома, вот и уточняет айпишник.
Чтобы узнать IP машины, используйте команду:
Также можно использовать ifconfig:
Как узнать версию OS
Сидите вы у Заказчика на линуксовой машине. Пытаетесь что-то установить — не работает. Лезете гуглить, а способы установки разные для разных операционных систем. Но как понять, какая установлена на данной машине?
На этой виртуалке стоит CentOs 7.
Если нужна версия ядра:
Как узнать, как работает команда
Если вы не знаете, как работает команда, всегда можно спросить о ней саму систему, используя встроенную команду man:
Закрыть мануал можно с помощью клавиши q. Для того, кто первый раз в линуксовой консоли, это совсем не очевидно, а подсказки есть не везде.
Команда удобна тем, что не надо даже уходить из командной строки, сразу получаешь всю информацию. К тому же это всегда актуальная информация. А что вы там нагуглите — неизвестно =))
Хотя лично мне проще какую-то команду прогуглить, ведь так я получу русское описание + сначала самые главные флаги (а их может быть много). Но я сама новичок в линуксе, это подход новичка. А лучше сразу учиться прокачивать навык поиска по man-у. Он вам очень пригодится для более сложных задач!
Если man у программы нет, используйте флаг -h (—help):
Как создать много тестовых папок и файлов
Допустим, у нас есть некая папка test. Создадим в ней сотню директорий и кучу файликов в каждой:
Вот и все, дальше можно играться с ними!
- mkdir — создать директорию
- touch — создать файл (или изменить существующий, но если файла с таким именем нет, то команда создаст новый, пустой)
- <000..100>— пробежится по всем числам от 0 до 100
— пробежится по всем буквам английского алфавита от A до Z
Символ $ при описании команд означает начало строки, куда мы пишем команду. Так мы отделяем то, что ввели сами (pwd) от ответа системы (/home/test).
Ага, в домашней директории. Создам себе песочницу:
Вот в ней и буду творить!
А потом можно проверить, что получилось:
Как-то так! Имхо, полезные команды.
Я нашла их в книге «Командная строка Linux. Полное руководство», они используются для того, чтобы создать песочницу для прощупывания команды find. Я, как и автор, восхищаюсь мощью командной строки в данном случае. Всего 2 строчки, а сколько боли бы принесло сделать похожую структуру через графический интерфейс!
И, главное, тестировщику полезно — может пригодиться для тестов.
Как протестировать IOPS на Linux
Это очень полезно делать, если машину вам дает заказчик. Там точно SSD-диски? И они дают хороший iops? Если вы разрабатываете серверное приложение, и от вас требуют выдерживать нагрузку, нужно быть уверенными в том, что диски вам выдали по ТЗ.
Наше приложение активно использует диск. Поэтому, если заказчик хочет видеть хорошие результаты по нагрузке, мы хотим видеть хорошие результаты по производительности самих дисков.
Но верить админам другой стороны на слово нельзя. Если приложение работает медленно, они, разумеется, будут говорить, что у них то все хорошо, это «они» виноваты. Поэтому надо тестировать диски самим.
Я расскажу о том, как мы тестировали диски. Как проверили, сколько IOPS они выдают.
1) Скачиваем последнюю версию, распаковываем, переходим в каталог. В командах ниже нужно заменить «fio-3.19» на актуальную версию из списка
2) Должны стоять пакеты для сборки
Какие должны быть результаты:
- Средний SSD, выпущенный 2-3 года назад — 50 тысяч IOPS.
- Свежий Samsung 960 Pro, который стоит на одной из железок у нас в офисе — 350 тысяч IOPS.
Если должно быть 50 тысяч, а диск выдает сильно меньше, то:
— он не SSD;
— есть сетевые задержки;
— неправильно примонтирован;
— с ними что-то еще плохое случилось и стоит поднять алярм.
И это все?
Еще полезно изучить команду find и регулярные выражения. Тестировщику как минимум надо уметь «грепать логи» — использовать grep. Но это уже остается на самостоятельный гуглеж.
База, которая всегда нужна — pwd, cp, mv, mkdir, touch. Остальное можно легко гуглить, как только возникает необходимость.
Вот вам еще пара ссылочек от меня:
-
— а то вроде про «>» знаешь еще по винде, а что значит «>>»? Вот в статье и ответ! — очень полезная штука, если у вас есть доступы на продакшен. Обезопасьте себя )))
Книги и видео по теме
Где тренироваться
Можно поднять виртуалку. Правда, тут сначала придется разбираться, как поднимать виртуалку )))
А можно купить облачную машину. Когда мне надо было поиграться с линуксом, я пошла на SimpleCloud (он мне в гугле одним из первых выпал и у него дружелюбный интерфейс. Но можно выбрать любой аналог) и купила самую дешманскую машину — за 150 руб в месяц. Месяца вам за глаза, чтобы «пощупать-потыркать», и этой машины с минимумом памяти тоже.
У меня был когда-то план самой платить эти 150р за то, чтобы дать машину в общий доступ. Но увы. Как я не пыталась ее огородить (закрывала команды типа ssh, ping и прочая), у меня не получилось. Всегда есть люди, которых хлебом не корми, дай испортить чужое. Выложил в общий доступ пароли? На тебе ддос-атаку с твоего сервера. Ну и сервер блокируют. После N-ой блокировки я плюнула на это дело. Кто хочет научиться, найдет 150р.
Основы командного интерфейса
Поскольку не исключена вероятность, что эту книгу будут читать и совсем начинающие применители Linux'а вообще, тех, для кого Mint оказался первым дистрибутивом этой операционной системы, в этом очерке будут даны некоторые общие сведения об интерфейсе командной строки ( CLI — Command Line Interface). Тем более, что это потребуется уже ближайшее время, в очерках, посвящённых управлению пакетами.
Введение в CLI
CLI представляет собой базу, для которой GUI всякого рода являют лишь оболочку. Всякое действие в linux-системе может быть выполнено прямой командной директивой. И его же можно осуществить путем манипулирования объектами. Например, копирование файлов выполняется соответствующей командой — cp , это первый способ. Но его же можно осуществить перетаскиванием мышью объекта, представляющего наш файл зрительно, из того места, где он находился ранее, туда, где мы хотим видеть его копию, а это уже второй способ.
То есть манипуляция объектами в GUI — это обычно более или менее опосредованное выполнение соответствующих данному действию команд. Почему основные навыки работы с CLI не помешают даже тому пользователю, который не вылезает из графической среды. Ибо сфера применения CLI не ограничивается «голой» консолью. Он же используется в эмуляторах терминала в графическом режиме оконной среды X . Более того, в настоящее время это основная среда для применения командного интерфейса — к текстовой консоли обычно обращаются только в аварийных ситуациях.
CLI в большинстве случаев обеспечивается классом программ, именуемых командными интерпретаторами, командными процессорами, командными оболочками или по простому шеллами ( shell ).
Как легко догадаться по одному из определений, кроме предоставления пользовательского интерфейса, шеллы выполняют и вторую функцию — служат интерпретаторами собственных языков программирования. На этом основывается классификация шеллов — они разделяются на две группы, обычно именуемые Bourne-shell совместимые и C-shell совместимые. В силу ряда причин в качестве стандарта принята одна из оболочек первой группы — так называемый POSIX-шелл . Правда, он представляет собой чистую абстракцию, однако большинство используемых в Unix'ах оболочек с этим стандартом совместимы. А системная оболочка Mint , Dash , довольно точно воспроизводит и его функциональность. И потому все примеры, иллюстрирующие принципиальные вопросы CLI, будут базироваться на наиболее используемых командах, построенных в соответствие с правилами POSIX-шелла.
Командная строка
Основой командного интерфейса является командная строка, начинающаяся с приглашения для ввода. Далее он будет обозначаться милым сердцу россиянина символом длинного зеленого друга — $ , если речь идёт о сеансе обычного пользователя, или символом решётки — # , для приглашения строки в сеансе администратора. Это — чистая условность: вид приглашения может быть настроен в широких пределах, причём по разному в разных оболочках. Об этом мы поговорим, когда речь дойдёт до описания конкретного шелла — Zsh .
Командная строка — визуальное представление среды, в которой задаются основные элементы командного интерфейса: командные директивы с их аргументами и опциями.
Командная директива (или просто команда) — основная единица, посредством которой пользователь взаимодействует с шеллом. Она образуется по определенным правилам, именуемым синтаксисом. Синтаксис командной директивы определяется, в первую очередь, языком, принятым в данной командной оболочке. Кроме того, некоторые команды (не очень многочисленные, но весьма употребимые) имеют собственный, нестандартный синтаксис.
Однако в целом базовые правила построения команд имеют много общего. И именно эти базовые правила станут предметом данного раздела. Синтаксические особенности отдельных нестандартных команд будут оговариваться по ходу изложения.
Итак, командная директива образуется:
- именем команды, однозначно определяющим ее назначение,
- опциями, определяющими условия выполнения команды, и
- аргументами — объектами, над которым осуществляются действия.
Очевидно, что имя команды является обязательным компонентом, тогда как опции и аргументы могут и отсутствовать (или подразумеваться в неявном виде по умолчанию).
ещё один непременный компонент командной директивы — это специальный невидимый символ конца строки: именно его ввод отправляет команду на исполнение. В обыденной жизни этот символ вводится нажатием и отпусканием клавиши Enter . Почему обычно и говорят: для исполнения команды нажмите клавишу Enter . Тот же эффект, как правило, достигается комбинацией клавиш Control+M . Символа конца командной строки, знаменующего исполнение команды, мы на экране не видим. Однако важно, что это — такой же символ, как и любой другой (хотя и имеющий специальное значение).
В подавляющем большинстве случаев опции (или их последовательности) задаются непосредственно за именем команды, а аргумент (или группа аргументов) команду завершает, хотя это правило имеет некоторые исключения. Вне зависимости от порядка опций и аргументов, принятых для данной команды, интерпретация их осуществляется слева направо.
Команды, опции и аргументы обязательно разделяются между собой пробелами. Кроме того, опции обычно предваряются (без пробела) символом дефиса или двойного дефиса. Впрочем, немногочисленные (но весьма употребимые) команды могут использоваться с опциями без всяких предваряющих символов.
Как уже говорилось, имя команды определяет выполняемые ею функции. Существуют команды, встроенные в оболочку, то есть не имеющие запускающих их исполняемых файлов, и команды внешние. В последнем случае имя команды однозначно указывает на имя исполняемого файла программы, выполняемой при отдаче соответствующей директивы. Часто встроенные и внешние команды одного назначения имеют одинаковые имена. В этом случае обычно предпочтительно использование встроенных команд — впрочем, они и вызываются в первую очередь. Для вызова одноимённой внешней команды её нужно задать с указанием пути. Так, директива
вызовет для определения времени выполнения команды search (о ней будет рассказываться в следующем очерке) встроенную команду time . А в форме
будет задействована внешняя утилита с тем же именем. Кстати, это один из тех случаев, когда второй вариант может иногда оказаться предпочтительней: встроенная и внешняя команды имеют разные форматы вывода, причём в первой он зависит от используемой командной оболочки. И потому она не всегда подходит для прямого сравнения результатов — например, быстродействия в разных системах.
Определить, является ли данная команда встроенной в оболочку или внешней, можно с помощью встроенных команд type или which . Для встроенных команд вывод их будет таким:
Или, в некоторых случаях, таким:
Для внешних команд любой из этих вариантов даст в выводе путь к исполняемому файлу:
Некоторые команды могут выступать под несколькими именами. Это связано с тем, что исторически в различных Unix-системах команды, исполнявшие одинаковые функции, могли получать разные названия. В каждой конкретной системе обычно используется только одна из таких команд-дублеров. Но при этом имена дублирующих команд также могут присутствовать в системе — для совместимости. Не следует думать, что это две различные программы одного назначения: как правило, такая синонимичность команд реализуется посредством механизма ссылок (links) или псевдонимов (alias), о которых речь пойдёт позднее.
Иногда команда, вызванная через имя своего синонима, может отличаться по своей функциональности от самой же себя, вызванной под родным именем. В этом случае говорят о эмуляции одной команды другой. Типичный пример — командная оболочка /bin/bash в большинстве дистрибутивов Linux имеет своего дублера — /bin/sh ; вызванная таким образом, она воспроизводит базовую функциональность стандарта POSIX-шелла.
Автодополнение
Для правильного применения команд, конечно же, нужно знать их имена и назначение. Однако нас никто не заставляет напрягать пальцы вводом имени команды полностью. Потому что тут на помощь приходит великий метод автодополнения.
Благодаря этому методу для любой команды достаточно ввести первые несколько ее символов — и нажать клавишу табуляции ( Tab ). И, если введённых буковок достаточно для однозначной идентификации, полное имя команды волшебным образом возникнет в строке. Если же наш ввод допускает альтернативы продолжения имени — все они высветятся на экране (сразу или после повторного нажатия на табулятор), и из них можно будет выбрать подходящую.
Большинство употребимых команд POSIX-систем — коротки и мнемонически прозрачны. И может показаться. что не такое уж это облегчение — заменить ввод двух-трех символов нажатием табулятора (а то ещё и неоднократным). Однако, когда речь дойдет до аргументов команд — тут вся мощь автодополнения станет явной.
И ещё маленькое отступление. Автодополнение — стандартная возможность Bash и всех других командных оболочек, относимых к категории развитых. Но как раз в стандарте POSIX эта возможность не предусмотрена, и потому POSIX shell ее лишён. Нет этой функции и в Dash — системной командной оболочке Mint . Которая, впрочем, в интерактивном режиме не используется.
Ещё один способ облегчения ввода команд — обращение к их истории, о чём разговор будет несколько позже.
Опции
Указания только имени команды достаточно для выполнения некоторых из них. Типичный пример — команда ls (от list), предназначенная для просмотра имен файлов (строго говоря, содержимого каталогов). Данная без аргументов, она выводит список имен файлов, составляющих текущий каталог, представленный в некоторой форме по умолчанию, например, в домашнем каталоге пользователя это будет выглядеть примерно так:
Исполнение же многих других команд невозможно без указания опций и (или) аргументов. Для них в ответ на ввод одного её имени часто следует не сообщение об ошибке (или не только оно), но и краткая справка по использованию команды. Например, в ответ на ввод команды для создания каталогов mkdir (от make directory) последует следующий вывод:
Для одних опций достаточно факта присутствия в командой директиве, другие же требуют указания их значений (даваемых после опции обычно через знак равенства). В приведённом примере команды mkdir к первым относятся опции -v (или —verbose ), предписывающая выводит информацию о ходе выполнения команды (запомним эту опцию — в том же смысле она используется чуть ли не во всех командах Unix), и -p , которая позволяет создать любую цепочку промежуточных каталогов между текущим и новообразуемым (в случае их отсутствия).
А вот опция -m , определяющая атрибуты доступа к создаваемому каталогу, обязательно требует указания значения — этих самых атрибутов, заданных в символьной форме.
Многие опции имеют две формы — краткую, односимвольную, и полную, или многосимвольную, Некоторые же опции могут быть даны только в многосимвольной форме. Общее правило здесь таково: если одного символа достаточно для однозначного определения опции, могут употребляться обе формы в качестве равноправных. Однако поскольку количество символов латинского алфавита ограниченно (а человеческая фантазия, конструирующая опции — безгранична), при большом количестве опций одной команды некоторые из них приходится делать исключительно многосимвольными.
Продемонстрирую это на примере опций все той же команды mkdir . Полный их список будет следующим:
Очевидно, что для опции —version краткая форма совпала бы с таковой для опции —verbose , и потому первая существует только в полной форме. А вот для опции —help краткая форма в большинстве команд возможна, и она выглядит как -h . Более того, во многих командах вызов помощи может быть вызван посредством опции -? . К слову сказать — приведенный выше список опций команды mkdir получен именно таким способом.
Раз уж зашла речь об опциях —version и -h ( —help , -? ), давайте и их запомним на будущее. Это — так называемые стандартные опции GNU, в число коих входит и опция -v , —verbose . Назначение «длинной» их формы ( —version , —help , —verbose ) идентично почти во всех командах, краткой — во многих.
Опять-таки, из того же примера видно, что опции в односимвольной форме предваряются единичным символом дефиса и могут быть даны единым блоком, без пробелов:
При этом, естественно, опция, требующая указания значений, ставится последней, и ее значение отделяется пробелом. Опции же в многосимвольной форме требуют предварения удвоенным дефисом, обязательно должны разделяться пробелами и значения их, если таковые требуются, присваиваются через символ равенства (по научному он называется ещё оператором присваивания):
Загадочные семерки после опции -m ( —mode ) — это и есть те самые атрибуты доступа, данные в символьной нотации, о которых речь пойдёт в соответствующем разделе.
Опции команды именуются также флагами (реже ключами) или параметрами. Однозначной трактовки этих терминов нет. Однако обычно под флагами подразумеваются опции, не требующие указания значений. Термин параметр же применяется к опции, такового требующей, и объединяет опцию и ее значение. Правда, мне встречалось определение параметра как совокупности опций и аргументов, но я буду придерживаться приведенных определений.
Порядок опций, если их приводится более одной, для большинства команд не существенен. Хотя, например, для команды tar , создающей файловые архивы, опция -f , значением которой является имя создаваемого или распаковываемого архива, традиционно указывается последней. И, к слову сказать, именно эта команда — одна из немногих, опции которой не обязаны предваряться символами дефиса. Так, директивы
абсолютно равноценны: и та, и другая создает единый архивный файл filename.tar из отдельных файлов каталога dir .
Особый смысл имеет символ удвоенного дефиса — , если после него не следует никакой опции: таким образом обозначается конец списка опций, и все последующие, отделённые пробелом, символы интерпретируются как аргументы. Одинарный же дефис с последующим пробелом, напротив, подменяет аргументы команды, то есть в качестве таковых рассматривается стандартный ввод: знание этого нам потребуется, когда речь дойдёт до командных конвейеров.
Пример: опции команды ls
Опции определяют условия выполнения команды. На предыдущей странице был приведён пример команды ls без опций. Однако на самом деле отсутствием опций при ней определяется вид выводимого списка по умолчанию — как многоколочночного списка, состоящего из имен файлов без учета т.н. скрытых файлов (а таковыми являются файлы, имена которых начинаются с символа точки, почему они ещё называются dot-файлами), без каких-либо их атрибутов и без визуального различия файлов различных типов.
Различные же опции команды ls определяют состав и формат выводимого списка файлов. Так, в форме
она обеспечивает вывод списка имен всех файлов текущего каталога, включая скрытые файлы вида .* (символ * здесь обозначает шаблон имени, соответствующий любому количеству любых символов — в том числе и нулевому, то есть отсутствию оных), символы текущего ( ./ ) каталога и каталога родительского ( ../ ).
дается вывод списка имен файлов в «длинном» формате (отсюда название опции -l — от long), то есть с указанием атрибутов доступа, принадлежности, времени модификации, размера и некоторых других характеристик:
позволяет получить список файлов с символьным различением файлов различных типов. Например, имя каталога будет выглядеть как dirname/ , имя исполнимого файла — как filename* (здесь звездочка — не шаблон имени, а символическое обозначение исполняемого файла), и так далее.
Я столь подробно остановился на команде ls не только из-за многочисленности ее опций: это — одна из самых употребимых команд для просмотра файловой системы. И, должным образом настроенная (в том числе и с помощью приведенных опций), она дает ничуть не менее информативную и зрительно выразительную картину, чем развитые файловые менеджеры типа Midnight Commander или многочисленные файловых менеджеры графического режима.
Аргументы
Таким образом мы подобрались к понятию аргументов командной директивы. Аргументами определяется, как правило, объект (или объекты) действия команды. В большинстве случаев в качестве аргументов команд выступают имена файлов и (или) пути к ним.
Выше говорилось, что при отсутствии аргументов команда ls выводит список имен файлов текущего каталога. Это значит, что текущий каталог выступает как заданный неявным образом (по умолчанию) аргумент команды ls . Если же требуется вывести список имен файлов каталога, отличного от текущего, путь к нему должен быть указан в качестве аргумента команды явно, например:
Большинство команд допускает указание не одного, а нескольких (и даже очень многих) аргументов. Так, единой директивой вида
можно скопировать (команда cp — от copy) сколько угодно файлов из текущего каталога в каталог dir (на самом деле на это «сколько угодно» накладываются некоторые теоретические ограничения, определяемые максимально возможной длиной командной строки, но практически предел этот очень далек).
Маленькое отступление. Упоминание команды cp — удобный случай чуть вернуться назад и рассмотреть одну очень важную опцию, почти универсальную для команд POSIX-систем. Для начала попробуем скопировать один каталог в другой:
Как вы думаете, что получится в результате? Правильно, сообщение о невозможности выполнения этой операции — примерно в таком виде:
поскольку команда cp в чистом виде для копирования каталогов не предназначена. Что делать? Очень просто — указать опцию -R (от Recursive; в большинстве систем проходит и опция -r с тем же смыслом, но первая форма работает абсолютно везде. В результате в каталог dir2 не только будут скопированы сам каталог dir1 и все входящие в него файлы, но и вложенные подкаталоги из dir1 , если таковые имеются.
Маленькое уточнение: вполне возможно, что в дистрибутиве, который имеется в вашем распоряжении, проходит и копирование каталогов просто через cp , без всяких дополнительных опций. Это — потому, что команда cp часто определяется как псевдоним самой себя с опцией рекурсивного копирования, о чем скоро пойдет речь.
Вообще рекурсия (то есть определение некоего выражения через самого себя) — очень важное понятие в Unix, пронизывающее происходящие от нее системы насквозь. И послужившие даже базой для своеобразного хакерского юмора. Однако сейчас для нас важно только то, что рекурсия применима практически ко всем файловым операциям, позволяя распространить действие одной командной директивы не только на файлы данного каталога, но и на все вложенные подкаталоги и их содержимое.
Однако вернемся к аргументам. Действие некоторых команд неоднозначно в зависимости от аргументов, к которым она применяется. Например, команда mv служит как для переименования файлов, так и для их перемещёния в другой каталог. Как же она узнает, что ей делать в данном конкретном случае? Да именно по аргументам. Если дать ее в форме
то следствием будет переименование filename1 в filename2 . А вот если первым аргументом указан файл, а вторым — каталог, например
то результатом будет перемещёние filename из текущего каталога в каталог dir . К слову сказать, команды типа mv воспринимают разное количество аргументов в зависимости от того, какие они, эти аргументы. В первом примере аргументов может быть только два — имя исходного файла и имя файла целевого. Зато во втором примере в качестве аргументов можно задать сколько угодно файлов и каталогов (с учетом вышеприведенной оговорки относительно «сколько угодно») — все они будут перемещёны в тот каталог, который окажется последним в списке. То есть директивой:
в каталог dirN будут перемещёны все файлы file1 . fileN и все каталоги dir1 . dirM . Характерно, что для этого команде mv , в отличие от команды cp , ей не требуется каких-либо дополнительных опций — она рекурсивна по самой своей природе.
Пути к файлам
Для правильного построения аргументов команды требуется рассмотрение ещё одного понятия — пути к файлу. Путь — это точное позиционирование файла в файловой системе относительно ее корня (обозначаемого символом прямого слэша — / ) или нашего в ней положения — текущего каталога (который, напомню, символически обозначается единичной точкой — . ).
Так, если пользователь находится в своем домашнем каталоге (абсолютный путь к нему обычно выглядит как /home/username ), то просмотреть содержимое каталога /usr/bin он может двумя способами — тем, который был дан в предыдущем примере, или вот так:
Первый путь в аргументе команды ls — абсолютный, отсчитываемый от корневого каталога, второй — задается относительно каталога текущего, ведь ../ — это родительский каталог для него.
Пути в аргументах команд могут быть весьма длинными. Например, чтобы просмотреть список шрифтов, применяемых в интерфейсе Cinnamon по умолчанию, нужно дать команду следующего вида:
И читатель вправе спросить — неужели мне все это вводить вручную? Отнюдь — отвечу я ему. Потому что автодополнение, о котором упоминалось по ходу разговора об именах команд, действует также для путей в их аргументах — последовательным нажатием клавиши табуляции все недостающие символы будут добавляться
Ещё один способ избежать набора длинных путей к файлам — это определение переменной PATH . Внимательный читатель, вероятно, обратил внимание, что при наборе команды путь к исполняемому её файлу не указывается. Для внутренних команд причина понятна — они прошиты в самой оболочке. А как мы обходимся без указания путей к командам внешним? Неужели система мистическим чувством определяет, где они находятся?
Отнюдь, ни малейшей мистики, Просто каталоги, в которых находятся команды (а это, как правило, /bin , /sbin , /usr/bin , /usr/sbin ) определены в качестве значений переменной PATH , о чём мы подробнее поговорим со временем.
Кое-что об исключениях
Итак, типичная форма POSIX-команды в обобщенном виде выглядит следующим образом:
Из этого правила выбиваются немногочисленные, но весьма полезные и часто используемые команды. Однако и для таких команд с нестандартным синтаксисом устанавливаются те же компоненты — имя, опции, аргументы, хотя по ряду причин (в том числе исторических) порядок их может меняться.
Это можно проиллюстрировать на примере полезнейшей команды find , предназначенной для поиска файлов (и не только для этого — она являет собой почти универсальное орудие в деле всякого рода файловых манипуляций). В типичной своей форме она выглядит примерно следующим образом:
Здесь dir — каталог, в котором выполняется поиск, — может рассматриваться в качестве аргумента команды. Опция -option1 (обратим внимание, что здесь, не смотря на многосимвольность опций, они предваряются единичным символом дефиса) и ее значение value определяют критерий поиска, например, -name filename — поиск файла с указанным именем, а опция -option2 предписывает, что же делать с найденным файлом (файлами), например, -print — вывести его имя на экран. причём опция действия также может иметь значение. Например, значением опции -exec будет имя команды, вызываемой для обработки найденного файла (файлов). Так, директива вида
требует отыскать в домашнем каталоге (
/ ), выступающем в качестве аргумента, файлы, имя которых (первая опция — критерий поиска) соответствует шаблону *.tar (значение первой опции), и выполнить (вторая опция — действия) в их отношении команду tar с собственными опциями, обеспечивающими распаковку архивов (значение второй опции). Интересно, что в этом контексте в качестве значений второй опции команды find выступает не только внешняя команда, но и все относящиеся к ней опции.
В последнем примере имеется несколько символов, смысл которых может показаться непонятным. Надеюсь, он прояснится достаточно скоро — в разговоре о регулярных выражениях.
Псевдонимы
Вернемся на минуту к команде ls . У читателя может возникнуть вполне резонный вопрос: а если я всегда хочу видеть ее вывод с символическим различением типов файлов, да ещё в «длинном» формате? Ну и без вывода скрытых файлов мне никак не прожить. И что же — мне каждый раз вводить кучу опций, чтобы получить столь элементарный эффект?
Отнюдь — ответил бы граф, стуча манжетами о подоконник. Потому что этот вопрос задавали себе многие поколения не только пользователей, но и разработчиков. И ответили на него просто — введением понятия псевдонима команды (alias).
Что это такое? В большинстве случаев — просто некоторое условное имя, подменяющее определённую команду с теми её опциями, которые мы используем чаще всего. Причём, что характерно, псевдоним команды может совпадать с ее именем. То есть, например, — набирая просто ls , мы получаем список файлов не в умолчальном формате, а в том, в каком угодно нам.
Устанавливаются псевдонимы очень просто — одноименной командой alias , в качестве аргументов которой выступают имя псевдонима и его значение, соединенные оператором присваивания (именуемым в просторечии знаком равенства). А именно, если мы хотим ныне, и присно, и во веки веков видеть вывод команды ls с символьным различением типов файлов, нам достаточно дать команду вроде следующей:
Здесь следует обратить внимание на два момента: а) на то, что имя псевдонима совпадает с именем команды (что отнюдь не препятствует создания псевдонима типа ll='ls -l' специально для вывода файловых списков в длинном формате), и б) на одинарные кавычки, в которые заключено значение псевдонима. Смысл их станет ясен несколькими параграфами позже, а пока просто запомним, что кавычки (и именно одинарные) — обязательный атрибут команды установки псевдонима.
Таким образом мы можем наделать себе псевдонимов на все случаи жизни. В разумных пределах, конечно — иначе вместо упрощения жизни мы создадим себе необходимость запоминания множество невнятных сочетаний символов. Однако на наиболее важных (и обычно определяемых) псевдонимах я остановлюсь.
Вспомним команды типа cp и mv , которыми мы, в частности, можем скопировать или переместить какие-то файлы из каталога в каталог. А что произойдет, если чисто случайно в целевом каталоге уже имеются файлы, одноименные копируемым/перемещаемым? Произойдет штука, могущая иметь весьма неприятные последствия: файлы в целевом каталоге будут заменены новыми, теми, что копируются туда или перемещаются. То есть исходное содержание этих файлов будет утрачено — и безвозвратно, восстановить его будет невозможно никакими силами.
Разумеется, иногда так и нужно, например, при полном резервном копировании старые версии файлов и должны быть заменены их более свежими вариантами. Однако такое приемлемо далеко не всегда. И потому в большинстве команд, связанных с необратимыми изменениями файловой системы, предусматривается специальная опция — -i (или —interactive ). Если задать эту опцию с командой cp или mv , то при совпадении имён исходного и целевого файлов будет запрошено подтверждение на выполнение соответствующего действия:
И пользователь может решить, нужно ли ему затирать существующий файл, ответив yes (обычно достаточно y ), или это нежелательно, и должно ответить no (а также просто n — или не отвечать ничего, это равноценно в данном случае отрицательному ответу).
Так вот, дабы не держать в голове необходимость опции -i (ведь, как я уже говорил, пропуск ее в неподходящий момент может привести к весьма печальным результатам), в подавляющем большинстве систем для команд cp и mv (а также для команды rm , служащей для удаления файлов — эта операция также практически необратима) определяются одноименные им псевдонимы такого вида:
Все это, конечно, очень благородно, заметит внимательный читатель. Но что, если мне заведомо известно, что сотни, а то и тысячи файлов целевого каталога должны быть именно переписаны новыми своими версиями? Что же, сидеть и, как дурак, жать на клавишу Y ?
Не обязательно. Потому что все команды рассматриваемого класса имеют ещё опцию -f (в «длинной» своей форме, —force , она также практически универсальна для большинства команд). Которая, отменяя действие опции -i , предписывает принудительно переписать все файлы целевого каталога их обновленными тезками. И никто не мешает нам на этот случай создать ещё один псевдоним для команды cp , например:
Правда, предварительно нужно убедиться, что в системе нет уже команды с именем, совпадающим с именем псевдонима — иначе эффект может быть весьма неожиданным (впрочем, это относится ко всем псевдонимам, не совпадающим с именами подменяемых команд).
Есть и другой способ обойти опции, установленные для команды-псевдонима: просто отменить псевдоним. Что делается командой обратного значения
То есть дав директиву
мы вернем команде копирования ее первозданный смысл. Ну а узнать, какие псевдонимы у нас определены в данный момент, и каковы их значения, ещё проще: команда
без опций и аргументов выведет полный их список:
Когда я сказан о пользовании псевдонимами ныне, и присно, и вовек, — то был не совсем точен. Ныне, то есть в текущем сеансе пользователя — да, они работают. Однако после рестарта системы (или просто после выхода из данного экземпляра командной оболочки) они исчезнут без следа. Чтобы заданные псевдонимы увековечить, их нужно прописать в конфигурационном файле пользовательского шелла. Но этим мы займемся впоследствии. А пока обратимся к переменным.
Переменные
Переменные играют для аргументов команд примерно такую же роль, что и псевдонимы — для команд. То есть избавляют от необходимости мрачного ввода повторяющихся последовательностей символов. Конечно, это — далеко не единственное (а может быть, и не главное) назначение переменных, однако на данном этапе для нас наиболее существенное.
Что такое переменная? Ответ просто — некоторое имя, которому присвоено некоторое значение. Не очень понятно? — Согласен. Но, возможно, станет яснее в дальнейшем.
Имена переменных в принципе могут быть любыми, хотя некоторые ограничения также существуют. Я уже вскользь упоминал о переменных в разговоре про пути к файлам, где фигурировала переменная PATH . Когда дело дойлёт у нас до пользовательских аккаунтов, придётся поговорить о переменных SHELL , USER , HOME .
Все эти (и ещё некоторые) имена зарезервированы за внутренними, или встроенными, переменными оболочки (некий минимальный их набор имеется в любом шелле). То есть значения их определены раз и навсегда. и пользователем не изменяются. То есть он, конечно, может их изменить, если очень хочет — но ничего доброго, кроме путаницы, из этого не выйдет.
Таких встроенных переменных довольно много. Одна из первых по значению — всё та же переменная PATH . Это — список каталогов, в которых оболочка, в ответ на ввод пользователя в командной строке, ищет исполнимые файлы — то есть просто команды. Я уже обращал внимание, что во всех приведённых выше примерах имена команд указывались без всяких путей к ним (в отличие от файлов-аргументов, путь к которым — обязателен). Так вот, успех её поисков и определяется списком значений переменной PATH . Каковые могут быть просмотрены командой echo :
Обратим внимание на то, что в качества аргумента команды выступает не просто имя переменной, а оно же, но предваренное символом доллара. Который в данном случае никакого отношения к приглашению командной строки не имеет, а предписывает команде echo подменить имя переменной ее значением (значениями). В большинстве дистрибутивов Linux случае вывод команды для пользователя будет в обязательном порядке включать такие каталоги:
Для администратора системы сюда обязательно добавятся каталоги /sbin , /usr/sbin и /usr/local/sbin . Остальные значения переменной PATH могут варьировать по умолчанию, а также задаваться пользователем (как — поговорим позже).
Обратим вниммание на одно важное обстоятельство: практически во всех дистрибутивах Linux и в более иных ОС в перечне значений переменной PATH отсуствует текущий каталог
Тем временем вернемся к переменной HOME . Значение ее — полный абсолютный путь к домашнему каталогу пользователя. То есть, чтобы перейти в него, пользователю по имени alv вместо
и он в своих владениях. Может показаться, что экономия — грошовая (тем паче, что перейти в собственный каталог пользователь может просто командой cd без всяких аргументов), но минуту терпения — и выгоду от использования переменных вы увидите.
Кроме переменных, предопределенных в шелле, пользователю предоставляется почти полная свобода в определении переменных собственных. И вот тут-то и наступает ему обещанное облегчение при наборе аргументов команд.
Предположим, что у нас имеется глубоко вложенный подкаталог с данными, постоянно требующимися в работе. Чисто условно примем, что путь к нему — следующий:
Весьма удручающе для набора, даже если исправно работать табулятором для автодополнения, не так ли? Прекрасно, упрощаем себе жизнь определением переменной:
Дело в шляпе, Теперь, если нам нужно просмотреть состав этого каталога, достаточно будет команды
А вызвать из него любой файл для редактирования можно так:
Подобно псевдонимам, переменные, определенные таким образом (то есть просто в командной строке), имеют силу только в текущем сеансе работы — по выходе из оболочки они утрачиваются. Для того, чтобы они действовали перманентно, переменные должны быть прописаны в конфигурационном файле пользовательского шелла. Однако, в отличие от псевдонимов, и этого оказывается не всегда достаточно. Ибо переменная, определенная посредством
работает не просто только в текущем сеансе — но ещё и только в конкретном экземпляре шелла. Почему и называется переменной оболочки — shell variable. Звучит это. быть может, пока не очень понятно. Однако практически любое действие в шелле — запуск команды или программы, например, — начинается с того, что оболочка, в которой это действие совершается, запускает новый экземпляр самой себя — дочерний шелл, или, как иногда говорят, субшелл.
Так вот, этот самый субшелл не наследует переменные родительской оболочки. И в итоге запущенная из командной строки программа ничего не будет знать, например, о путях к исполняемым файлам. Что автоматически ведет к невозможности запуска из нее команд просто по имени, без указания точного пути.
Чтобы избежать такой неприятной ситуации, было придумано понятие переменных окружения, или переменных среды — environment variable. Это — те переменные, которые наследуются от родительского шелла всеми дочерними программами. И чтобы сделать их таковыми, переменные следует экспортировать. Как? Командой export, которая может быть применена двояким образом. Можно сначала определить переменную:
а затем применить к ней команду export :
А можно сделать это в один прием:
Второй способ применяется, если нужно определить и экспортировать одну переменную. Если же за раз определяется несколько переменных:
то проще прибегнуть к первому способу, так как команда export может иметь сколько угодно аргументов:
Традиционно имена переменных окружения задаются в верхнем регистре, переменных оболочки — в нижнем.
Навигация и редактирование
Имя команды, ее опции и аргументы образуют т.н. командные «слова». В качестве словоразделителей выступают пробелы. Кроме того, как разделители «слов» интерпретируется ряд специальных символов — прямой слэш ( / ) — элемент пути к файлу, обратный слэш ( \ ), служащий для экранирования специальных символов, и операторы командных конструкций, о которых будет сказано ниже.
В некоторых случаях имеет смысл различать «большое слово» и «малое слово». Первые разделяются пробелами, в качестве же вторых интерпретируются символы, лежащие между всеми другими словоразделителями.
Подчеркнем, что командное «слово» прямо не соотносится ни с опциями, ни с аргументами команды. Введение этого понятия призвано просто облегчить навигацию в командной строке и ее редактирование.
Ибо одно из великих достижений командного интерфейса POSIX-систем, заценить которое могут в полной мере только те, кто застал времена «черного DOS'а», — это возможность перемещёния внутри командной строки и внесения необходимых изменений в имя команды, ее опции и аргументы. Делается это различными способами.
Самый привычный и, казалось бы, очевидный способ — использование клавиш перемещёния курсора Left , Right , End и Home , действующих (хотя и не всегда) в командной строке точно так же, как и в каком-нибудь ворд-процессоре для Windows (клавиши Up , Down , PageUp , PageDown зарезервированы для других целей). То есть они позволяют перемещаться на один символ влево и вправо. в начало и конец командной строки. А если добавить сюда ещё клавиши Delete и Backspace , позволяющие удалять символы в позиции курсора или перед ней — то, казалось бы, чего ещё желать?
Оказывается — есть чего, и самый очевидный способ навигации и редактирования оказывается не самым эффективным. Для начала заметим, что в общем случае привычные клавиши перемещёния курсора и редактирования в POSIX-системах не обязаны работать также, как они делают это в DOS/Windows. Это зависит от многих причин, в том числе и исторических. Ведь POSIX-системы по определению предназначены работать на любых практически машинах (в том числе и на тех, клавиатуры которых клавиш управления курсором просто не имели).
Однако это не главное — в большинстве Linux-дистрибутивов командная оболочка по умолчанию настраивается так, чтобы пользователь при желании мог использовать привычные ему клавиши. Однако тут-то и оказывается, что плюс к этому оболочка предоставляет ему много более эффективную систему навигации по командной строке и ее редактирования. И это — система управляющих последовательностей, так называемых keybindings. То есть сочетания специальных клавиш, именуемых управляющими, с обычными алфавитно-цифровыми.
Управляющие последовательности
Основные управляющиеся клавиши, которые используются в таких последовательностях (и имеются на клавиатурах почти любых машин — как говорят в таких случаях, в любых типах терминалов) — это клавиши Control и Meta .
Пардон — возразит внимательный читатель, — сколько я ни долблю по клавишам моей PC'шки, но клавиши Meta не замечал. Возражение принято, но: на PC-клавиатурах функции Meta выполняют либо а) нажатие и отпускание клавиши Escape , либо б) нажатие и удерживание клавиши Alt .
Впрочем, к этой теме я ещё вернусь. А пока достаточно нескольких простых рецептов, практически универсальных для любых командных оболочек в терминалах любых типов.
Рецепт первый: большая часть управляющих последовательностей состоит из сочетания клавиши Control и алфавитно-цифрового символа. Под сочетанием (или комбинацией, для чего я уже употреблял ранее символ плюс) понимается то, что, удерживая нажатой клавишу Control , мы одновременно нажимаем и какую-нибудь литерную или цифровую.
Так, действие клавишной комбинации Control+F (от Forward — в большинстве случаев регистр алфавитной клавиши управляющей последовательности значения не имеет) эквивалентно нажатию клавиши Right — это перемещёние на один символ вправо, комбинации Control+B (от Back ) — нажатию Left (перемещёние на один символ влево). Комбинации Control+A и Control+E действуют аналогично Home и End , перемещая курсор в начало и конец командной строки, соответственно, Ну а с помощью комбинаций Control+D и Control+H можно удалить единичный символ в позиции курсора или перед ней (также, как и клавишами Delete и Backspace , соответственно).
Предвижу резонный вопрос: а какие достоинства в комбинации клавиш Control+Что_то по сравнению с элементарными End или Left ? Конечно, одно достоинство — очевидно: при массовом вводе команд (а также, забегая вперед, замечу — и любых иных наборов символов, от исходных текстов до романов), при использовании keybindings руки не отрываются от основной (алфавитно-цифровой) части клавиатуры. И в итоге, по приобретении некоторого минимального навыка, дело движется ну гораздо быстрее. Обосновать тестами не могу (тут какая-нибудь физиометрия понадобится), но не верящим — предлагаю попробовать.
Главное же преимущество клавиатурных последовательностей перед стандартными навигационными клавишами — много более широкая их функциональность. Я не случайно начал этот параграф с упоминания командных «слов» — это, наряду с единичными символами, также навигационные (и, добавлю, редакционные) единицы командной строки. То есть управляющие последовательности позволяют при навигации и редактировании оперировать не только единичными символами, но и целыми словами.
Например, комбинация Meta+F смещает курсор на одно «слово» вперед, та же Meta в сочетании с B — на одно слово назад, и так далее. Прошу обратить внимание: действие алфавитной клавиши в комбинации с Meta сходно по смыслу ее сочетанию с клавишей Control , но как бы «усилено»: последовательность Meta+D уничтожает не символ в позиции курсора, как это было бы для D в сочетании с Control , а все командное «слово».
Рассматривать ключевые последовательности подробно здесь я не буду: детали их действия зависят от командной оболочки и ее настроек. Отмечу только два существенных обстоятельства. Первое: keybindings предоставляют пользователю полный комплекс приемов для любых действий в командной строке — вплоть до преобразования регистров уже введенных символов и «слов» (из нижнего в верхний и наоборот), «перетасовки» символов в команде или ее аргументах, и так далее.
Значение управляющих последовательностей не ограничивается командной строкой — большинство популярных в POSIX-мире текстовых редакторов, от простых Nano или joe до грандиозного vim и монструозного emacs . построены по тому же принципу. Так что навыки, полученные при работе с keybindings, например, в Bash, весьма поспособствуют виртуозному освоению любого из этих инструментов.
И второе — действие ключевых последовательностей, как правило. не зависит не только от типа терминала и физического устройства клавиатуры, но и от ее раскладки — при переключении на кириллицу они будут работать столь же справно, как и в латинице.
История команд
Возможности навигации и редактирования строки особенно ярко проявляются в сочетании с другой замечательной особенностью, предоставляемой командными оболочками — доступом к истории команд. То есть: раз введенная в строке команда не уходит в небытие после исполнения, а помещается в специальный буфер памяти. Который, как и все в Unix'ах, именуется весьма незатейливо — буфер истории команд. Откуда команда (со всеми её опциями и аргументами) может быть извлечена для повторного использования. Или — для редактирования и исполнения в новой реинкарнации.
Буфер истории команд сохраняется в течении всего сеанса работы. Однако в большинстве случаев командные оболочки настраиваются так, что по выходе из сеанса буфер истории сохраняется в специальном файле в домашнем каталоге пользователя, и таким образом его содержимое оказывается доступным при следующем запуске шелла. Имя этого файла может быть различным в разных оболочках, но обычно включает компонент history (в Bash —
/.bash_history ).Так что, можно сказать, что введенным нами командам суждена вечная жизнь.
Конечно, не совсем вечная. И размер буфера истории команд, и количество строк в файле истории — величины конечные. Так что, если установленный предел превышен, то старые команды вытесняются более новыми. Однако и величину буфера, и количество строк в файле истории можно установить любыми. Разумеется, в разумных пределах — не знаю, существует ли принципиальное ограничение на их размер, за исключением объёма памяти и дискового пространства. А если учесть, что и из буфера, и из памяти с помощью соответствующих настроек (со временем я расскажу, каких) можно исключить дубликаты и ещё кое-какой мусор — то мое заявление о вечной жизни команд не выглядит столь уж преувеличенным.
Универсальное средство доступа к буферу истории команд — специальная команда, встроенная во все шеллы, таковой поддерживающие — history (в большинстве дистрибутивов Linux она по умолчанию имеет псевдоним — h ). Данная без опций, эта команда выводит полный список команд в их исторической (издревле к современности) последовательности, или некоторое количество команд, определенных соответствующими настройками (о которых будет говориться позднее).
В качестве опции можно указать желаемое количество одновременно выведенных команд. Например, директива
выведет две последние команды из буфера истории вместе с их номерами:
Любая из команд в буфере истории может быть повторно запущена на исполнение. Для этого достаточно набрать в командной строке символ ! (восклицательный знак) и затем, без пробела — номер команды в списке буфера. Например,
для приведенного выше примера повторно откроет файл shell.html в текстовом редакторе joe .
Другой способ доступа к командам из буфера истории — комбинации клавиш Control+P и Control+N , служащие для последовательного его просмотра (как бы «пролистывания») назад и, соответственно, вперед (разумеется, если есть куда). Они дублируются клавишами управления курсором Up и Down (назад и вперед, соответственно). Кроме того, последовательности Meta+< и Meta+&rt; обеспечивают переход к первой и последней команде в буфере истории.
Любая извлеченная (с помощью стрелок или управляющими последовательностями) из буфера истории в текущую строку команда может быть повторно запущена на исполнение — нажатием клавиши Enter или дублирующей ее комбинацией Control+M . причём предварительно ее можно отредактировать — изменить опции, или аргументы, — точно так же, как и только что введенную.
Поиск в истории
Во всех современных «развитых» шеллах предусмотрены средства поиска команды в буфере истории — простым перебором (обычно Meta+P — назад и Meta+N — вперед).
Впрочем, не смотря на громкое название, обычный поиск ничем практически не отличается от пролистывания исторического списка курсорными стрелками. Что при обширной истории команд может быть весьма утомительным. И потому для ее облегчения предусмотрена такая интересная возможность, как наращиваемый поиск (incremental search) нужной команды в буфере истории по одному (или нескольким) из составляющих ее символов.
Выполняется инкрементный поиск так: после нажатия (при пустой командной строке) клавишной комбинации Control+R появляется предложение ввести алфавитный символ (или — последовательность символов произвольной длины), заведомо входящий в состав требуемой команды:
Ввод такого символа выведет последнюю из команд, его содержащих. При этом введенный символ будет отмечен знаком курсора. Он не обязан входить в имя команды, но может быть составляющим ее опций или аргументов (имени файла или пути к нему, например). Следующее нажатие Control+R зафиксирует курсор на предыдущем символе, в пределах этой же или более ранней по списку команды, и т.д. Однако вместо этого в строке поиска можно вводить дополнительные символы, детализирующие условия поиска команды (или — ее опций и аргументов).
Процедуру поиска можно продолжать вплоть до достижения требуемого результата — то есть нахождения той команды, которая нужна именно сейчас. Нажатие клавиши Enter в любой из этих моментов запускает найденную (то есть помещённую в командную строку) команду на исполнение, с завершением поиска. Поиск обрывается также и нажатием комбинации Control+C . Перед запуском найденная команда может быть отредактирована стандартными средствами — с использованием управляющих последовательностей.
Регулярные выражения
Как известно, все пользователи-POSIX'ивисты должны быть в обязательном порядке привержены одному из семи смертных грехов. И грех этот — леность, можно сказать, показатель профессиональной пригодности линуксоида. В соответствие со своей леностью разработчики POSIX-систем придумывают способы, как бы им минимизировать свои усилия. А применители из лени изощряются в использовании этих приемов на практике. В частности — в том, как свести к минимуму набор в командной строке.
Собственно говоря, этой цели служили почти все приемы, описанные выше. Осталось осветить немногое. А именно — регулярные выражения, реализуемые с помощью т.н. специальных символов (или метасимволов).
Элементарная, и весьма частая, в духе школьных, задача: из каталога dir1 требуется скопировать все файлы в каталог dir2 . Так неужели все они должны быть перечислены в качестве аргументов команды cp ? Нет, нет, и ещё раз нет. Ибо для этой цели придуманы шаблоны имен файлов. Самый часто используемый из них — специальный символ * (вроде бы я о нем уже говорил?). Он подменяет собой любое количество любых символов (в том числе — и нулевое, то есть отсутствие символов вообще). То есть для решения предложенной задачи нам достаточно дать команду:
Чуть усложним условия: к копированию из dir1 предназначены не все файлы, а только html-документы, традиционно имеющие суффикс html . Решение от этого не становится сложнее:
Однако тут можно вспомнить, что html-документы могут иметь и расширение htm . Не пропустим ли мы их таким образом при копировании? Таким — безусловно, пропустим. Однако нам на помощь придет другой шаблон — символ ? . А соответствует он любому единичному символу (или — его отсутствию, т.е. символу null). И значит, если команда из примера будет модифицирована таким образом:
то она гарантированно охватит все возможные маски html-документов.
Вроде все хорошо. Однако нет: из каталога dir1 нам нужно скопировать только три определенных файла — file1 , file2 , file3 . Не придется ли каждый из них указывать в командной строке с полным путем (а ведь они могут быть и в глубоко вложенном подкаталоге типа dir1/dir11/dir111 )? Все равно не придется, на столь хитрую. постановку задачи у нас есть прием с левой резьбой — символы группировки аргументов, обозначаемые фигурными скобками. Что на практике выглядит так:
И приведет к единоразовому копированию всех трех файлов в каталог dir2 . Заметим, что сгруппированные аргументы разделяются запятыми без пробелов. И ещё: в оболочке Bash группируемые аргументы придется полностью вводить руками. Но вот в Zsh на них распространяется возможность автодополнения, да и запятая после каждого имени появляется автоматически (и столь же автоматически исчезает при закрытии фигурной скобки).
Группировка аргументов может быть сколь угодно глубоко вложенной. Так, команда
в один заход создаст трехуровневую структуру каталогов внутри текущего — если только не забыть про опцию -p , которая предписывает создавать промежуточные подкаталоги в случае их отсутствия.
И ещё несколько примеров. Регулярное выражение для диапазона — то есть вида [. ] , подменяет любой из символов, заключенных в квадратные скобки. Символы эти могут даваться списком без пробелов (например, выражение [12345] соответствует любому символу от 1 до 5 ) или определяться в диапазоне, крайние значения которого разделяются дефисом без пробелов (эквивалентное первому выражение — [1-5] ). Кроме того, символ ^ , предваряющий список или диапазон, означает отрицание: выражение [^abc] подменяет любой символ, исключая символы a , b и c .
Последние примеры регулярных выражений могут показаться надуманными. Однако представим. что в том же каталоге dir1 , кроме html-документов, содержатся также файлы изображений в различных форматах — GIF, JPEG, TIFF и так далее (традиционно имеющие одноименные расширения). И все они должны быть скопированы в каталог dir2 , а вот как раз html-файлы нам в данный момент без надобности. No problemas, как говорят у них:
И в каталоге dir2 окажется все содержимое каталога dir1 , за исключением html-файлов.
Экранирование
Из приведённых примеров можно видеть, что метасимволы, образующие регулярные выражения, интерпретируются командной оболочкой особым образом, не так, как обычные алфавитно-цифровые символы, составляющие, скажем, имена файлов.
В то же время собственно POSIX-системы накладывают на имена файлов очень мало ограничений. И в принципе система не запретит вам создать файл с именем, содержащим метасимволы. Другое дело, что работать с таким образом именованными файлами может быть сложно — командная оболочка будет пытаться интерпретировать их в соответствии с правилами для регулярных выражений.
Конечно, использовать метасимволы в именах файлов весьма не рекомендуется. Однако а) возможны элементарные ошибки при наборе, и б) файлы, полученные при обмене с другими операционными системами (сами знаете. какими), могут иметь довольно непривычный (и, я даже сказал бы, неприличный) вид.
Вспомним, что MS Word в качестве имени файла спокойно берёт первую фразу документа. А если это — вопрос? И тогда завершающий имя символ ? будет в шелле интерпретироваться как шаблон, а не как элемент имени. Думаю, не нужно обладать очень развитым воображением, чтобы представить последствия. Что делать в таких ситуациях? Для их разрешения резонными людьми придумано было понятие экранирования.
Начнём с первого примера использования экранирования — разрыва длинных строк. Командные директивы, с многочисленными их опциями, особенно в полной форме, и аргументами могут оказаться весьма длинными, не укладывающимися в пределы экранной строки. Правда, обычно командная оболочка по умолчанию настраивается с разрешением так называемого word wrapping'а (то есть переноса «слов» команды без обрыва строки — последнее, как мы помним, достигается нажатием клавиши Enter или комбинации Control+M и приводит к немедленному исполнению введённой команды. Если ввод ее не окончен — последует сообщение об ошибке). Однако перенос «слов» при этом происходит, как бог на душу положит. И в результате командная директива теряет читабельность и становится сложной для понимания.
Тут-то и приходит на помощь понятие экранирования, упомянутое абзацем выше. Знак экранирования — обратный слэш ( \ ), — превращает символ, имеющий специальное значение, например, упоминавшийся ранее шаблон в именах файлов — * , в самую обычную звездочку. А раз конец строки — тоже символ, хотя и специальный, то и он доступен для экранирования. Так что если завершить введённый фрагмент команды обратным слэшем (некоторые оболочки требуют предварить его пробелом, и лучше так и делать, хотя в Bash или Zsh пробел не обязателен), после чего нажать Enter , то вместо попытки исполнения будет образована новая строка. в которой можно продолжать ввод. Вид приглашения к вводу при этом изменится — это будет так называемое вторичное приглашение командной строки, и его представление настраиваемо, также как и вид приглашения первичного.
Возвращаемся к экранированию обратным слэшем. Действие его распространяется только на непосредственно следующий за ним символ. Если символы, могущие быть воспринятые как специальные, идут подряд, каждый из них должен предваряться обратным слэшем.
У обратного слэша есть ещё одна интересная особенность — я назвал бы ее инвертированием специального значения символов. Для примера: некая последовательность цифр (например, 033 ), введенная в командной строке, будет воспринята как набор обычных символов. Однако она же может выступать как код какого-либо символа (в частности, 033 — код символа Escape в восьмеричной системе счисления). И подчас возникает необходимость ввода таких кодов (тот же код для Escape , скажем, затруднительно ввести каким-либо иным образом).
И вот тут обратный слэш проявляет свое инвертирующее действие: последовательность \033 будет восприниматься уже не как набор символов, а как код символа Escape (обратим внимание, что тут достаточно единичного слэша). Непосредственно в командной строке такой способ инвертированного экранирования, по понятным причинам, обычно не используется, но находит широкое применение в сценариях.
О кавычках
Есть и экраны, распространяемые на все, что заключено внутри них. Это — кавычки, двойные и одинарные: большая часть символов между ними утрачивает свое специальное значение. Но не все: в двойных кавычках сохраняют специальное значение метасимволы $ и \, а также обратные кавычки (`), о назначении которых я скажу чуть позже. То есть в них сохраняется возможность, с одной стороны, получения значений переменных (как мы помним, с помощью $ИМЯ ). А с другой стороны, если нам требуется дать символ бакса в его прямом и привычном значении, у нас есть возможность заэкранировать его обратным слэшем. И если потребуется вывести на экран сообщение «с вас, уважаемый, пятьсот баксов», то это можно сделать таким образом:
ещё одно широко применяемое использование двойных кавычек — экранирование пробелов, предотвращающих разбиение аргументов команды на отдельные «слова». Правда, в случае с командой echo это, как правило, не требуется (хотя настоятельно рекомендуется экранировать ее аргумент таким образом). Однако представьте, что в качестве аргумента команды копирования и перемещёния выступает файл, переписанный с Windows-машины. Ведь там пробелы в именах — вещь обычная. Тут-то экранирование двойными кавычками и придется к месту.
Из сказанного понятно, почему двойные кавычки именуются ещё неполными, или не строгими — они все же допускают внутри себя использование символов со специальными значениями. В противоположность им, кавычки одинарные носят имя строгих, или полных. Потому что между ними утрачивают специальное значение все метасимволы, кроме их самих — в том числе и символ единичного экранирования. В итоге они используются там, где гарантированно требуется отсутствие специальных символов. Если вы помните, мы применили строгие кавычки при установке псевдонимов. Они же часто оказываются обязательными при определении переменных.
Завершая тему экранирования, осталось сказать только об обратных кавычках. Их функция очень узка: они служат для экранирования команд. То есть, скажем, команда
в полном соответствие со своим именем, просто выведет нам собственный аргумент:
Однако если аргумент команды закрыть обратными кавычками, то date будет воспринято как имя команды, подлежащей исполнению. И результат этого исполнения (то есть текущая дата и время — а именно для их получения и предназначена команда date) будет замещать имя команды в выводе echo:
Если вспомнить, что обратные кавычки сохраняют свое специальное значение внутри кавычек двойных, становится ясной польза от их применения: они незаменимы в тех случаях, когда требуется вывод результатов работы одной команды внутри другой. К как в нашем примере с выводом даты, если его (вывод) следует включить в некое выдаваемое командой echo сообщение.
Конечно, в описанном случае добиться той же цели можно было бы гораздо легче — просто командой date. Однако представьте, что у нас возникло желание одновременно и получить сведения о количестве пользователей в системе (для чего предназначена команда who). Тут-то и выясняется. что проще всего это сделать командой типа следующей:
Ответом на что будет сообщение, подобное тому, что часто можно наблюдать на главной странице многих сайтов:
А теперь последнее, чем и закроем тему регулярных выражений вообще. В этом разделе рассматривалось использование метасимволов в командной оболочке (конкретно, в данном случае. в Dash, Bash и Zsh). В других оболочках применение метасимволов и условия их экранирования могут несколько отличаться. И к тому же многие запускаемые из строки шелла команды могут иметь свои правила построения регулярных выражений. Так что в итоге их форма определяется сочетанием особенностей конкретной оболочки и команды, из неё запущенной. Все это при необходимости будет оговариваться в дальнейшем.
А пока переходим к рассмотрению командных конструкций — одной из тех особенностей CLI, которая определяет мощь и универсальность этого интерфейса.
Вводные слова о командных конструкциях
Надеюсь, из того, что было рассказано на предшествующих страницах, посвящённых CLI, читателю стало ясно, что подавляющее большинство команд в POSIX-системах очень просты по сути и предназначены для выполнения какого-либо одного элементарного действия.
То есть команда cp умеет только копировать файлы, команда rm — только удалять их, но зато делают они это хорошо. Подчас — через чур хорошо, что мог ощутить на себе каждый, кому «посчастливилось» по ошибке выдать директиву вроде
Для тех, кто не испытал этого волнительного ощущения, поясню: результатом будет полное и безвозвратное уничтожение всех файлов от текущего каталога вниз (включая подкаталоги любой степени вложенности).
А если задать ту же команду от лица администратора, то, в зависимости от текущего положения на файловом древе, можно нечувствительно удалить что угодно, вплоть до системы целиком: одна из причине, почему повседневные действия не следует выполнять под root'ом.
Собственно, разделение любой задачи на серию элементарных операций — это и есть основной принцип работы в POSIX-системах, тот самый пресловутый Unix-way, о котором столько говорят его приверженцы.
Однако вслед за этапом решительного размежевания (эх, неистребимы в памяти нашего поколения слова товарища Ленина) должен наступить этап объединения, как за анализом явления следует синтез эмпирических данных о нём. И целям такого объединения служат командные конструкции.
Командные конструкции — очень важный компонент интерфейса командной строки. Они позволяют объединять несколько команд воедино и выполнять различные команды последовательно или параллельно. Для этого служат специальные символы — операторы: фонового режима, объединения, перенаправления и конвейеризации.
Совместное выполнение команд
Простейшая командная конструкция — это выполнение команды в фоновом режиме, что вызывается вводом символа амперсанда после списка опций и (или аргументов):
В Bash и Zsh пробел перед символом амперсанда не обязателен, но в некоторых шеллах он требуется, и потому лучше возвести его ввод (как и во всех аналогичных случаях) в ранг привычки. После этого возвращается приглашение командной строки и возможен ввод любых других команд (в том числе и фоновых). Команды для параллельного исполнения можно задать и в той же строке:
В результате все команды, перечисленные в строке, кроме той, что указана последней, будут выполняться в фоновом режиме.
Существуют и конструкции для последовательного выполнения команд. Так, если ряд команд разделен в строке символом точки с запятой ( ; )
то сначала будет выполнена команда command1 , затем — command1 и так далее. Молчаливо предполагается, что каждая из этих команд может иметь любое количество опций и аргументов. И, опять-таки, обрамление ; пробелами не обязательно во многих командных оболочках. Сами по себе команды не обязаны быть связанными между собой каким-либо образом — в сущности, это просто эквивалент последовательного их ввода в командной строке:
и так далее. При этом первая команда может, например, копировать файлы, вторая — осуществлять поиск, третья — выполнять сортировку, или другие действия. Очевидно, что в общем случае выполнение последующей команды не зависит от результатов работы предшествующей.
Однако возможна ситуация, когда результаты предыдущей команды из такой конструкции используются в команде последующей. В этом случае ошибка исполнения любой составляющей команды, кроме последней, делает невозможным продолжение работы всей конструкции. Что само по себе было бы ещё полбеды — однако в некоторых ситуациях исполнение последующей команды возможно только при условии успешного завершения предыдущей.
Характерный пример — сборка программы из ее исходных текстов, включающая три стадии — конфигурирование, собственно компиляцию и установку собранных компонентов. Что обычно выполняется последовательностью из трёх команд:
Ясно, что если конфигурирование завершилось ошибкой, то компиляция начаться не сможет и, соответственно, потом нечего будет устанавливать. И потому объединение их в последовательную конструкцию вида
может оказаться нецелесообразным.
Однако для предотвращения таких ситуаций в конструкции из взаимосвязанных команд существует другой оператор, обозначаемый удвоенным символом амперсанда — &&. Он указывает, что последующая команда конструкции должна исполняться только в том случае, если предыдущая завершилась успешно:
На практике обе приведённые в качестве примера конструкции дадут один и тот же результат — разумеется, если все составляющие их команды будут выполнены без ошибок. Однако в ряде иных случаев различие между этими конструкциями может быть существенным.
Впрочем, предусмотрена и командная конструкция, в которой последующей команде предписано исполняться в том и только в том случае, если предыдущая команда завершилась неудачно. Она имеет вид
и может служить, в частности, для вывода сообщений об ошибках.
Перенаправление
Следующая командная конструкция — это так называемое перенаправление ввода/вывода. Чтобы понять,что это такое, нужно помнить две вещи:
любая команда получает данные для своей работы (например, список опций и аргументов) со стандартного устройства ввода (которым в первом приближении будем считать клавиатуру), а результаты своей работы представляет на стандартном устройстве вывода (коим договоримся считать экран монитора);
POSIX-системах любое устройство — не более чем имя специального файла, именуемого файлом устройства.
Таким образом, ничто не запрещает нам подменить специальный файл устройства ввода или устройства вывода любым иным файлом (например, обычным текстовым). Откуда и будут в этом случае браться входные данные или куда будет записываться вывод команды.
Перенаправление вывода команды обозначается следующим образом:
В первом случае (одиночный символ > ) вывод команды command образует содержимое нового файла с именем filename , не появляясь на экране. Или, если файл с этим именем существовал ранее, то его содержимое подменяется выходным потоком команды (точно также, как при копировании одного файла в другой, уже существующий). Почему такое перенаправление называется замещающим (или перенаправлением в режиме замещёния).
Во втором же случае (двойной символ >> ) происходит добавление вывода команды command в конец существующего файла filename (при отсутствии же его в большинстве случаев просто образуется новый файл). И потому это называется присоединяющим перенаправлением, или перенаправлением в режиме присоединения.
Перенаправление ввода выглядит так:
Простейший случай перенаправления вывода — сохранение результата исполнения команды в обычном текстовом файле. Например, конструкция
создаст файл, содержанием которого будет список файлов каталога dir1 . А в результате выполнения конструкции
к этому списку добавится и содержимое каталога dir2 .
При перенаправлении ввода команда получает данные для своей работы из входящего в командную конструкцию файла. Например, конструкция
выведет на экран строки файла list , отсортированных в порядке возрастания значения ASCII-кода первого символа, а конструкция
осуществит сортировку строк того же файла в порядке, обратном алфавитному (вернее, обратном порядку кодов символов, но это нас в данном случае не волнует).
В одной конструкции могут сочетаться перенаправления ввода и вывода, как в режиме замещёния, так и в режиме присоединения. Так, конструкция
не только выполнит сортировку строк файла list (это — назначение команды sort ) в обратном алфавитному порядке (что предписывается опцией -r , происходящей в данном случае от reverce), но и запишет ее результаты в новый файл list_r , а конструкция
добавит по-новому отсортированный список в конец существующего файла list .
Конвейеры
Возможности построения командных конструкций не ограничиваются перенаправлением ввода/вывода: результаты работы одной команды могут быть переданы для обработки другой команде. Это достигается благодаря механизму программных каналов (pipe) или конвейеров — последний термин лучше отражает существо дела.
При конвейеризации команд стандартный вывод первой команды передается не в файл, а на стандартный ввод следующей команды. Простой пример такой операции — просмотр списка файлов:
Перенаправление вывода команды ls , то есть списка файлов, который при использовании полного формата записи (опция -l ) может занимать многие экраны, на ввод команды less позволяет просматривать результат с ее помощью постранично или построчно в обоих направлениях.
Конвейеризация команд может быть сколь угодно длинной. Возможно также объединение конвейеризации команд и перенаправления в одной конструкции. Кроме того, команды в конструкции могут быть сгруппированы с тем, чтобы они выполнялись как единое целое. Для этого группа команд разделяется символами ; и пробелами, как при последовательном выполнении команд, и заключается в фигурные скобки. Так, если нам требуется перенаправить вывод нескольких команд в один и тот же файл, вместо неуклюжей последовательности типа
можно прибегнут к более изящной конструкции:
Как и многие из ранее приведённых примеров, этот может показаться надуманным. Однако представьте, что вам нужно создать полный список файлов вашего домашнего каталога, разбитый по подкаталогам, да ещё и с комментариями, в каком подкаталоге что находится. Конечно, можно вывести состав каждого подкаталога командой ls , слить их воедино командой cat (она предназначена, в частности, и для объединения — конкатенации, — файлов, и речь о ней будет позже), загрузить получившееся хозяйство в текстовый редактор или ворд-процессор, где добавить необходимые словеса. А можно — обойтись единой конструкцией:
И в результате получить файл такого (условно) содержания, которое мы для разнообразия просмотрим с помощью только что упомянутой команды cat (благо и для просмотра содержимого файлов она также пригодна):
Понятие о фильтрах
С понятием командных конструкций тесно связано понятие программ-фильтров. Это — команды, способные принимать на свой ввод данные с вывода других команд, производить над ними некоторые действия и перенаправлять свой вывод (то есть результат модификации полученных данных) в файлы или далее по конвейеру — другой команде.
Программы-фильтры — очень эффективное средство обработки текстов, и в своё время мы к ним вернемся для подробного изучения. Пока же важно отметить, что в качестве фильтров могут работать не все команды. Например, команды find или grep фильтруют имена файлов или фрагменты их содержимого, а команда ls фильтром не является.
Сценарии оболочки
Наш затянувшийся разговор о командах и командном интерфейсе подходит к концу. И в заключение этого раздела — ещё немного терпения. Потому что было бы несправедливо не уделить чуть-чуть места тому, что придает командному интерфейсу POSIX-систем его несравненную гибкость и универсальность. Заодно способствуя закоснению пользователя в смертном грехе лености. Итак — слово о сценариях оболочки.
В самом начале я обмолвился, что шелл — это не просто среда для ввода единичных команд и командных конструкций, но и ещё интерпретатор собственного языка программирования. Так вот, сценарии оболочки, именуемые также скриптами, — это и есть программы, написанные на этом языке.
Только не заподозрите меня в гнусном намерении учить вас программерству. Господь борони, и в мыслях не держал (тем паче, что и сам-то этим ремеслом не владею в должной для обучения других степени). Нет, просто на последующих страницах нам то и дело придётся рассматривать кое-какие примеры готовых сценариев, а подчас и пытаться создавать их собственноручно. Ибо занятие это в элементарном исполнении навыков программирования не требует вообще.
В самом простом случае сценарий — это просто одна или несколько команд или (и) командных конструкций с необходимыми опциями и аргументами, сохраненные в виде обычного именованного текстового файла. И предназначены они в первую очередь для автоматизации часто исполняемых рутинных операций, в частности, ввода длинных последовательностей в командной строке.
Создание пользовательского сценария — просто, как правда. Для этого всего и нужно:
- создать командную конструкцию, достойную увековечивания;
- поместить ее в простой текстовый файл;
- по потребности и желанию снабдить комментариями;
- тем или иным способом запустить файл на исполнение.
С принципами создания команд и командных конструкций мы в первом приближении разобрались раньше. А вот способов помещёния их в файл существует множество. Можно просто ввести (или вызвать из буфера истории) нужную команду и оформить ее как аргумент команды echo, вывод которой перенаправить в файл:
Таким образом мы получили простейший скрипт для копирования файлов из рабочего каталога в каталог для резервного хранения данных, что впредь и будем проделывать регулярно (не так ли?).
Аналогичную процедуру можно выполнить с помощью команды cat — она, оказывается, способна не только к объединению файлов и выводу их содержимого, но и к вводу в файл каких-либо данных. Делается это так. Вызываем cat с перенаправлением ее вывода в файл:
и нажимаем Enter . После этого команда остается в ожидании ввода данных для помещёния их в новообразованный файл. Не обманем ее ожиданий и проделаем это. причём можно не жаться и выполнить ввод в несколько строк, например:
Завершив ввод тела скрипта, все той же клавишей Enter открываем новую строку и набираем комбинацию Control+D , выдающую символ окончания файла.
В результате получаем сценарий для архивирования в специально предназначенном для этого каталоге archivedir наших рабочих данных (командой tar), а заодно и их компрессии (командой gzip ) — в Unix, в отличие от DOS/Windows, архивирование и компрессия обычно рассматриваются как разные процедуры.
Наконец, сценарий можно создать в любом текстовом редакторе. но это не так интересно — по крайней мере, пока. Да и стоит ли вызывать редактор ради двух-трёх строк?
Комментариями в шелл-сценариях считаются любые строки, начинающиеся с символа решетки ( # ) — они не учитываются интерпретатором и не принимаются к исполнению. Хотя комментарий может быть начат и внутри строки — важно только, что между символом # и концом её больше ничего не было бы. Ясно, что комментарии — элемент для скрипта не обязательный, но очень желательный. Хотя бы для того, чтобы не забыть, ради чего этот сценарий создавался.
Но одна строка, начинающаяся символом решётки, в сценарии практически обязательна. И должна она быть первой и выглядеть следующим образом:
В данном случае восклицательный знак подчеркивает, что предваряющий его символ решетки ( # ) — не комментарий, а указание (т.н. sha-bang) на точный абсолютный путь к исполняемому файлу оболочки, для которой наш сценарий предназначен, например,
для POSIX-шелла, или
для оболочки Bash. Здесь следует подчеркнуть, что шелл, для которого предназначается сценарий, отнюдь не обязан совпадать с командной оболочкой пользователя. И полноты картины для замечу, что указание точного имени интерпретатора требуется не только для шелл-скриптов, но и для программ на любых языках сценариев (типа Perl или Python).
Так что по хорошему в обоих приведенных выше примерах ввод команд сценария следовало бы предварить строкой sha-bang. Конечно, отсутствие имени командной оболочки в явном виде обычно не помешает исполнению шелл-сценария: для этого будет вызван системный командный интерпретатор по умолчанию — в Mint /bin/dash . Однако если сценарий предназначен для другой командной оболочки, то без sha-bang он может исполняться неправильно (или не исполняться вообще).
Теперь остается только выполнить наш сценарий. Сделать это можно разными способами. Самый напрашивающийся — непосредственно вызвать требуемый шелл как обычную команду, снабдив его аргументом — именем сценария (предположим, что он находится в текущем каталоге):
Далее, для вызова скриптов существует специальная встроенная команда оболочки, обозначаемая символом точки. Используется она аналогично:
с тем только исключением, что тут требуется указание текущего каталога в явном виде (что и символизируется ./ ).
Однако наиболее употребимый способ запуска сценариев — это присвоение его файлу так называемого атрибута исполнения. Эта процедура волшебным образом превращает невзрачный текстовый файлишко во всамделишную (хотя и очень простую) программу.
Так вот, после присвоения нашему сценарию бита исполнения запустить его можно точно также, как любую другую команду — просто из командной строки:
Опять же — в предположении, что сценарий находится в текущем каталоге ( ./ ), иначе потребуется указание полного пути к нему. Что, понятно, лениво, но решается раз и навсегда: все сценарии помещаются в специально отведенный для этого каталог (например, $HOME/bin ), который и добавляется в качестве ещё одного значения переменной PATH данного пользователя.
Понятие о функциях
И уж совсем в заключение этого раздела осталось сказать пару слов о функциях командной оболочки. Это — такая же последовательность команд (или даже просто одиночная команда), как и сценарий, но — не вынесенная в отдельный исполняемый файл, а помещённая в тело другого скрипта. В коем она опознаётся по имени, и может быть выполнена неоднократно в ходе работы этого скрипта.
Главное отличие функции от сценария — в том, что она выполняется в том же процессе (и, соответственно, экземпляре шелла), что и заключающий её сценарий. Тогда как для каждого скрипта, вызываемого из другого сценария, создаётся отдельный процесс, порождающий собственный экземпляр шелла. Это может быть важным, если в сценарии определяются некоторые переменные, которые имеют силу только в нём самом.
Функции не обязательно помещаются внутрь сценария — их можно собрать в некоторые отдельные файлы, которые именуются библиотеками функций и могут быть использованы по мере надобности.
Ранее на протяжении всего повествования неоднократно упоминались (и будут упоминаться впредь) системные библиотеки, в частности, главная библиотека glibc . Так вот, это — точно такие же сборники функций, правда, не командной оболочки, а языка Си, и, соответственно, хранящиеся не в виде текстовых файлов, а в бинарном, откомпилированном, виде.
Настройка шелла
Во всех дистрибутивах Linux в качестве пользовательской командной оболочки по умолчанию выступает Bash, и Mint здесь не исключение. Так что, хотя автор этих строк не является ни её любителем, ни, тем более, знатоком, совсем обойти её вниманиемне мог. Так что ниже даётся мини-очерк настройки этого шелла.
Оболочка Bash поддерживает все интерактивные возможности, столь важные для пользователя, как то: автодополнение для команд и путей к файлам, историю оных (включая средства инкрементного поиска), мощные возможности навигации и редактирования командной строки.
Важно, что существует дополнительный пакет bash-completion: установка его обогащает базовую оболочку множеством опциональных средств настройки автодополнения (в том числе и для командных аргументов). Правда, чтобы эта дополненная оболочка была по настоящему удобной и функциональной, нужно приложить некоторые усилия по её настройке, чем мы сейчас и займёмся.
Схема настройки bash предусматривает наличие пары файлов /etc/profile и /etc/bashrc (для логин-шелла и просто интерактивного его экземпляра), а также соответствующих им пользовательских конфигов —
/.bashrc . При авторизации первым в любом случае считывается общесистемный профильный файл /etc/profile , вслед за ним — пользовательский профильный файл
/.bash_profile , после чего происходит обращение к
/.bashrc. Файл /etc/profile может занимать особое положение — в него часто помещают переменные окружения (например, локально-зависимые), которые должны быть общими для всех пользователей данной системы. Пользовательские же настройки определяются в файлах
/.bashrc . Обычно в
/.bash_profile определяются переменные окружения, которые должны действовать для всех дочерних процессов, а в
/.bashrc — параметры, всегда требуемые в интерактивном режиме (например, псевдонимы).
Редактирование командной строки в bash обеспечивается отдельным пакетом — библиотекой функций readline . Она имеет собственные конфигурационные файлы, общесистемный /etc/inputrc и пользовательский
Впрочем, в большинстве современных дистрибутивов Linux, ориентированных на графический режим и, следовательно, использование эмулятора терминала с интерактивным шеллом, не являющимся, тем не менее, шеллом пользовательским (login shell),
/.bash_profile играет сугубо служебную роль, и содержимое его сводится к отработке файла
/.bashrc и выполняются при этом все пользовательские настройки.
Большинство настроек Bash по умолчанию разумны, и потому наличные в данном дистрибутиве файлы вполне могут быть взяты за основу. Однако путём некоторых несложных действий их можно дополнить, увеличив удобство интерактивного использования командной оболочки.
По умолчанию в Bash автодополнение клавишей табулятора не работает, например, в аргументах многих команд, таких, как sudo или man .
Решается эта задача очень просто: достаточно файл
/.bashrc внести следующие строки:
После этого автодополнение будет работать буквально везде, где только можно себе представить, например, после набора dpkg —sea и нажатия табулятора получится dpkg —search.
Если в файл /etc/inpurc (или в
/inpurc) добавить такие строки:
то набор части команды, например, cd / , и последующий перебор стрелками <Up> и <Down> истории команд повлечёт извеление из буфера истории только тех из них, которые начинаются на cd / .