Основные команды Linux: почти полное руководство с примерами
Почти любое действие в ОС Linux можно выполнить командой из терминала. В статье разбираемся в базовых командах и их функциях.

Если вы когда-нибудь сталкивались с ОС Linux, вы наверняка слышали слово «терминал». Новички обычно воспринимают терминал как что-то страшное и зловещее. Но не все так страшно.
Введение в терминал Linux
Моя бабушка называет любой терминал «терминатором», что добавляет антуража. На самом деле терминал (bash) — это всего лишь командная строка с гораздо более широким набором функций, если сравнивать с Windows. Почти любое действие можно выполнить командой из терминала, но далеко не любое действие можно выполнить через окружения пользователя.
В этом и заключается преимущество терминала Linux — по сути из него можно полностью управлять системой, без необходимости окружения пользователя (графического интерфейса). На самом деле нередко серверы так и работают — черный экран, командная строка и все функции под рукой. В статье команды будут сгруппированы по функциям, а не по частоте использования, это связано с удобством восприятия и понимания.
Статья рассчитана на новичков и написана таким же новичком, в этом нет ничего зазорного — все когда-то начинали с нуля. Любое сообщество существует только до тех пор, пока есть приток новых участников.
Список команд в данной статье не является полным списком команд Linux. Во-первых, команд слишком много, чтобы перечислять их все, во-вторых, новичкам они не нужны, а профессионалы уже помнят их наизусть. Однако, не стоит расстраиваться, если у вас не получается запомнить команды — запоминание приходит с практикой. Чем чаще вы пользуетесь теми или иными командами, тем скорее вы их запомните.
Облачные базы данных в Selectel
Доверьте нашим специалистам развертывание и поддержку баз данных в облаке.
Основные команды Linux
Если вы проигнорировали введение, напомним, что команды в статье сгруппированы по исполняемой ими функции. Что может быть более необходимым для новичка, чем функция справки?
Команды для получения справки
man — manual, получение справки
Самая первая команда Linux для начинающих — manual — для получения полной справочной информации по другой команде. Некоторые пользователи настаивают, что искать в интернете информацию по команде проще и эффективнее. Однако, информация в интернете не всегда является верной, статья в интернете может быть устаревшей, не релевантной для вашей версии ОС и т.д. Использовать man всегда хорошая идея.
Чтобы получить справку по команде, введите перед ней man. Например, man man выдаст руководство по команде man. Также можно вывести мануал терминала Linux (man bash):
BASH(1) General Commands Manual BASH(1) NAME bash - GNU Bourne-Again SHell SYNOPSIS bash [options] [command_string | file] COPYRIGHT Bash is Copyright (C) 1989-2018 by the Free Software Foundation, Inc. DESCRIPTION Bash is an sh-compatible command language interpreter that executes commands read from the standard input or from a file. Bash also incorporates useful features from the Korn and C shells (ksh and csh). Bash is intended to be a conformant implementation of the Shell and Utilities portion of the IEEE POSIX specification (IEEE Standard 1003.1). Bash can be configured to be POSIX-confor‐ mant by default. OPTIONS All of the single-character shell options documented in the description of the set builtin command, including -o, can be used as options when the shell is invoked. In addition, bash interprets the following options when it is invoked: -c If the -c option is present, then commands are read from the first non-option argu‐ ment command_string. If there are arguments after the command_string, the first ar‐ gument is assigned to $0 and any remaining arguments are assigned to the positional
help — когда не работает man
Не у каждой команды имеется свое полноценное руководство и не всегда оно требуется. В таких случаях помогает help, которая выводит краткую справку.
history: history [-c] [-d смещение] [n] или history -anrw [файл] или history -ps аргумент [аргумент. ] Display or manipulate the history list. Display the history list with line numbers, prefixing each modified entry with a `*'. An argument of N lists only the last N entries. Options: -c clear the history list by deleting all of the entries -d offset delete the history entry at position OFFSET. Negative offsets count back from the end of the history list -a append history lines from this session to the history file -n read all history lines not already read from the history file and append them to the history list -r read the history file and append the contents to the history list -w write the current history to the history file -p perform history expansion on each ARG and display the result without storing it in the history list -s append the ARGs to the history list as a single entry If FILENAME is given, it is used as the history file. Otherwise, if HISTFILE has a value, that is used, else ~/.bash_history. If the HISTTIMEFORMAT variable is set and not null, its value is used as a format string for strftime(3) to print the time stamp associated
Похожий вариант — вывод справки через специальные ключи — -h или —help.
Tab — автозавершение команды
Командная строка Linux может предложить вам доступные варианты завершения команды. Например, если вы хотите узнать, куда можно перейти из текущей папки, наберите cd, затем дважды нажмите Tab. Если хотите узнать, какие папки начинаются с символа точки, введите cd . и завершите двойным нажатием Tab. Работает с любой командой, но только в современных оболочках — bash и zsh.
debtop@DebTop:~$ cd .aptitude/ .gnupg/ .mozilla/ Видео/ Изображения/ Рабочий стол/ .cache/ .kde/ .pki/ Документы/ Музыка/ Шаблоны/ .config/ .local/ snap/ Загрузки/ Общедоступные/ debtop@DebTop:~$ cd . ./ .aptitude/ .config/ .kde/ .mozilla/ ../ .cache/ .gnupg/ .local/ .pki/
cat /etc/*-release — какой дистрибутив установлен на моей машине
Если вы задумывались об установке Linux или уже использовали эту ОС, вы должны были знать, что существует несколько дистрибутивов. В зависимости от дистрибутива команды могут отличаться, поэтому полезно иметь возможность узнать, какой именно дистрибутив на этой машине. Это можно сделать и через информацию о системе, из графического интерфейса окружения пользователя, но наша статья о терминале. Команда cat /etc/*-release (без пробелов) покажет вам основную информацию о дистрибутиве — имя, версия, и т.д. Аналогами в данном случае будут являться lsb_release -a, которая выведет почти ту же информацию, а lsb_release -i напишет ID дистрибутива.
debtop@DebTop:~$ cat /etc/*-release PRETTY_NAME="Debian GNU/Linux 10 (buster)" NAME="Debian GNU/Linux" VERSION_ID="10" VERSION="10 (buster)" VERSION_CODENAME=buster ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" debtop@DebTop:~$ lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 10 (buster) Release: 10 Codename: buster debtop@DebTop:~$ lsb_release -i Distributor ID: Debian
whoami — какой пользователь сейчас используется
Терминал Linux позволяет работать от имени любого пользователя, но не всегда удается удержать в памяти текущего пользователя. Чтобы вспомнить текущего пользователя, существует простая команда whoami.
debtop@DebTop:~$ whoami desktop
whatis — что за программа?
Команда Linux терминала whatis дает краткое описание любой установленной программы.
debtop@DebTop:~$ whatis nano nano (1) - Nano's ANOther editor, an enhanced free Pico clone debtop@DebTop:~$ whatis apt apt (8) - command-line interface debtop@DebTop:~$ whatis krita krita: ничего подходящего не найдено.
Очевидно, что, если программа не установлена, то получить ее описание не получится.
whereis — полный путь к программе
Допустим, вы нашли нужную программу, но хотите попасть в ее директорию. Узнать директорию программы поможет whereis, показывающая полный путь к исполняемому файлу программы.
debtop@DebTop:~$ whereis bash bash: /usr/bin/bash /etc/bash.bashrc /usr/share/man/man1/bash.1.gz
Команды управления сетью
hostname, ifconfig — управление сетью
Эти команды покажут DNS-домен и IP-адрес вашего компьютера.
debtop@DebTop:~$ hostname DebTop debtop@DebTop:~$ hostname -i 127.0.1.1 debtop@DebTop:~$ ifconfig bash: ifconfig: команда не найдена
В некоторых версиях дистрибутивов Linux поддерживается команда ifconfig, которая также выводит текущий IP, но она работает не всегда. Взамен устаревшей ifconfig современные дистрибутивы отзываются на ip a[ddress], которая выведет на экран настройки сети и позволяет их редактировать. Команда является частью пакета утилит для настройки параметров сетевых устройств — iproute2. Команды из набора iproute2 пригодятся системным администраторам или тем, кто хочет создать доменную сеть дома.
debtop@DebTop:~$ ip a 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp4s0: mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1 000 link/ether b4:b5:2f:7f:fe:eb brd ff:ff:ff:ff:ff:ff 3: wlo1: mtu 1500 qdisc mq state UP group default qlen 1000 link/ether a4:17:31:2a:bc:59 brd ff:ff:ff:ff:ff:ff inet 192.168.1.195/24 brd 192.168.1.255 scope global dynamic noprefixroute wlo1 valid_lft 85273sec preferred_lft 85273sec inet6 fe80::3f0f:a837:e4c0:e52d/64 scope link noprefixroute valid_lft forever preferred_lft forever debtop@DebTop:~$ ip Usage: ip [ OPTIONS ] OBJECT < COMMAND | help >ip [ -force ] -batch filename where OBJECT := < link | address | addrlabel | route | rule | neigh | ntable | tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm | netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila | vrf | sr >OPTIONS := < -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] | -h[uman-readable] | -iec | -j[son] | -p[retty] | -f[amily] < inet | inet6 | ipx | dnet | mpls | bridge | link >| -4 | -6 | -I | -D | -M | -B | -0 | -l[oops] < maximum-addr-flush-attempts >| -br[ief] | -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] | -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]>
ping — диагностика неисправностей сети
Ping используют для поиска неисправностей, тестирования и диагностики сетевых соединений. Команда отправляет сообщение на указанный IP адрес и ждет ответ. Когда пакет адресат получает пакет, он отправляет ответ. Таким образом можно определить задержку сообщений или потерю пакетов.
Достаточно ввести, например, ping google.com, компьютер сам определит IP адрес домена и продолжит выполняться, пока ее не отменить сочетанием Ctrl+C.
Команды для управления файлами и директориями
Теперь, когда мы выяснили, где находится терминал, мы можем перейти в его директорию. Однако, этого делать не стоит, иначе можно что-нибудь сломать. Давайте попробуем поработать с директорией песочницы.
mkdir — создание директории
Для начала песочницу необходимо создать. Сделать это очень просто, находясь в домашней директории пользователя введем в bash:
mkdir playpen
Отлично, и что дальше? Точно ли директория создалась?
ls — list, отобразить директории и файлы
Чтобы убедиться в наличии директории нужно набрать ls, после выполнения команда покажет все каталоги и файлы.
debtop@DebTop:~$ mkdir playpen debtop@DebTop:~$ ls playpen Видео Загрузки Музыка 'Рабочий стол' snap Документы Изображения Общедоступные Шаблоны
cd — change directory, сменить директорию
Теперь перейдем в созданную директорию. Для навигации в терминале Linux нужно ввести cd имя_директории. В нашем случае cd playpen.
debtop@DebTop:~$ cd playpen debtop@DebTop:~/playpen$
Если работа в данной директории закончена и необходимо подняться на уровень вверх из текущей директории, используйте «cd пробел .. (две точки)»:
cd ..
А если вы работаете одновременно в двух директориях и периодически перемещаетесь из одной в другую, не нужно постоянно держать в голове, какой же была предыдущая. Достаточно использовать быстрый переход к предыдущей директории «cd пробел — (дефис)»:
cd —
debtop@DebTop:~/playpen/dir00$ cd /usr/lib/x86_64-linux-gnu/audacious debtop@DebTop:/usr/lib/x86_64-linux-gnu/audacious$ cd - /home/debtop/playpen/dir00 debtop@DebTop:~/playpen/dir00$ cd - /usr/lib/x86_64-linux-gnu/audacious debtop@DebTop:/usr/lib/x86_64-linux-gnu/audacious$ cd - /home/debtop/playpen/dir00 debtop@DebTop:~/playpen/dir00$ cd ..
pwd — где я сейчас?
Обратите внимание, как только мы сменили директорию, поменялся и префикс до символа $, так терминал показывает нам, где мы находимся в данный момент. Конечно, терминал не станет отображать полный путь, если он слишком длинный, поэтому не стоит всегда полагаться на префикс. Быстро понять текущую рабочую директорию поможет команда pwd. Расшифровка этой команды простая — три английских слова — Print Working Directory. На самом деле расшифровка команд Linux всегда простая, они все произошли от английских слов, но были сокращены для лучшего запоминания.
Обратно к песочнице. Пока что директория (также каталог, папка) пуста и не содержит ни одного файла. Давайте создадим в ней 43 директории, в каждой по 43 файла. Можно создавать вручную, каждый раз прописывая имя, а можно поступить проще:
mkdir dir
Синтаксис команды простой: mkdir создает директорию, dir задает начальное имя для каждой новой директории, числа в фигурных скобках указывают переменную часть имени создаваемых папок. То есть, команда mkdir test_folder_ создала бы нам 5 папок с начальным именем test_folder_0.
Давайте проверим, создались ли наши тестовые папки — ls.
debtop@DebTop:~/playpen$ ls dir00 dir03 dir06 dir09 dir12 dir15 dir18 dir21 dir24 dir27 dir30 dir33 dir36 dir39 dir42 dir01 dir04 dir07 dir10 dir13 dir16 dir19 dir22 dir25 dir28 dir31 dir34 dir37 dir40 dir02 dir05 dir08 dir11 dir14 dir17 dir20 dir23 dir26 dir29 dir32 dir35 dir38 dir41
Как создать файл?
Замечательно, теперь создадим по 43 файла в каждой. Для создания файла существует более 10 разных способов, самый простой:
> имя_файла
На самом деле >, как и обратный знак < не совсем являются командами, это символы перенаправления или связи. Однако, если перед именем несуществующего файла поставить знак >вместе с указанием расширения файла, в текущей директории появится пустой файл.
Но нам требуется поместить по 42 файла в 42 директории, а терминал Linux откажется воспринимать команду со знаком перенаправления, поэтому используем команду touch. Эта команда позволяет задать время последнего изменения файла или создать новые файлы:
touch dir/text.txt
debtop@DebTop:~/playpen$ touch dir/text.txt debtop@DebTop:~/playpen$ ls dir00 text00.txt text06.txt text12.txt text18.txt text24.txt text30.txt text36.txt text42.txt text01.txt text07.txt text13.txt text19.txt text25.txt text31.txt text37.txt text02.txt text08.txt text14.txt text20.txt text26.txt text32.txt text38.txt text03.txt text09.txt text15.txt text21.txt text27.txt text33.txt text39.txt text04.txt text10.txt text16.txt text22.txt text28.txt text34.txt text40.txt text05.txt text11.txt text17.txt text23.txt text29.txt text35.txt text41.txt
rm — remove, удаление
Чтобы удалить какой-либо файл, достаточно ввести команду rm с именем файла:
rm text00.txt
Можно удалить несколько:
Если попытаться удалить целый каталог по аналогии, то ничего не получится. Все потому, что для удаления каталога нужна другая команда: rmdir:
rmdir delete_me
Команда rmdir тоже не всесильна, она не позволит удалить каталог, в котором есть что-то еще — файл или другой каталог (даже пустой).
Для удаления каталога с содержимым можно использовать команду rm с опцией рекурсивного удаления -r. Обратите внимание на картинку ниже, все описанные переходы по директориям, упомянутые в описании команды cd действуют и для rm. Поэтому, при нахождении в подкаталоге dir01, команда будет выглядеть вот так:
rm -r ../dir03
debtop@DebTop:~/playpen/dir01$ rm text00.txt debtop@DebTop:~/playpen/dir01$ rm text.txt debtop@DebTop:~/playpen/dir01$ mkdir delete_me debtop@DebTop:~/playpen/dir01$ ls delete_me text16.txt text20.txt text24.txt text28.txt text32.txt text36.txt text40.txt text13.txt text17.txt text21.txt text25.txt text29.txt text33.txt text37.txt text41.txt text14.txt text18.txt text22.txt text26.txt text30.txt text34.txt text38.txt text42.txt text15.txt text19.txt text23.txt text27.txt text31.txt text35.txt text39.txt debtop@DebTop:~/playpen/dir01$ rm delete_me rm: невозможно удалить 'delete_me': Это каталог debtop@DebTop:~/playpen/dir01$ rmdir delete_me debtop@DebTop:~/playpen/dir01$ ls text13.txt text17.txt text21.txt text25.txt text29.txt text33.txt text37.txt text41.txt text14.txt text18.txt text22.txt text26.txt text30.txt text34.txt text38.txt text42.txt text15.txt text19.txt text23.txt text27.txt text31.txt text35.txt text39.txt text16.txt text20.txt text24.txt text28.txt text32.txt text36.txt text40.txt debtop@DebTop:~/playpen/dir01$ rmdir ../dir03 rmdir: не удалось удалить '../dir03': Каталог не пуст debtop@DebTop:~/playpen/dir01$ rm -r ../dir03 debtop@DebTop:~/playpen/dir01$ ls .. dir00 dir04 dir07 dir10 dir13 dir16 dir19 dir22 dir25 dir28 dir31 dir34 dir37 dir40 dir01 dir05 dir08 dir11 dir14 dir17 dir20 dir23 dir26 dir29 dir32 dir35 dir38 dir41 dir02 dir06 dir09 dir12 dir15 dir18 dir21 dir24 dir27 dir30 dir33 dir36 dir39 dir42
cp — copy, копирование
Кроме создания и удаления файлов и директорий терминал позволяет их копирование.
Снова перейдем в директорию dir02 и скопируем файл text00.txt в директорию dir01:
cp text00.txt /home/debtop/playpen/dir01
Поскольку text00.txt находится в текущей директории, до него можно не писать полный путь. Такое указание пути называется относительным. Путь до dir01 мы указали полностью, от домашней директории, такой путь называется абсолютный. Можно было указать просто ../dir01, тогда это был бы снова относительный путь.
Если попробовать повторить копирование теперь, когда в dir01 опять появился файл text00.txt, внешне не произойдет ничего, но на самом деле файл будет заменен на файл с тем же именем без каких-либо вопросов.
debtop@DebTop:~/playpen/dir01$ cd ../dir02 debtop@DebTop:~/playpen/dir02$ cp text00.txt home/debtop/playpen/dir01 cp: невозможно создать обычный файл 'home/debtop/playpen/dir01': Нет такого файла или каталога debtop@DebTop:~/playpen/dir02$ cp text00.txt /home/debtop/playpen/dir01 debtop@DebTop:~/playpen/dir02$ ls ../dir01 text00.txt text16.txt text20.txt text24.txt text28.txt text32.txt text36.txt text40.txt text13.txt text17.txt text21.txt text25.txt text29.txt text33.txt text37.txt text41.txt text14.txt text18.txt text22.txt text26.txt text30.txt text34.txt text38.txt text42.txt text15.txt text19.txt text23.txt text27.txt text31.txt text35.txt text39.txt
Каталоги копируются по тому же принципу, только нужно не забывать про добавление опции рекурсивного копирования:
cp -r dir00 dir03
debtop@DebTop:~/playpen$ ls dir00 dir04 dir07 dir10 dir13 dir16 dir19 dir22 dir25 dir28 dir31 dir34 dir37 dir40 dir01 dir05 dir08 dir11 dir14 dir17 dir20 dir23 dir26 dir29 dir32 dir35 dir38 dir41 dir02 dir06 dir09 dir12 dir15 dir18 dir21 dir24 dir27 dir30 dir33 dir36 dir39 dir42 debtop@DebTop:~/playpen$ cp dir00 dir03 cp: не указан -r; пропускается каталог 'dir00' debtop@DebTop:~/playpen$ cp -r dir00 dir03 debtop@DebTop:~/playpen$ cp -r dir00 dir03/ debtop@DebTop:~/playpen$ cd dir03 debtop@DebTop:~/playpen/dir03$ ls dir00 text05.txt text11.txt text17.txt text23.txt text29.txt text35.txt text41.txt text00.txt text06.txt text12.txt text18.txt text24.txt text30.txt text36.txt text42.txt text01.txt text07.txt text13.txt text19.txt text25.txt text31.txt text37.txt text02.txt text08.txt text14.txt text20.txt text26.txt text32.txt text38.txt text03.txt text09.txt text15.txt text21.txt text27.txt text33.txt text39.txt text04.txt text10.txt text16.txt text22.txt text28.txt text34.txt text40.txt
Если при копировании каталога или файла в качестве адреса копирования указать имя несуществующей директории (или файла), то система автоматически воспримет это как команду создать файл или каталог с таким именем.
Когда вы хотите скопировать не всю директорию целиком, а только ее содержимое, укажите слэш после места назначения, а после него поставьте звездочку (*):
cp -r dir00/* dir03/dir
Принцип действия команд rm и cp очень простой и очевидный, но не стоит забывать, что новичку многое кажется сложнее, чем есть на самом деле.
mv, move — перемещение
Третья команда для управления файлами — mv — перемещает файлы и директории.
Принцип действия полностью аналогичен предыдущим двум командам:
mv что_перемещаем куда_перемещаем
debtop@DebTop:~/playpen$ mv dir16 dir19/dir debtop@DebTop:~/playpen$ ls dir19 dir text05.txt text11.txt text17.txt text23.txt text29.txt text35.txt text41.txt text00.txt text06.txt text12.txt text18.txt text24.txt text30.txt text36.txt text42.txt text01.txt text07.txt text13.txt text19.txt text25.txt text31.txt text37.txt text02.txt text08.txt text14.txt text20.txt text26.txt text32.txt text38.txt text03.txt text09.txt text15.txt text21.txt text27.txt text33.txt text39.txt text04.txt text10.txt text16.txt text22.txt text28.txt text34.txt text40.txt
При перемещении каталогов мы перемещаем их целиком так, что они перестают существовать в исходном местоположении. То есть, каталог dir16 из предыдущего примера больше не существует в каталоге ~/playpen. Но это не всегда удобно, бывает необходимо переместить не сам каталог, а только содержимое — все файлы, каталоги и файлы, вложенные в них. Для этого используется опция —v[erbose], покажем на примере. Переместим все содержимое папки dir19 в папку dir17 командой mv, оставив папку dir19 пустой:
mv -v dir19/* dir17/
debtop@DebTop:~/playpen$ ls dir00 dir04 dir08 dir12 dir17 dir21 dir25 dir29 dir33 dir37 dir41 dir01 dir05 dir09 dir13 dir18 dir22 dir26 dir30 dir34 dir38 dir42 dir02 dir06 dir10 dir14 dir19 dir23 dir27 dir31 dir35 dir39 dir03 dir07 dir11 dir15 dir20 dir24 dir28 dir32 dir36 dir40 debtop@DebTop:~/playpen$ man mv debtop@DebTop:~/playpen$ ls dir19 dir text05.txt text11.txt text17.txt text23.txt text29.txt text35.txt text41.txt text00.txt text06.txt text12.txt text18.txt text24.txt text30.txt text36.txt text42.txt text01.txt text07.txt text13.txt text19.txt text25.txt text31.txt text37.txt text02.txt text08.txt text14.txt text20.txt text26.txt text32.txt text38.txt text03.txt text09.txt text15.txt text21.txt text27.txt text33.txt text39.txt text04.txt text10.txt text16.txt text22.txt text28.txt text34.txt text40.txt debtop@DebTop:~/playpen$ mv -v dir19/* dir17/ переименован 'dir19/dir' -> 'dir17/dir' переименован 'dir19/text00.txt' -> 'dir17/text00.txt' переименован 'dir19/text01.txt' -> 'dir17/text01.txt' переименован 'dir19/text02.txt' -> 'dir17/text02.txt' переименован 'dir19/text03.txt' -> 'dir17/text03.txt' переименован 'dir19/text40.txt' -> 'dir17/text40.txt' переименован 'dir19/text41.txt' -> 'dir17/text41.txt' переименован 'dir19/text42.txt' -> 'dir17/text42.txt' debtop@DebTop:~/playpen$ ls dir00 dir04 dir08 dir12 dir17 dir21 dir25 dir29 dir33 dir37 dir41 dir01 dir05 dir09 dir13 dir18 dir22 dir26 dir30 dir34 dir38 dir42 dir02 dir06 dir10 dir14 dir19 dir23 dir27 dir31 dir35 dir39 dir03 dir07 dir11 dir15 dir20 dir24 dir28 dir32 dir36 dir40 debtop@DebTop:~/playpen$ ls dir19 debtop@DebTop:~/playpen$ ls dir17 dir text05.txt text11.txt text17.txt text23.txt text29.txt text35.txt text41.txt text00.txt text06.txt text12.txt text18.txt text24.txt text30.txt text36.txt text42.txt text01.txt text07.txt text13.txt text19.txt text25.txt text31.txt text37.txt text02.txt text08.txt text14.txt text20.txt text26.txt text32.txt text38.txt text03.txt text09.txt text15.txt text21.txt text27.txt text33.txt text39.txt text04.txt text10.txt text16.txt text22.txt text28.txt text34.txt text40.txt
Глубина вложенности
Можно пойти дальше — создать папку с большой вложенностью dir18 и переместить только файлы первого уровня в папку dir19:
find dir18/ -maxdepth 1 -type f -print0 | xargs -0 mv -t dir19
Эта сложная команда найдет (find) все файлы (-type f) с глубиной вложенности 1 (-maxdepth 1) внутри dir18 и переместит их в dir19 как обычные файлы (mv -t). Часть «xargs -0» служит в роли команды, связующей две других и позволяет им работать вместе. С глубиной вложенности -maxdepth можно экспериментировать, задавать ей разные значения (1, 2, 3 и т.д.) получая новый результат каждый раз.
Команды для архивирования
Важный аспект работы с файлами — возможность создавать архивы. В Linuxе это реализовано с помощью утилит терминала. Рассмотрим несколько базовых команд архивирования:
- gzip — создать архив. Работает следующим образом: gzip файл.расширение. Можно сразу несколько, например, gzip text12.txt text13.txt.
debtop@DebTop:~/playpen$ cd dir00 debtop@DebTop:~/playpen/dir00$ gzip text14.txt debtop@DebTop:~/playpen/dir00$ ls text00.txt text07.txt text14.txt.gz text21.txt text28.txt text35.txt text42.txt text01.txt text08.txt text15.txt text22.txt text29.txt text36.txt text02.txt text09.txt text16.txt text23.txt text30.txt text37.txt text03.txt text10.txt text17.txt text24.txt text31.txt text38.txt text04.txt text11.txt text18.txt text25.txt text32.txt text39.txt text05.txt text12.txt text19.txt text26.txt text33.txt text40.txt text06.txt text13.txt text20.txt text27.txt text34.txt text41.txt
- gunzip — распаковать архив — gunzip файл.расширение.gz.
debtop@DebTop:~/playpen/dir00$ ls text00.txt text07.txt text14.txt.gz text21.txt text28.txt text35.txt text42.txt text01.txt text08.txt text15.txt text22.txt text29.txt text36.txt text02.txt text09.txt text16.txt text23.txt text30.txt text37.txt text03.txt text10.txt text17.txt text24.txt text31.txt text38.txt text04.txt text11.txt text18.txt text25.txt text32.txt text39.txt text05.txt text12.txt text19.txt text26.txt text33.txt text40.txt text06.txt text13.txt text20.txt text27.txt text34.txt text41.txt debtop@DebTop:~/playpen/dir00$ gunzip text14.txt.gz debtop@DebTop:~/playpen/dir00$ ls text00.txt text06.txt text12.txt text18.txt text24.txt text30.txt text36.txt text42.txt text01.txt text07.txt text13.txt text19.txt text25.txt text31.txt text37.txt text02.txt text08.txt text14.txt text20.txt text26.txt text32.txt text38.txt text03.txt text09.txt text15.txt text21.txt text27.txt text33.txt text39.txt text04.txt text10.txt text16.txt text22.txt text28.txt text34.txt text40.txt text05.txt text11.txt text17.txt text23.txt text29.txt text35.txt text41.txt
- zip — более привычный формат архива. Чтобы передать файл на другую операционную систему, и чтобы адресат мог его распаковать лучше использовать утилиту zip.
Утилита zip терминала Linux позволяет упаковать сразу несколько файлов в один архив (gzip также позволяет поместить несколько файлов в архив, но с ней сложнее разобраться) с помощью рекурсивной опции -r. Текст команды Linux:
zip -r texts.zip text12.txt text13.txt
В данном случае texts.zip будет названием архива, а text12.txt и text13.txt — файлы, которые нужно поместить в архив.
debtop@DebTop:~/playpen/dir00$ zip -r texts.zip text12.txt text13.txt adding: text12.txt (stored 0%) adding: text13.txt (stored 0%) debtop@DebTop:~/playpen/dir00$ ls text00.txt text06.txt text12.txt text18.txt text24.txt text30.txt text36.txt text42.txt text01.txt text07.txt text13.txt text19.txt text25.txt text31.txt text37.txt texts.zip text02.txt text08.txt text14.txt text20.txt text26.txt text32.txt text38.txt text03.txt text09.txt text15.txt text21.txt text27.txt text33.txt text39.txt text04.txt text10.txt text16.txt text22.txt text28.txt text34.txt text40.txt text05.txt text11.txt text17.txt text23.txt text29.txt text35.txt text41.txt
- tar — создание резервных копий. Утилита tar создает архивы с расширением .tar, утилиту обычно используют для резервного копирования так как она не сжимает файлы, а только собирает в архив. Чтобы создать архив .tar, выполните команду с опциями —cvf. Например:
tar -cvf newark.tar text07.txt ../dir22
Создаст архив с именем newark.tar, в который будут помещены файл text.07.txt и все файлы из каталога dir22, располагающегося внутри родительского каталога.
Для просмотра содержимого .tar архива используются опции -tvf:
tar -tvf newark.tar
debtop@DebTop:~/playpen/dir00$ tar -cvf newark.tar text07.txt ../dir22 text07.txt tar: Удаляется начальный `../' из имен объектов ../dir22/ ../dir22/text04.txt tar: Удаляются начальные `../' из целей жестких ссылок ../dir22/text07.txt ../dir22/text40.txt ../dir22/text08.txt ../dir22/text32.txt ../dir22/text28.txt ../dir22/text26.txt ../dir22/text11.txt ../dir22/text25.txt debtop@DebTop:~/playpen/dir00$ tar -tvf newark.tar -rw-r--r-- debtop/debtop 0 2020-11-25 13:44 text07.txt drwxr-xr-x debtop/debtop 0 2020-11-25 13:44 dir22/ -rw-r--r-- debtop/debtop 0 2020-11-25 13:44 dir22/text04.txt -rw-r--r-- debtop/debtop 0 2020-11-25 13:44 dir22/text07.txt -rw-r--r-- debtop/debtop 0 2020-11-25 13:44 dir22/text40.txt -rw-r--r-- debtop/debtop 0 2020-11-25 13:44 dir22/text08.txt -rw-r--r-- debtop/debtop 0 2020-11-25 13:44 dir22/text32.txt -rw-r--r-- debtop/debtop 0 2020-11-25 13:44 dir22/text28.txt -rw-r--r-- debtop/debtop 0 2020-11-25 13:44 dir22/text26.txt -rw-r--r-- debtop/debtop 0 2020-11-25 13:44 dir22/text11.txt -rw-r--r-- debtop/debtop 0 2020-11-25 13:44 dir22/text25.txt
Опции для распаковки .tar архива -xvf:
tar -xvf newark.tar
-rw-r--r-- debtop/debtop 0 2020-11-25 13:44 dir22/text27.txt -rw-r--r-- debtop/debtop 0 2020-11-25 13:44 dir22/text39.txt hrw-r--r-- debtop/debtop 0 2020-11-25 13:44 text07.txt ссылка на text07.txt debtop@DebTop:~/playpen/dir00$ ls arch.tar text05.txt text11.txt text17.txt text23.txt newark.tar text35.txt text41.txt dir00 text06.txt text12.txt text18.txt text24.txt scrolls.tar text36.txt text42.txt text01.txt text07.txt text13.txt text19.txt text25.txt text31.txt text37.txt text02.txt text08.txt text14.txt text20.txt text26.txt text32.txt text38.txt text03.txt text09.txt text15.txt text21.txt text27.txt text33.txt text39.txt text04.txt text10.txt text16.txt text22.txt text28.txt text34.txt text40.txt texts.zip
После выполнения в текущий каталог будут скопированы все файлы из архива, но архив не будет удален. Удалить его можно, выполнив rm.
Команды для работы с текстом
Nano, Vim — редактирование текстовых файлов
Как посмотреть содержимое файла в Linux терминале? Через утилиты терминала Linux часто требуется открыть или отредактировать текстовые файлы. Для этого перейдем в директорию dir42 и откроем text42.txt с помощью Nano — простого текстового редактора.
nano text42.txt
Запишем текст в файле, затем сохраним его сочетанием Ctrl+O (^ в терминале Linux всегда значит Ctrl) и выйдем сочетанием Ctrl+X. Nano позволяет редактировать файлы прямо из окна терминала, обладает базовым, но не очень богатым набором функций. Кроме Nano есть еще более продвинутый Vim, который открывает гораздо большие возможности редактирования файлов. Только Vim не всегда установлен в систему и из него сложнее выйти, потому что он не отображает подсказки. Для выхода из Vim используйте :q, для выхода без сохранения изменений — :q! и :w для сохранения всех изменений. Обязательно сначала использовать двоеточие, так как оно активирует командный режим.
grep — поиск
Чтобы найти текст в файле используйте grep, эта команда выведет соответствующие запросу строки текста. Можно искать словом, строкой или регулярным выражением, а вывод может быть файлом или папкой, совпадающим или наоборот — несовпадающим. Полезно использовать grep при поиске по большим логам.
Кроме непосредственно grep есть варианты pgrep, fgrep, egrep, которые выполняют ту же функцию, но для других целей. Часто grep используют в сочетании с другими командами, чтобы упростить работу с большими объемами данных, ниже мы еще увидим примеры такого использования.
head, tail — начало и конец текста
Команды head и tail используются для вывода первых и последних строк текста в одном или нескольких документах.
head/tail опции файл
По умолчанию команды выводят 10 строк текста, но количество можно изменить с помощью опции -n. Специально для эксперимента мы создали большой текстовый файл, из которого хотим получить ровно 1 первую или последнюю большую строку:
head -n 1 text00.txt
tail -n 1 text00.txt
debtop@DebTop:~/playpen/dir00$ head -n 1 text00.txt Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ut lacus ut justo blandit mattis . Sed magna elit, pharetra ac nulla eu, vulputate elementum ex. Donec porta sapien at dui males uada, quis pretium neque volutpat. Aliquam a tincidunt mi. Nunc posuere vehicula velit, sed int erdum lorem ullamcorper at. Aliquam finibus ultrices metus pharetra elementum. Aliquam erat vol utpat. In sit amet sapien commodo dolor feugiat sodales at vitae turpis. Donec ullamcorper dolo r quis lacus tempor, ac aliquet sem consectetur. Duis nec dignissim ligula. Sed gravida sed arc u quis commodo. Aliquam vestibulum nunc sed viverra imperdiet. Suspendisse accumsan sollicitudi n ex, interdum facilisis eros efficitur non. debtop@DebTop:~/playpen/dir00$ tail -n 1 text00.txt Aenean non ullamcorper diam. Ut iaculis vehicula libero sit amet elementum. Nullam ipsum metus, molestie vehicula dui in, tempus finibus nisl. In hac habitasse platea dictumst. In vehicula v elit nec massa porttitor finibus. Nulla libero justo, egestas vitae fringilla ut, gravida eu ri sus. Ut eget risus erat. Aenean interdum pretium semper. Aliquam vehicula dolor non augue lacin ia sodales. Morbi molestie massa sed enim placerat, id euismod odio condimentum. Nunc aliquet l acinia lacus, quis mattis tortor viverra sed. Vestibulum ullamcorper aliquet nibh, nec lacinia nunc tincidunt fringilla. Mauris sollicitudin nec lectus eget mollis. Aliquam eu accumsan nulla.
С помощью опции -c можно запросить уже не строки, а байты.
Например, команды для получения 100 байт текста:
head -с 100 text00.txt
debtop@DebTop:~/playpen/dir00$ tail -c 100 text00.txt ia nunc tincidunt fringilla. Mauris sollicitudin nec lectus eget mollis. Aliquam eu accumsan nulla. debtop@DebTop:~/playpen/dir00$ head -c 100 text00.txt Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ut lacus ut justo blandit mattis. Sed
tail -с 100 text00.txt
Другие опции можно посмотреть через man head.
HEAD(1) User Commands HEAD(1) NAME head - output the first part of files SYNOPSIS head [OPTION]. [FILE]. DESCRIPTION Print the first 10 lines of each FILE to standard output. With more than one FILE, precede each with a header giving the file name. With no FILE, or when FILE is -, read standard input. Mandatory arguments to long options are mandatory for short options too. -c, --bytes=[-]NUM print the first NUM bytes of each file; with the leading '-', print all but the last NUM bytes of each file -n, --lines=[-]NUM print the first NUM lines instead of the first 10; with the leading '-', print all but the last NUM lines of each file -q, --quiet, --silent never print headers giving file names -v, --verbose
Команды для управления процессами
Операционная система Linux не имеет встроенного графического диспетчера задач в отличие от Windows, вместо этого всеми процессами можно управлять из терминала. Говорят, что Linux стабильнее винды, но иногда все равно приходится гуглить «Как завершить процесс Linux», потому что что-то зависло.
kill / pkill / killall — завершить процесс
Первый вопрос — почему так много, какую команду использовать? Давайте по порядку:
- kill — убить процесс по его идентификатору (Process ID);
- pkill — убить процесс по его имени;
- killall — убить все процессы с указанным именем.
ps / pgrep — узнать ID процесса
Если вы не компьютер, то вряд ли вам известен ID нужного процесса. PS (Process Status) выведет на экран информацию о запущенных процессах. Чтобы показать список всех активных процессов, используется ps axu.
debtop@DebTop:~/playpen$ top top - 14:21:22 up 8 days, 21:57, 3 users, load average: 0,49, 0,66, 0,65 Tasks: 181 total, 1 running, 180 sleeping, 0 stopped, 0 zombie %Cpu(s): 0,8 us, 0,4 sy, 0,0 ni, 98,7 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st MiB Mem : 7856,4 total, 4009,2 free, 1944,6 used, 1902,6 buff/cache MiB Swap: 8068,0 total, 7913,4 free, 154,6 used. 5390,8 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 690 root 20 0 309888 34416 16856 S 2,0 0,4 5:46.67 Xorg 11426 debtop 20 0 1195064 78272 62036 S 1,7 1,0 0:15.55 konsole 936 debtop 20 0 2994244 59840 36732 S 1,3 0,7 6:10.33 kwin_x11 11586 debtop 20 0 9188248 513296 127392 S 1,0 6,4 14:44.20 chrome 11068 debtop 20 0 973096 310508 142424 S 0,3 3,9 2:27.42 chrome 11107 debtop 20 0 390416 110176 62368 S 0,3 1,4 0:44.15 chrome 11516 debtop 20 0 9177080 384808 114828 S 0,3 4,8 0:58.68 chrome 1 root 20 0 169620 6872 5272 S 0,0 0,1 0:02.15 systemd 2 root 20 0 0 0 0 S 0,0 0,0 0:00.02 kthreadd 3 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_gp 4 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_par_gp 6 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 kworker/0:0H-kblockd 8 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 mm_percpu_wq 9 root 20 0 0 0 0 S 0,0 0,0 0:00.07 ksoftirqd/0 10 root 20 0 0 0 0 I 0,0 0,0 0:09.29 rcu_sched 11 root 20 0 0 0 0 I 0,0 0,0 0:00.00 rcu_bh 12 root rt 0 0 0 0 S 0,0 0,0 0:00.17 migration/0 14 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/0 15 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/1 16 root rt 0 0 0 0 S 0,0 0,0 0:00.37 migration/1 17 root 20 0 0 0 0 S 0,0 0,0 0:00.15 ksoftirqd/1 19 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 kworker/1:0H-kblockd
Проблема в том, что найти нужный процесс среди этого полотна очень сложно. Решений этой проблемы несколько.
1. top (Table Of Processes) — каждые 2 секунды обновляет активные процессы. Колонка PID указывает на ID процесса, USER на пользователя и т.д. Удобно. Если процесс активен постоянно, но уследить за постоянно обновляющимся списком не всегда получается.
2. Более продвинутые утилиты командной строки Linux — atop, htop. Отображают не только активные процессы с обновлением в две секунды, но и контроль над загрузкой и т.д. Утилиты полезны для системных администраторов, но для обычного пользователя все-таки перебор.
3. ps axu | grep имя_процесса. С помощью утилиты grep можно вычленить нужный процесс, если известно его имя.
debtop@DebTop:~/playpen$ ps axu | grep bash debtop 11468 0.0 0.0 8316 5192 pts/1 Ss 13:20 0:00 /bin/bash debtop 14232 0.0 0.0 6224 888 pts/1 S+ 14:22 0:00 grep bash
4. pidof — самый короткий способ выяснить ID процесса, если известно его имя.
debtop@DebTop:~/playpen$ pidof bash 11468
Пакетные менеджеры или как установить файл
По сравнению с Windows, в Linux установка программы требует чуть больше усилий. Даже для установки браузера Chrome придется залезть в терминал.
dpkg — установить файл с расширением .deb (только для систем на Debian).
Многие программы, скачанные из интернета, которые поддерживаются ОС Linux, имеют расширение .deb. Это файлы, оптимизированные под дистрибутивы на основе Debian (Debian, Ubuntu и Ubuntu-based, Mint и т.д.). Когда вы скачаете и попытаетесь открыть файл (точнее пакет) .deb кликом указателя скорей всего ничего не произойдет, потому что это необходимо делать через dpkg:
dpkg -i package.deb — установит пакет .deb;
dpkg —remove package — удалит пакет. Да, при удалении не требуется указывать расширение, так как пакет уже установлен в системе и идентифицируется по имени.
Примечание: Если вы работали в Windows, вы помните, что приложения удаляются не полностью, остаются пустые папки и записи в реестре. У Linux тоже есть такая особенность, остаточные файлы и папки называются dependencies (зависимости). Избавиться от них в Linux гораздо проще, чем в ОС от Майкрософт. Достаточно ввести:
dpkg —purge package.
apt — менеджер установки пакетов Debian-based
Интересная функция Linux — пакетные менеджеры. В каждом дистрибутиве есть свой пакетный менеджер, который может запрашивать и устанавливать пакеты из удаленных репозиториев. Это очень удобно — требуется знать только название пакета, который желаете установить и команду. Пакетный менеджер по умолчанию в Debian и дистрибутивах на основе Debian — apt (Advanced Packaging Tool).
Для установки пакета с помощью apt необходимо ввести команду:
apt install имя_пакета
Часто для этой операции потребуются права суперпользователя, но об этом см. раздел ниже.
Нередко можно встретить apt-get вместо apt — это тот же самый пакетный менеджер, только более старая его версия. Тем не менее оба варианта существуют и работают. Пакетный менеджер apt объединяет сразу несколько прежних команд (apt-get и apt-cache в apt install и apt search), а также оптимизирует процесс установки пакетов.
Команда для удаления установленного пакета с помощью apt:
apt remove имя_пакета
Для удаления зависимостей вместо remove используется purge:
apt purge имя_пакета
Для автоматического удаления всего лишнего из системы используется apt autoremove.
Автоматическое удаление лишнего — это как встроенный в систему менеджер очистки, команда удаляет все файлы и зависимости, которые больше не требуются в системе, например, потому что соответствующего им приложения больше нет в системе.
yum — менеджер установки пакетов Red Hat
Red Hat — один из наиболее популярных дистрибутивов Linux. Утилита yum написана на python. Это пакетный менеджер Red Hat и дистрибутивов на основе Red Hat, например CentOS. Менеджер yum (Yellowdog Updater, Modified) использует формат пакетов rpm вместо deb, но команды остались прежними:
При удалении пакета менеджер yum по умолчанию всегда сохраняет файлы конфигурации, которые отличаются от изначальных по умолчанию и не имеет команды аналогичной apt purge. Впрочем, способы достижения аналогичного результата существуют всегда.
pacman — менеджер пакетов ArchLinux
Еще один дистрибутив, имеющий свой пакетный менеджер — ArchLinux. Утилита pacman написана на языке C (Си). ArchLinux имеет только одну версию — текущую, которая постоянно обновляется, и для этой системы pacman подходит идеально. Пакеты здесь представляют собой архивы формата .tar.xz.
Пакетный менеджер pacman работает иначе чем yum, apt или dpkg. Чтобы установить или удалить пакет с помощью pacman используются опции:
- -S устанавливает пакет ArchLinux;
- -Sw скачивает, но не устанавливает пакет;
- -U для установки пакетов с локального компьютера;
- -s для поиска пакетов;
- -u для обновления установленных пакетов;
- -R для удаления;
- -Rn для удаления резервных копий файлов конфигурации;
- -Rs для удаления зависимостей.
После опции всегда идет имя пакета, т.е.:
pacman -S имя_пакета
Команды управления пользователями
sudo — запуск команд и приложений через терминал в Linux от имени администратора (суперпользователя)
Все важные действия в Linuxе требуют подтверждения от имени администратора, в Linux администратор называется суперпользователем или root. Чтобы выполнить команду от имени суперпользователя, нужно ввести перед ней sudo. Это позволит выполнять команды от имени суперпользователя до окончания текущей сессии в терминале.
Если вы не хотите вводить sudo каждый раз, когда терминал просит это сделать, вы можете переключиться в режим суперпользователя. Для этого выполните su, введите пароль, тогда вы сможете выполнять любые команды по умолчанию от имени суперпользователя. Однако, лучше поступать так только, если вы точно знаете, что делаете. Сломать что-то важное в системе получится вряд ли, но вероятность возрастает лучше использовать sudo.
useradd (adduser) / userdel (deluser) / usermod — добавить, удалить, изменить пользователя
С помощью этих команд вы сможете управлять учетными записями пользователей. Полезно иметь под рукой такую возможность в сетевом домене или домашней сети, выдавать и ограничивать права.
Для добавления пользователя используйте useradd имя_пользователя.
Пароль для нового пользователя задается командой passwd имя_пользователя.
Аналогичным образом, командой userdel имя_пользователя, можно удалить созданную учетную запись.
Третья команда — usermod позволяет изменять учетные записи пользователей: изменять домашнюю директорию, имя учетной записи, оболочку входа в систему, «срок годности» пароля и т.д.
У каждой из трех команд есть свои опции, знать которые новичкам нет необходимости, но знать об их существовании не возбраняется.
Команды выключения и перезагрузки
Linux можно выключить или перезагрузить из командной строки. Зачем это делать? Во-первых, команды очень полезны, если отсутствует графическая оболочка системы — окружение пользователя, и вся работа происходит из терминала. Во-вторых, различные команды или опции помогут произвести перезагрузку или выключение с разными параметрами.
shutdown — выключение
shutdown опции время сообщение
Время — отсрочка выключения. Можно указывать:
- в 24-часовом формате когда нужно указать точное время выключения с точностью до минуты shutdown 10:10;
- в формате +мин, например, shutdown +10 выключит компьютер через 10 минут после выполнения. Команды shutdown +0 и shutdown now выключат компьютер немедленно.
Сообщение (wall) — текстовое сообщение, отправляемое пользователям компьютеров в сети. Если требуется добавить комментарий с причиной выключения. При добавлении сообщения обязательно указывать время.
Некоторые опции:
- -H (Halt) — останавливает все функции процессора, но не выключает компьютер. Halt можно использовать как самостоятельную команду, отдельно от shutdown;
- -P — полное выключение компьютера. Можно использовать как команду poweroff;
- -r (reboot) — перезагрузка. В качестве команды — reboot;
- -k — не производить никаких действий, отправить сообщение;
- -c — отменить запланированное выключение. Можно отменить выключение, только если не было задано время +0 или now.
Заключение, несколько советов
Мы рассмотрели основные команды Linux с примерами, надеемся, что они окажутся вам полезными. Напоследок приведем несколько советов по использованию терминала одной строкой.
Двойной символ & (амперсанд)
Предназначен для выполнения нескольких команд последовательно:
команда1 && команда2 && команда3
команда3 выполнится только после успешного исполнения команды2, а команда2 — после команды1.
Вертикальная черта | (pipe)
Вводит результат первой команды в последующую. Например, следующая команда добавит таблицу процессов к команде поиска:
ps axu | grep имя_процесса
&& и || можно комбинировать. Например вот так: команда1 && команда2 || команда3
Стрелки вверх и вниз на клавиатуре
Помогают осуществлять навигацию по последним командам. Стрелка вверх (Ctrl+P) — предыдущая выполненная команда, стрелка вниз (Ctrl+N) — следующая.
history — история
Если вы забыли, как вы выполнили действие пять дней назад, а вот оно снова потребовалось, выполните history, и терминал выведет на экран последнюю тысячу команд.
Новая вкладка bash
Не всегда удобно иметь несколько окон. Некоторые терминалы, как и браузеры, дают возможность открыть несколько вкладок сочетанием клавиш Ctrl+Shift+T.
Копирование и вставка, прерывание команды
Пробовали ли вы копировать текст и вставлять в терминал? Пробовали Ctrl+C? Ctrl+C прервет выполнение текущей команды, например таблицы процессов, сбросит текст, введенный в строку. Скопировать текст из bash — Ctrl+Shift+C, вставить — Ctrl+Shift+V (для MacOS — Command+C и Command+V соответственно).
Как задаются и выполняются простые и сложные команды linux
Copyleft (no c) — 1996-2004 В. Кравчук, OpenXS Initiative, идея, составление, перевод, примеры Назад Оглавление Вперёд
Командный интерпретатор
Пользователь ОС UNIX общается с системой через командный интерпретатор (shell). Через него происходит доступ к командам, файловой системе и другим функциям ядра UNIX. Это обычная программа (т.е. не входит в ядро операционной системы UNIX). Ее можно заменить другой или использовать несколько разных версий. Наиболее известны следующие версии:
sh Классический интерпретатор версии UNIX V7, иначе называемый по фамилии автора Bourne shell .
ksh Интерпретатор Korn shell , дополняющий классический shell возможностями работы с заданиями пользователя, историей работы и позволяющий редактировать командную строку при помощи команд, аналогичных vi . Является фактически стандартом для POSIX-совместимых систем, в частности, UNIX System V.
csh Стандартный интерпретатор BSD UNIX и производных от него систем. Отличается улучшенными диалоговыми возможностями, способом присваивания и экспортирования переменных в среду, управляющими конструкциями и рядом других моментов; тоже поддерживает историю и редактирование командной строки. Главное и, по моему мнению, отрицательное его отличие от других интерпретаторов, — это свои управляющие конструкции, не совпадающие с sh .
bash Свободно распространяемый в виде исходных текстов интерпретатор, называемый » Bourne another shell «, объединяющий все лучшее из остальных интерпретаторов с удобными возможностями редактирования командной строки и работы с историей команд. В настоящее время — фактический стандарт.
В рамках этого курса мы будем рассматривать, в основном, средства, не выходящие за пределы возможностей командных интерпретаторов sh и ksh (в классической версии 1988 года).
Структура командной строки
Командные строки рассматриваются по одной и имеют определенную структуру. Чтобы понять ее, рассмотрим ряд синтаксических определений:
Итак, простая команда — это последовательность слов через пробел. Нажатие клавиши Enter при вводе команды или перевод строки при обработке сценария являются для командного интерпретатора признаком завершения команды. Она обрабатывается и выполняется.
Значением простой команды является ее статус выхода (см. далее) в случае нормального завершения или (восьмеричное) 200+статус при ненормальном завершении.
Пример простой команды:
$ who oracle pts000 Aug 20 10:08 root console Aug 20 09:03 intdbi pts004 Aug 20 12:45 $
Из простых команд строятся более сложные конструкции: конвейеры и списки .
Конвейер — это последовательность одной или более команд, разделенных | . Стандартный выходной поток каждой команды, кроме последней, соединяется при помощи программного канала со стандартным входным потоком следующей команды. Каждая команда выполняется как отдельный процесс; интерпретатор ожидает окончания последней команды. Статусом выхода конвейера является статус выхода его последней команды. Вот пример простого конвейера:
$ ls | tee save | wc 15 15 100 $
Список — это последовательность одного или более конвейеров, разделенных ; , & , && или || и, возможно, заканчивающаяся ; или & . Из этих четырех символов, ; и & имеют равный приоритет, который ниже, чем у && и || (эти символы тоже имеют равный приоритет). Точка с запятой ( ; ) вызывает последовательное выполнение предшествующего конвейера (т.е. командный интерпретатор ожидает окончания конвейера перед выполнением любых команд, следующих за точкой с запятой). Амперсанд ( & ) вызывает асинхронное выполнение предшествующего конвейера (т.е. командный интерпретатор не ожидает окончания работы конвейера). Символ && ( || ) ведет к тому, что следующий за ним список выполняется только в том случае, когда предыдущий конвейер вернул нулевой (ненулевой) статус выхода. В список может входить произвольное количество переводов строк и точек с запятой, разделяющих команды.
Теперь можно дать общее определение команды:
Список в круглых скобках выполняется в порожденном командном интерпретаторе. Круглые скобки обычно используют для группировки команд.
Список в фигурных скобках выполняется в текущем командном интерпретаторе, без порождения дополнительного процесса, и замещает образ командного интерпретатора (это аналог системного вызова exec ).
Операторы управления и синтаксис определения функций рассматривается далее.
Рассмотрим пример сложной команды:
bash$ (sleep 5; date) & date [1] 1148 Wed Aug 20 15:00:11 . 1997 bash$ Wed Aug 20 15:00:16 . 1997
Фоновый процесс начинается, но сразу «засыпает»; тем временем вторая команда date выдает текущее время, а интерпретатор — приглашение для ввода новой команды. Через пять (примерно, зависит от загрузки системы и т.п.) секунд прекращается выполнение команды sleep и первая команда date выдает новое время.
Метасимволы командного интерпретатора
Ряд символов, как было описано выше, имеют для командного интерпретатора специальное значение — это метасимволы . Они описаны в табл. 23.
Метасимволы не входят в команды и обрабатываются в несколько проходов до начала выполнения реальных программ.
Таблица 23. Метасимволы командного интерпретатора
| Метасимвол | Интерпретация |
| > | prog>file — переключить стандартный выходной поток в файл |
| >> | prog>>file — добавить стандартный выходной поток к файлу |
| prog | |
| | | p1 | p2 — передать стандартный выходной поток p1 как стандартный входной поток p2 |
| » Документ здесь «: стандартный входной поток задается в последующих строках до строки, состоящей только из символов str . По умолчанию в данных интерпретируются метасимволы \ , $ и « . Если необходимо предотвратить в данных интерпретацию всех метасимволов, необходимо экранировать строку str , предварив обратной косой или взяв в двойные или одиночные кавычки. | |
| * | Задает в имени файла любую строку из нуля или более символов |
| ? | Задает любой символ в имени файла |
| [abc] | Задает любой символ из [abc] в имени файла, при этом допускаются диапазоны, задаваемые при помощи дефиса — . Если первым символом после [ является ! , с этой конструкцией сопоставляется любой символ, не входящий в квадратные скобки. |
| ; | Разделитель команд: p1; p2 — выполнить p1 , затем p2 . |
| & Выполняет предшествующую команду в фоновом режиме | |
| `. ` | Инициирует выполнение команд(ы) в . ; `. ` заменяется на полученный в результате выполнения стандартный выходной поток |
| (. ) | Инициирует выполнение команд(ы) . в порожденном командном интерпретаторе |
| $1,$2. $9 | Заменяются аргументами командного файла |
| $var | Значение переменной ( ключевого параметра ) var в сеансе |
| $ | Значение var : исключает коллизии в случае конкатенации переменной с последующим текстом |
| \ | \c — использовать непосредственно символ c , \ перевод строки — отбрасывается |
| ‘. ‘ | Непосредственное использование того, что в кавычках |
| «. « | Непосредственное использование, но после того, как будут интерпретированы метасимволы $ , `. ` и \ |
| # | Начало комментария |
| var=value | Присваивает значение value переменной var |
| p1&&p2 Выполнить p1 ; в случае успеха выполнить p2 | |
| p1||p2 | Выполнить p1 ; в случае неудачи выполнить p2 |
Примечание Большинство метасимволов будет рассматривается по ходу изложения. Здесь мы остановимся на тех из них, которые используются для генерации имен файлов и экранирования.
Перед выполнением команды каждое слово-аргумент команды просматривается в поисках метасимволов * , ? и [ . Если в слове есть один из этих символов, слово рассматривается как шаблон (обратите внимание на синтаксические отличия от шаблонов ed ). Такое слово заменяется отсортированными в алфавитном порядке именами файлов, соответствующих шаблону. Если ни одно их имен файлов не соответствует шаблону, слово оставляется без изменений. Символ . в начале имени файла или сразу после / , а также сам символ / , должны сопоставляться явно .
При таком количестве метасимволов интерпретатора необходимо иметь возможность экранировать специальный символ от интерпретации. Для этого можно использовать апострофы, кавычки или обратную косую. При этом кавычки одного вида могут экранировать кавычки другого вида. Обратите внимание, что кавычки «» , в отличие от апострофов, не экранируют строку полностью — интерпретатор заглядывает внутрь кавычек в поисках $ , `. ` и \ .
В кавычках могут содержаться переводы строк, пробелы, табуляции, символы ; , & , ( , ) , | , ^ , < и >. Задавая имя файла в кавычках, можно создать файлы с такими нетривиальными символами в именах. Впрочем, делать это не рекомендуется, так как работать с ними будет явно неудобно.
Создание сценариев
Имея последовательность команд, которую придется многократно использовать, преобразуем ее для удобства в «новую» команду со своим именем и будем использовать ее как обычную команду. Предположим, что вам как администратору предстоит часто подсчитывать количество пользователей, работающих в настоящий момент в системе, при помощи простого конвейера
$ who | wc -l
и для этой цели нужна новая программа nu .
Первым шагом будет создание обычного текстового файла, содержащего текст конвейера. Можно воспользоваться вашим любимым текстовым редактором, а можно проявить изобретательность:
$ echo 'who | wc -l' >nu
Интерпретатор является такой же программой, как редактор, who или wc . Раз это программа, ее можно вызвать и переключить ее входной поток. Итак, запускаем интерпретатор с входным потоком, поступающим из файла nu , а не с терминала:
$ who oracle pts000 Aug 20 10:08 root console Aug 20 09:03 intdbi pts004 Aug 20 12:45 $ cat nu who | wc -l $ sh < nu 3 $
Результат получился таким же, как и при вводе команды с терминала. Как и многие другие программы, интерпретатор обрабатывает файл, если он указан в качестве аргумента; вы с тем же успехом могли бы задать:
$ sh nu
На самом деле, этот вызов отличается, так как входной поток sh остается связанным с терминалом.
Не хотелось бы вводить sh каждый раз, кроме того, это создает различие между командами, написанными на языке shell, и другими выполняемыми файлами. Поэтому, если текстовый файл предназначен для выполнения, то интерпретатор считает, что он состоит из команд (интерпретатор csh требует, чтобы файл начинался с # ).
Примечание Если в первой строке выполняемого текстового файла указано:
#!/полный_путь_к_программе опции_программы
то данный текстовый файл будет интерпретироваться указанной программой, при вызове которой будут установлены заданные опции. Так можно выполнять, например, программы командного интерпретатора csh , не выходя из sh . Точно так же можно автоматически вызвать и интерпретаторы других языков сценариев, например, Perl.
Все, что вам нужно сделать, это объявить файл nu выполняемым, задав:
$ chmod +x nu
а затем вы можете вызывать его посредством
На самом деле, при выполнении команды nu создается новый процесс интерпретатора (порожденный интерпретатор), который и выполняет команды, содержащиеся в nu . Чтобы команда выполнялась в том же интерпретаторе, необходимо поставить перед вызовом команды точку ( . ). Заметьте, что
выполняется быстрее, чем простой вызов nu .
В большинстве программ надо использовать аргументы - файлы, флаги и т.д. В соответствии с синтаксисом командной строки, это можно сделать, передавая их после имени команды через пробелы.
Предположим, необходимо программу cx для установки права доступа к файлу на выполнение, так что
$ cx nu
есть сокращенная запись для
$ chmod +x nu
Создать такой сценарий не сложно. Остается только один вопрос - как получить в программе доступ к имени файла-аргумента. Для этого в командном интерпретаторе используются позиционные параметры .
При выполнении командного файла, каждое вхождение $1 заменяется первым аргументом, $2 - вторым и так далее до $9 . $0 заменяется именем выполняемой команды. Поэтому, если файл cx содержит строку
chmod +x $1
то при выполнении команды
$ cx nu
порожденный интерпретатор заменит $1 первым аргументом команды nu .
Значения позиционным параметрам присваиваются при вызове сценария, при вызове функции в сценарии или явно, с помощью команды set .
Как быть, если нужно работать с несколькими аргументами, например, заставить программу cx делать выполняемыми несколько файлов? Можно включить девять аргументов в командный файл (явно можно задавать только девять аргументов, так как конструкция $10 распознается как "первый аргумент, за которым следует 0"):
chmod +x $1 $2 $3 $4 $5 $6 $7 $8 $9
Если пользователь такого командного файла задаст менее девяти аргументов, то оставшиеся окажутся пустыми строками и только настоящие аргументы будут переданы chmod порожденным интерпретатором. Но такое решение не подходит, если количество аргументов превышает девять.
Интерпретатор предоставляет специальный параметр $* , который заменяется всеми аргументами команды, независимо от их количества. С учетом этого, правильное определение cx будет таким:
chmod +x $*
Все позиционные и специальные параметры, поддерживаемые командным интерпретатором, представлены в табл. 24.
Таблица 24. Позиционные и специальные параметры командного интерпретатора
| Параметр | Назначение |
| $0 | Имя выполняемой команды |
| $1,$2. $9 | Заменяются аргументами командного файла |
| $# | Количество аргументов |
| $* | Все аргументы, передаваемые интерпретатору. "$*" является единым словом, образованным из всех аргументов, объединенных вместе с пробелами. |
| $@ | Аналогично $* . "$@" идентично аргументам: пробелы в аргументах игнорируются, и получается список слов, идентичных исходным аргументам. |
| $- | Флаги, установленные в интерпретаторе. |
| $? | Значение, возвращенное последней выполненной командой ( статус выхода ). |
| $$ | Номер процесса интерпретатора. |
| $! | Номер процесса последней команды, запущенной асинхронно с помощью & . |
Переменные и присваивание
Подобно большинству языков программирования, командный интерпретатор имеет переменные , которые называют еще ключевыми параметрами (поскольку они предаются по имени - ключу).
Переменные можно создавать, изменять и выбирать их значения. Для присваивания значения переменной применяется конструкция:
переменная=значение
Обратите внимание на отсутствие пробелов до и после знака присваивания. Вспомните, что командный интерпретатор считает пробелы разделителями слов. Если поставить пробел после знака присваивания, то интерпретатор не изменит значения переменной, но будет искать команду с именем значение .
Присваиваемое значение должно выражаться одним словом, и его следует взять в кавычки, если оно содержит метасимволы, которые не нужно обрабатывать.
Создание (определение) переменной происходит при первом присваивании ей значения. Переменные не нужно явно объявлять до момента их использования. Если переменная не объявлена (не получила значения), при обращении к ней будет получена пустая строка. Все переменные в командном интерпретаторе - строковые, поэтому тип переменной задавать не надо. Некоторые команды интерпретируют строки как числа.
Многие переменные, как, например, PATH , имеют специальное значение для интерпретатора. По традиции, такие переменные называют встроенными и обозначают прописными буквами, а обычные переменные - строчными. Основные встроенные переменные представлены в табл. 25.
Таблица 25. Встроенные переменные командного интерпретатора
| Переменная | Значение |
| $HOME | Начальный каталог пользователя. |
| $PATH | Путь для поиска выполняемых команд. |
| $CDPATH | Путь поиска для команды cd . |
| $IFS | Список символов, разделяющих слова в аргументах |
| Файл почтового ящика. Командный интерпретатор информирует пользователя о получении почты в указанный файл. | |
| $MAILCHECK | Эта переменная определяет, как часто (в секундах) интерпретатор будет проверять поступление почты в файл, определяемый переменной MAIL . По умолчанию принято значение 600 секунд. При установке в 0, интерпретатор будет проверять почту перед каждой выдачей строки-приглашения. |
| $PS1 | Строка-приглашение, по умолчанию принята '$ ' |
| $PS2 | Строка-приглашение при продолжении командной строки, по умолчанию принята '> ' |
Типичным примером использования переменных является хранение в них длинных строк, таких как имена файлов:
$ pwd /home/intdbi/dosapps/doc/book/unix/shell $ dir=`pwd` $ cd $ ln $dir/cx . . $ cd $dir $ pwd /home/intdbi/dosapps/doc/book/unix/shell
Встроенная команда интерпретатора set , при вызове без параметров показывает значение всех определенных переменных.
Присваивание значения переменной при вызове
Переменные называют ключевыми параметрами , поскольку им можно передавать значение по имени при вызове. Рассмотрим пример:
$ echo 'echo $x' >echox $ cx echox $ echo $x Hello $ echox $ x=Hi echox Hi
По умолчанию ключевые параметры можно передавать только до имени команды. Если установить флаг интерпретатора -k ( set -k ), то можно будет передавать значения переменным и после имени команды.
Экспортирование переменных в среду
Каждый экземпляр командного интерпретатора имеет свой набор переменных, размещаемых в отдельной области памяти. Если необходимо, чтобы определенная переменная в порожденных процессах имела конкретное значение, необходимо экспортировать ее в среду . Такая переменная называется переменной среды.
Для всех экспортированных переменных при запуске порожденного процесса создаются их локальные копии с теми же значениями. Рассмотрим пример:
$ x=Hello $ export x $ PS1='new$ ' sh new$ echo $x Hello new$ x='Good Bye' new$ echo $x Good Bye new$ exit $ $ echo $x Hello$
Изменение значение переменной в порожденном интерпретаторе не влияет на ее значение в родительском интерпретаторе.
Для просмотра значений всех переменных среды предназначена команда env .
Циклы в командном интерпретаторе
Командный интерпретатор поддерживает циклическую обработку. Чаще всего на практике используется цикл for - цикл по списку слов . Он описан в следующем подразделе.
Обратите внимание, что выделенные полужирным ключевые слова должны быть первым словом команды, т.е. первым словом в строке или идти сразу после точки с запятой.
Цикл for
Цикл for имеет следующий синтаксис:
Переменная последовательно получает значение очередного слова из списка, и для этого значения выполняются команды в теле цикла. Цикл завершается, когда пройден весь список слов. По умолчанию в качестве списка слов используются аргументы командной строки.
Рассмотрим пару примеров таких циклов:
$ for i in 1 2 3 4 5 > do > echo $i > done
Обратите внимание, что командный интерпретатор распознает цикл, выдает вторичное приглашение, и выполняет цикл только после его завершения ключевым словом done .
Список слов для цикла обычно порождается динамически. Например, путем раскрытия шаблонов имен файлов:
$ for i in *.c *.h > do > echo $i > diff -b old/$i $i > echo > done | pr -h "diff `pwd`/old `pwd`" | lp & [4] 1430
Можно также порождать его командой, подставляя ее результаты:
$ for i in `pick *.c *.h` > do > echo $i: > diff -b old/$i $i > done | pr | lp
Операторы цикла while и until
Командный интерпретатор поддерживает также традиционные циклы по условию со следующим синтаксисом:
Выполняются команды , задающие условие, и проверяется код возврата последней из них. Если это ноль ( истина ), выполняются команды в теле цикла while или завершается выполнение цикла until . Если это не ноль ( ложь ), завершается работа цикла while или выполняется очередная итерация цикла until .
На основе этих циклов часто создаются программы-" следилки ", работающие бесконечно:
$ cat watchfor # watchfor: watching for log ins and log outs. PATH=/usr/bin new=/tmp/wfor1.$$ old=/tmp/wfor2.$$ >$old # создает пустой файл while : # бесконечный цикл do who >$new diff $old $new mv $new $old sleep 60 done | awk ' />/ < $1 = "in: "; print >/ < $1 = "out: "; print >' $
Оператор выбора
Командный интерпретатор поддерживает выполнение того или иного блока команд в зависимости от значения некоторого слова. Для этого предлагается оператор case со следующим синтаксисом:
Слово (обычно - значение переменной) сравнивается последовательно с шаблонами. Если произошло сопоставление ( по правилам сопоставления шаблонов имен файлов ) выполняются команды, соответствующие данному варианту и оператор завершается. Учтите, что шаблон *) сопоставляется с любым словом, и, тем самым, задает вариант по умолчанию.
В шаблонах оператора case символы . и / , в отличие от шаблонов имен файлов, не обязательно задавать явно.
Условный оператор
Командный интерпретатор поддерживает условный оператор следующего общего вида:
Выполняются команды после if и проверяется код возврата последней из них. Если это 0 ( истина ) выполняются соответствующие команды после then и выполнение оператора завершается. Если же это не 0 ( ложь ), то при наличии конструкций elif выполняются последовательно соответствующие команды-условия и, если они возвращают код 0, команды после then , а затем оператор завершается. Если ни одно из условий не было истинным, выполняются команды в части else и оператор завершается.
В качестве условия в условном операторе может использоваться любая команда. Однако, имеется стандартная команда для проверки условий в традиционном понимании. Это команда test , представленная в следующем разделе.
Проверка условий в командном интерпретаторе
Команда test имеет следующий синтаксис:
Выражение строится из примитивов, представленных в табл. 26, при необходимости, с помощью следующих операторов:
| ! | Унарный оператор отрицания. |
| -a | Бинарный оператор "и". |
| -o | Бинарный оператор "или". |
| () | Скобки для группировки. Учтите, что скобки распознаются командным интерпретатором, поэтому их надо брать в кавычки. |
Таблица 26. Основные примитивы команды test
| Примитив | Условие |
| -r файл | файл существует и доступен для чтения |
| -w файл | файл существует и доступен для записи |
| -x файл | файл существует и является выполняемым |
| -f файл | истина, если файл существует и является обычным файлом (не каталогом) |
| -d файл | файл существует и является каталогом |
| -h файл | файл существует и является символьной связью |
| -s файл | файл существует и не пуст |
| -t [ дескриптор ] | истина, если открытый файл с указанным дескриптором (по умолчанию, 1) ассоциирован с терминалом |
| -z s1 | истина, если строка s1 имеет нулевую длину |
| -n s1 | истина, если строка s1 имеет ненулевую длину |
| s1 = s2 | истина, если строки s1 и s2 идентичны |
| s1 != s2 | истина, если строки s1 и s2 не совпадают |
| s1 | истина, если строка s1 непустая |
| n1 -eq n2 | сравнение целых чисел на равенство ( = ). Можно использовать также и другие сравнения: -ne ( != ), -gt ( > ), -ge ( >= ), -lt ( < ) и -le ( |
Рассмотрим пример использования условного оператора и команды test :
$ cat which # which cmd: Безопасная версия сценария для выдачи каталога, # из которого будет вызываться выполняемая программа opath=$PATH PATH=/usr/bin # Это гарантирует использование настоящих команд # echo, sed и test в любом случае! case $# in 0) echo 'Usage: which command' 1>&2; exit 2 esac for i in `echo $opath | sed 's/^:/.:/ s/::/. /g s/:$/:./ s/:/ /g'` do if test -x $i/$1 then echo $i/$1 exit 0 # команда найдена fi done exit 1 # не найдена $ which sed ./sed $ which which ./which
Перехват и обработка сигналов
В программах командного интерпретатора можно перехватывать и обрабатывать сигналы. Для этого используется команда trap , устанавливающая с момента выполнения обработчик в виде последовательности команд ( одним словом ) для всех перечисленных сигналов. Эта команда имеет следующий синтаксис:
Рассмотрим пример реализации команды nohup , позволяющей запустить программу так, чтобы она продолжала работать при выключении терминала:
$ cat nohup # nohup: no kill and hangup trap "" 1 15 if test -t 2>&1 then echo "Redirect stdout to 'nohup.out'" exec nice -5 $* >>nohup.out 2>&1 else exec nice -5 $* 2>&1 fi $
Запрос информации у пользователя
Командный интерпретатор позволяет, при необходимости, запрашивать у пользователя информацию, которая помещается в указанную переменную. Для этого используется команда read :
$ read greeting Hello, world! $ echo $greeting Hello, world! $
На практике имеет смысл перед запросом выдать приглашение с помощью команды echo . Например, вот так:
$ cat pick # pick: select arguments PATH=/bin:/usr/bin for i # for each argument, try $*, "$*" and "$@" do echo -n "$i? " > /dev/tty read responce case $responce in y*) echo $i;; q*) break esac doneПредставленная выше программа pick выдает каждое указанное в качестве аргумента слово в отельной строке со знаком вопроса и требует от пользователя подтвердить необходимость его выдачи в стандартный выходной поток. Поскольку эта программа может использоваться в других сценариях, входной и выходной потоки которых перенаправлены, она взаимодействует непосредственно с текущим терминалом (через устройство /dev/tty ).
Вычисления в командном интерпретаторе
Вычисления можно выполнять с помощью любой программы, воспринимающей свои параметры как выражение, значение которого необходимо вычислить, и выдающей результат вычисления в стандартный выходной поток. Одна из таких программ, expr , рассмотрена далее. Но современные командные интерпретаторы включают встроенную команду для выполнения простейших арифметических действий. Это команда let :
Вот как ее можно использовать:
$ let a=5 $ echo $a 5 $ let a=a*a+34/2 $ echo $a 42 $ let "a = 7" $ echo $a 7Обратите внимание, что если вокруг знака равенства идут пробелы, необходимо брать выражение в кавычки. Команда let требует, чтобы выражение было одним словом. Кроме того, для обращения к значению переменной в этой команде не нужно использовать метасимвол $ .
Команда expr
Одной из стандартных программ-калькуляторов является программа expr . Ее основные операторы представлены в табл. 27.
Таблица 27. Основные операторы, распознаваемые командой expr
| Оператор | Результат |
| выр1 \| выр2 | Возвращает значение первого выражения, если оно не пустое и не равно 0, иначе, возвращает значение второго выражения. |
| выр1 \& выр2 | Возвращает значение первого выражения, если оба выражения - не пустые и не равны 0, иначе, возвращает 0. |
| выр1 < +, - >выр2 | Складывает или вычитает целочисленные аргументы. |
| выр1 < \*, /, % >выр2 | Умножает, делит или возвращает остаток от деления для целочисленных аргументов. |
| length строка | Возвращает длину строки. |
Рассмотрим простой пример вычисления с помощью expr :
$ a=5 $ echo $a 5 $ a=`expr $a \* $a + 34 / 2` $ echo $a 42
Обратите внимание, что между элементами выражения надо указывать пробелы.
Функции в командном интерпретаторе
Стандартным способом разбиения программ на модули в командном интерпретаторе является оформление необходимых действий в виде отдельного выполняемого файла с программой командного интерпретатора - создание новой команды. Тем не менее, для некоторых модулей такой подход может оказаться неэффективным и избыточным, так как модули могут не представлять самостоятельного значения вне программы, в которой они используются. Поэтому в современных версиях командных интерпретаторов предлагается возможность создавать и вызывать функции .
Синтаксис определения функции
Для определения функций используется ключевое слово function . Функции читаются и хранятся внутренне командным интерпретатором. Функции выполняются как команды, причем аргументы передаются как позиционные параметры . Синтаксис определения функции следующий:
где список команд задает команды, выполняемые в качестве тела функции. Команды обычно разделяются точкой с запятой или переводами строк.
Выполнение и использование функций
Функции выполняются вызвавшим их процессом и используют все его файлы и текущий рабочий каталог. Сигналы, перехватываемые вызывающим процессом, внутри фунции обрабатываются стандартным образом. Сигналы, не перехватываемые или игнорируемые функцией, прекращают ее выполнение и передаются вызвавшей команде.
Обычно переменные совместно используются вызывающей программой и функцией. Однако, специальная команда typeset , используемая внутри функции, позволяет определять локальные переменные, область действия которых - текущая функция и все вызываемые ею функции.
Для выхода из функции используется специальная команда return . В случае ошибки в функции, управление передается вызывающей команде.
Идентификаторы определенных функций можно получить с помощью опций -f или +f специальной команды typeset . Текст функций показывается при использовании опции -f . Определение функции можно отменить с помощью опции -f специальной команды unset .
Обычно при выполнении сценария командным интерпретатором никакие функции не заданы. Опция -xf команды typeset позволяет экспортировать функцию для использования сценариями, выполняемыми без отдельного вызова интерпретатора. Функции, которые должны быть определены для всех вызовов интерпретатора, необходимо задавать в файле начального запуска с помощью опций -xf команды typeset .
Рассмотрим классический пример итеративной реализации функции вычисления факториала:
# test.sh - test shell functions factorial () < typeset i typeset n i=1; n=1 while [ $i -le $1 ] do let n=n*i let i=i+1 done echo $n return >a=`factorial $11` echo $a
При вызове эта программа, как и ожидалось, вычислит факториал своего первого параметра:
bash$ test.sh 5 120
Часто в виде функций оформляется выдача сообщений о параметрах вызова программы. В любом случае, если задача может быть разбита на подзадачи, решение этих подзадач имеет смысл оформлять в виде отдельной команды, если они полезны не только в контексте решаемой задачи, или в виде функции в противном случае.
Файлы начального запуска командного интерпретатора
Стандартная среда для работы командных интерпретаторов задается в файлах начального запуска , которые автоматически выполняются в начальном интерпретаторе с помощью команды точка ( . ), т.е. без порождения. Файлы начального запуска размещаются в начальном каталоге пользователя и называются .profile ( sh , ksh ) или .bash_profile ( bash ). Переменные, составляющие среду, в файле начального запуска надо экспортировать.
Рассмотрим пример содержимого файла начального запуска:
INFORMIXDIR=/usr/inf.731 INFORMIXSERVER=onarturo7 ONCONFIG=onconfig SQLHOSTS=sqlhosts PATH=$PATH:$INFORMIXDIR/bin LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$INFORMIXDIR/lib/esql:$INFORMIXDIR/lib DB_LOCALE=ru_ru.8859-5 CLIENT_LOCALE=ru_ru.8859-5 KAIOON=1 NODEFDAC=YES DBDATE=DMY4/ DBTIME='%H:%M:%S %d/%m/%Y' DBMONEY=.4 export KAIOON export INFORMIXDIR INFORMIXSERVER LANG PATH ONCONFIG SQLHOSTS export DBDATE DBTIME DBMONEY NODEFDAC export DB_LOCALE CLIENT_LOCALE
Управление заданиями
Управление заданиями - это механизм для отслеживания процессов, которые порождаются из текущего сеанса работы с терминалом. Можно запустить любое число заданий. Они могут работать, завершиться или находиться в других состояниях. Для управления заданиями можно использовать несколько команд, чтобы проследить результаты их работы или потребовать от системы уведомления об окончании задания.
Запуск задания в фоновом режиме
Фоновый режим позволяет продолжить использование сеанса работы с терминалом, пока выполняется команда. Для запуска команды в фоновом режиме, достаточно к команде добавить символ амперсанд ( & ). Командный интерпретатор вернет номер задания и идентификатор процесса:
$ make & [2] 254 $
Если задание не требует от пользователя ввода, оно продолжает свою работу до полного завершения. Если команде нужен ввод, она переходит в состояние ожидания, на экран выводится соответствующее уведомление, которое выглядит примерно так:
[1] + Suspended (tty input) programm 0
В данном случае в ожидании ввода приостановилось выполнение программы programm . Пользователю необходимо перевести из фонового режима в привилегированный и выполнить ввод.
Просмотр состояния заданий
С помощью команды jobs пользователь имеет возможность просмотреть состояние своих заданий и получит список всех заданий запущенных в сеансе работы с терминалом.
$ jobs [1] Stopped (user) du [2]- Stopped (user) du -a /home/intdbi [3]+ Stopped (user) du -r /home/intdbi $
Команда jobs принимает два флага. Флаг -l включает идентификатор процесса с номером задания.
$ jobs -l [1] 1351 Stopped (user) du [2]- 1381 Stopped (user) du -a /home/intdbi [3]+ 1383 Stopped (user) du -r /home/intdbi $
Флаг -р заменяет номер задания на идентификатор процесса.
$ jobs -p 1351 1381 1383 $
Идентификатор процесса может использоваться при обращении к команде ps .
Номера заданий
Номер задания позволяет командному интерпретатору наблюдать за процессами. Его можно рассматривать как головной элемент группы процессов, поскольку пользовательское задание порождает любые команды либо в конвейере, либо, как подзадания.
Перевод задания в привилегированный режим
Команда fg переводит задания в привилегированный режим. При наличии приостановленного задания, его можно сделать привилегированным (перевести на передний план) с помощью команды fg #номер_задания (или fg номер_задания в bash ). После этого задание либо выведет на экран сообщение о том, что ему нужно от терминала, либо будет принимать ожидаемый ввод. Переведя задание в привилегированный режим, можно приостановить его выполнение, нажав комбинацию калвиш Ctrl-Z , и заняться им позже.
Любое задание из списка, предоставленного командой jobs , доступно, если пользователь захочет сделать его привилегированным, даже в том случае, когда оно уже работает в фоновом режиме. Если в этом списке приведено только одно задание, то при использовании команды fg пользователю не нужно задавать его номер. Если номер задания не задан, предполагается текущее задание.
Перевод задания в фоновый режим
С помощью команды bg можно возобновить в фоновом режиме работу приостановленного или остановленного задания. Для этого нужно указать соответствующий номер задания, после чего оно перейдет в фоновый режим, и будет работать до своего завершения, или пока ему снова не потребуется ввод с терминала.
Команда ожидания завершения процесса
Это последняя существенная команда управления заданиями. При вводе wait приостанавливается работа командного интерпретатора до тех пор, пока не будут завершены все фоновые задания. Сюда входят и любые остановленные задания, поэтому при вводе wait стоит убедиться, что все фоновые задания работают. Команда wait может также принимать в качестве параметра номер задания. В этом случае командный интерпретатор приостанавливается до тех пор, пока не завершится выполнение указанного задания.
Как задаются и выполняются простые и сложные команды linux
Топологическая сортировка, считывает пары строк, разделенных пробельными символами, и выполняет сортировку, в зависимости от заданного шаблона.
cat list-1 list-2 list-3 | sort | uniq > final.list # Содержимое файлов, # сортируется, # затем удаляются повторяющиеся строки, # и результат записывается в выходной файл.
Ключ -c выводит количество повторяющихся строк.
bash$ cat testfile Эта строка встречается только один раз. Эта строка встречается дважды. Эта строка встречается дважды. Эта строка встречается трижды. Эта строка встречается трижды. Эта строка встречается трижды. bash$ uniq -c testfile 1 Эта строка встречается только один раз. 2 Эта строка встречается дважды. 3 Эта строка встречается трижды. bash$ 3 Эта строка встречается трижды. 2 Эта строка встречается дважды. 1 Эта строка встречается только один раз.
Команда sort INPUTFILE | uniq -c | sort -nr выводит статистику встречаемости строк в файле INPUTFILE (ключ -nr, в команде sort, означает сортировку в порядке убывания). Этот шаблон может с успехом использоваться при анализе файлов системного журнала, словарей и везде, где необходимо проанализировать лексическую структуру документа.
Пример 12-8. Частота встречаемости отдельных слов
#!/bin/bash # wf.sh: "Сырой" анализ частоты встречаемости слова в текстовом файле. ARGS=1 E_BADARGS=65 E_NOFILE=66 if [ $# -ne "$ARGS" ] # Файл для анализа задан? then echo "Порядок использования: `basename $0` filename" exit $E_BADARGS fi if [ ! -f "$1" ] # Проверка существования файла. then echo "Файл \"$1\" не найден." exit $E_NOFILE fi ######################################################## # main () sed -e 's/\.//g' -e 's/ /\ /g' "$1" | tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr # ========================= # Подсчет количества вхождений # Точки и пробелы заменяются #+ символами перевода строки, #+ затем символы переводятся в нижний регистр #+ и наконец подсчитывается количество вхождений, #+ и выполняется сортировка по числу вхождений. ######################################################## # Упражнения: # --------- # 1) Добавьте команду 'sed' для отсечения других знаков пунктуации, например, запятых. # 2) Добавьте удаление лишних пробелов и других пробельных символов. # 3) Добавьте дополнительную сортировку так, чтобы слова с одинаковой частотой встречаемости #+ сортировались бы в алфавитном порядке. exit 0
bash$ cat testfile Эта строка встречается только один раз. Эта строка встречается дважды. Эта строка встречается дважды. Эта строка встречается трижды. Эта строка встречается трижды. Эта строка встречается трижды. bash$ ./wf.sh testfile 6 Эта 6 встречается 6 строка 3 трижды 2 дважды 1 только 1 один 1 раз
Команда expand преобразует символы табуляции в пробелы. Часто используется в конвейерной обработке текста.
Команда unexpand преобразует пробелы в символы табуляции. Т.е. она является обратной по отношению к команде expand.
Предназначена для извлечения отдельных полей из текстовых файлов. Напоминает команду print $N в awk, но более ограничена в своих возможностях. В простейших случаях может быть неплохой заменой awk в сценариях. Особую значимость, для команды cut, представляют ключи -d (разделитель полей) и -f (номер(а) поля(ей)).
Использование команды cut для получения списка смонтированных файловых систем:
cat /etc/mtab | cut -d ' ' -f1,2
Использование команды cut для получения версии ОС и ядра:
uname -a | cut -d" " -f1,3,11,12
Использование команды cut для извлечения заголовков сообщений из электронных писем:
bash$ Re: Linux suitable for mission-critical apps? MAKE MILLIONS WORKING AT HOME3 Spam complaint Re: Spam complaint
Использование команды cut при разборе текстового файла:
# Список пользователей в /etc/passwd. FILENAME=/etc/passwd for user in $(cut -d: -f1 $FILENAME) do echo $user done # Спсибо Oleg Philon за этот пример.
cut -d ' ' -f2,3 filename эквивалентно awk -F'[ ]' '< print $2, $3 >' filename
Используется для объединения нескольких файлов в один многоколоночный файл.
Может рассматриваться как команда, родственная команде paste. Эта мощная утилита позволяет объединять два файла по общему полю, что представляет собой упрощенную версию реляционной базы данных.
Команда join оперирует только двумя файлами и объедияет только те строки, которые имеют общее поле (обычно числовое), результат объединения выводится на stdout. Объединяемые файлы должны быть отсортированы по ключевому полю.
File: 1.data 100 Shoes 200 Laces 300 Socks
File: 2.data 100 $40.00 200 $1.00 300 $2.00
bash$ join 1.data 2.data File: 1.data 2.data 100 Shoes $40.00 200 Laces $1.00 300 Socks $2.00
На выходе ключевое поле встречается только один раз.
Выводит начальные строки из файла на stdout (по-умолчанию -- 10 строк, но это число можно задать иным). Эта команда имеет ряд интересных ключей.
Пример 12-9. Какие из файлов являются сценариями?
#!/bin/bash # script-detector.sh: Отыскивает файлы сценариев в каталоге. TESTCHARS=2 # Проверяются первые два символа. SHABANG='#!' # Сценарии как правило начинаются с "sha-bang." for file in * # Обход всех файлов в каталоге. do if [[ `head -c$TESTCHARS "$file"` = "$SHABANG" ]] # head -c2 #! # Ключ '-c' в команде "head" выводит заданное #+ количество символов, а не строк. then echo "Файл \"$file\" -- сценарий." else echo "Файл \"$file\" не является сценарием." fi done exit 0
Пример 12-10. Генератор 10-значных случайных чисел
#!/bin/bash # rnd.sh: Генератор 10-значных случайных чисел # Автор: Stephane Chazelas. head -c4 /dev/urandom | od -N4 -tu4 | sed -ne '1s/.* //p' # =================================================================== # # Описание # -------- # head: # -c4 -- первые 4 байта. # od: # -N4 ограничивает вывод 4-мя байтами. # -tu4 беззнаковый десятичный формат вывода. # sed: # -n, в комбинации с флагом "p", в команде "s", # выводит только совпадающие с шаблоном строки. # Автор сценария описывает действия 'sed' таким образом: # head -c4 /dev/urandom | od -N4 -tu4 | sed -ne '1s/.* //p' # ----------------------------------> | # Передает вывод в "sed" --------> | # пусть это будет 0000000 1198195154\n # sed начинает читать символы: 0000000 1198195154\n. # Здесь он находит символ перевода строки, # таким образом он получает строку (0000000 1198195154). # Затем он просматривает . Первый и единственный -- это # диапазон действие # 1 s/.* //p # Номер строки попадает в заданный лиапазон, так что теперь он приступает к выполнению действия: # пытается заменить наибольшую подстроку, заканчивающуюся пробелом # ("0000000 ") "ничем" (//), и если замена произведена -- выводит результат # ("p" -- это флаг команды "s", а не команда "p", которая имеет иное значение). # теперь sed готов продолжить чтение входного потока. (Обратите внимание: # если опустить ключ -n, то sed выведет строку еще раз) # Теперь sed дочитывает остаток строки. # Он готов приступить к анализу 2-й строки (которая отмечена '$' # как последняя). # Поскольку строка не попадает в заданный , на этом обработка прекращается. # Проще говоря, команда sed означает: # "В первой строке удалить любые символы, вплоть до последнего встреченного пробела, # и затем вывести остаток." # Сделать это можно более простым способом: # sed -e 's/.* //;q' # Где, заданы два (можно записать и по другому # sed -e 's/.* //' -e q): # диапазон действие # ничего (для совпадающих строк) s/.* // # ничего (для совпадающих строк) q (quit) # Здесь sed считывает только первую строку. # Выполняет оба действия, и выводит строку перед завершением # (действие "q"), поскольку ключ "-n" опущен. # =================================================================== # # Простая альтернатива: # head -c4 /dev/urandom| od -An -tu4 exit 0
Выводит последние строки из файла на stdout (по-умолчанию -- 10 строк). Обычно используется для мониторинга системных журналов. Ключ -f, позволяет вести непрерывное наблюдение за добавляемыми строками в файл.
Пример 12-11. Мониторинг системного журнала с помощью tail
#!/bin/bash filename=sys.log cat /dev/null > $filename; echo "Создание / очистка временного файла." # Если файл отсутствует, то он создается, #+ и очищается, если существует. # : > filename и > filename дают тот же эффект. tail /var/log/messages > $filename # Файл /var/log/messages должен быть доступен для чтения. echo "В файл $filename записаны последние строки из /var/log/messages." exit 0
Многоцелевая поисковая утилита, использующая регулярные выражения. Изначально это была команда в древнем строчном редакторе ed, g/re/p, что означает -- global - regular expression - print .
Поиск участков текста в файле(ах), соответствующих шаблону pattern, где pattern может быть как обычной строкой, так и регулярным выражением.
bash$
bash$ ps ax | grep clock 765 tty1 S 0:00 xclock 901 pts/1 S 0:00 grep clock
-i -- выполняется поиск без учета регистра символов.
-w -- поиск совпадений целого слова.
-l -- вывод только имен файлов, в которых найдены участки, совпадающие с заданным образцом/шаблоном, без вывода совпадающих строк.
-r -- (рекурсивный поиск) поиск выполняется в текущем каталоге и всех вложенных подкаталогах.
The -n option lists the matching lines, together with line numbers.
bash$ grep -n Linux osinfo.txt
-v (или --invert-match) -- выводит только строки, не содержащие совпадений.
grep pattern1 *.txt | grep -v pattern2 # Выводятся строки из "*.txt", совпадающие с "pattern1", # но ***не*** совпадающие с "pattern2".
-c ( --count) -- выводит количество совпадений без вывода самих совпадений.
grep -c txt *.sgml # (количество совпадений с "txt" в "*.sgml" файлах) # grep -cz . # ^ точка # означает подсчет (-c) непустых ("." -- содержащих хотя бы один символ) элементов, # разделенных нулевыми байтами (-z) # printf 'a b\nc d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz . # 4 printf 'a b\nc d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz '$' # 5 printf 'a b\nc d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz '^' # 5 # printf 'a b\nc d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -c '$' # 9 # По-умолчанию, в качестве разделителя, принимается символ перевода строки (\n). # Обратите внимание: ключ -z характерен для GNU-версии "grep". # Спасибо S.C.
Если grep вызывается для поиска по группе файлов, то вывод будет содержать указание на имена файлов, в которых найдены совпадения.
bash$ grep Linux osinfo.txt misc.txt
Для того, чтобы заставить grep выводить имя файла, когда поиск производится по одному-единственному файлу, достаточно указать устройство /dev/null в качестве второго файла.
bash$
Если совпадение было найдено, то grep возвращает код завершения -- 0, это может оказаться полезным при выполнении поиска в условных операторах ( в таких случаях особый интерес может представлять ключ -q, который подавляет вывод).
SUCCESS=0 # если найдено совпадение word=Linux filename=data.file grep -q "$word" "$filename" # "-q" -- подавляет вывод на stdout. if [ $? -eq $SUCCESS ] then echo "Образец $word найден в $filename" else echo "Образец $word в файле $filename не найден" fi
Пример 29-6 -- пример поиска заданного образца в системном журнале, с помощью grep.
Пример 12-12. Сценарий-эмулятор "grep"
#!/bin/bash # grp.sh: Очень "грубая" реализация 'grep'. E_BADARGS=65 if [ -z "$1" ] # Проверка наличия аргументов. then echo "Порядок использования: `basename $0` pattern" exit $E_BADARGS fi echo for file in * # Обход всех файлов в $PWD. do output=$(sed -n /"$1"/p $file) # Подстановка команд. if [ ! -z "$output" ] # Что произойдет, если кавычки вокруг "$output" убрать? then echo -n "$file: " echo $output fi # эквивалент: sed -ne "/$1/s|^|$: |p" echo done echo exit 0 # Упражнения: # --------- # 1) Добавьте вывод символов перевода строки, если найдено более одного совпадения в любом из файлов. # 2) Добавьте обработку различных ключей.
fgrep -- то же самое, что и grep -F. Эта команда выполняет поиск строк символов (не регулярных выражений), что несколько увеличивает скорость поиска.
Утилита agrep имеет более широкие возможности поиска приблизительных совпадений. Образец поиска может отличаться от найденной строки на указанное число символов.
Для поиска по сжатым файлам следует использовать утилиты zgrep, zegrep или zfgrep. Они с успехом могут использоваться и для не сжатых файлов, но в этом случае они уступают в скорости обычным grep, egrep и fgrep. Они очень удобны при выполнении поиска по смешенному набору файлов -- когда одни файлы сжаты, а другие нет.
Команда look очень похожа на grep, и предназначена для поиска по "словарям" -- отсортированным файлам. По-умолчанию, поиск выполняется в файле /usr/dict/words, но может быть указан и другой словарь.
Пример 12-13. Поиск слов в словаре
#!/bin/bash # lookup: Выполняется поиск каждого слова из файла в словаре. file=words.data # Файл с искомыми словами. echo while [ "$word" != end ] # Последнее слово в файле. do read word # Из файла, потому, что выполнено перенаправление в конце цикла. look $word > /dev/null # Подавление вывода строк из словаря. lookup=$? # Код возврата команды 'look'. if [ "$lookup" -eq 0 ] then echo "Слово \"$word\" найдено." else echo "Слово \"$word\" не найдено." fi done /dev/null then echo "Слово \"$word\" найдено." else echo "Слово \"$word\" не найдено." fi doneСкриптовые языки, специально разработанные для анализа текстовых данных.
Неинтерактивный "потоковый редактор" . Широко используется в сценариях на языке командной оболочки.
Утилита контекстного поиска и преобразования текста, замечательный инструмент для извлечения и/или обработки полей (колонок) в структурированных текстовых файлах. Синтаксис awk напоминает язык C.
wc -- "word count" , счетчик слов в файле или в потоке:
bash $ wc /usr/doc/sed-3.02/README [20 строк 127 слов 838 символов]wc -w подсчитывает только слова.
wc -l подсчитывает только строки.
wc -c подсчитывает только символы.
wc -L возвращает длину наибольшей строки.
Подсчет количества .txt -файлов в текущем каталоге с помощью wc:
$ ls *.txt | wc -l # Эта команда будет работать, если ни в одном из имен файлов "*.txt" нет символа перевода строки. # Альтернативный вариант: # find . -maxdepth 1 -name \*.txt -print0 | grep -cz . # (shopt -s nullglob; set -- *.txt; echo $#) # Спасибо S.C.Подсчет общего размера файлов, чьи имена начинаются с символов, в диапазоне d - h
bash$ ' 71832От переводчика: в случае, если у вас локаль отлична от "C", то вышеприведенная команда может не дать результата, поскольку wc вернет не слово "total", в конце вывода, а "итого". Тогда можно попробовать несколько измененный вариант:
bash$ ' 71832Использование wc для подсчета количества вхождений слова "Linux" в основной исходный файл с текстом этого руководства.
bash$ 50Отдельные команды располагают функциональностью wc в виде своих ключей.
. | grep foo | wc -l # Часто встречающаяся конструкция, которая может быть сокращена. . | grep -c foo # Ключ "-c" ("--count") команды grep. # Спасибо S.C.Замена одних символов на другие.
В отдельных случаях символы необходимо заключать в кавычки и/или квадратные скобки. Кавычки предотвращают интерпретацию специальных символов командной оболочкой. Квадратные скобки должны заключаться в кавычки.
Команда tr "A-Z" "*" или tr A-Z \* заменяет все символы верхнего регистра в filename на звездочки (вывод производится на stdout). В некоторых системах этот вариант может оказаться неработоспособным, тогда попробуйте tr A-Z '[**]'.
Ключ -d удаляет символы из заданного диапазона.
echo "abcdef" # abcdef echo "abcdef" | tr -d b-d # aef tr -d 0-9bash$ XКлюч -c "complement" заменит символы в соответствии с шаблоном. Этот ключ воздействует только на те символы, которые НЕ соответствуют заданному шаблону.
bash$ +c+d+b++++bash$ ----2--1Пример 12-14. toupper: Преобразование символов в верхний регистр.
#!/bin/bash # Преобразование символов в верхний регистр. E_BADARGS=65 if [ -z "$1" ] # Стандартная проверка командной строки. then echo "Порядок использования: `basename $0` filename" exit $E_BADARGS fi tr a-z A-ZПример 12-15. lowercase: Изменение имен всех файлов в текущем каталоге в нижний регистр.
#! /bin/bash # # Изменит все имена файлов в текущем каталоге в нижнй регистр. # for filename in * # Обход всех файлов в каталоге. do fname=`basename $filename` n=`echo $fname | tr A-Z a-z` # Перевести символы в нижний регистр. if [ "$fname" != "$n" ] # Переименовать только те файлы, имена которых изменились. then mv $fname $n fi done exit 0 # Сироки приведенные ниже не будут исполняться, поскольку выше стоит команда "exit". #--------------------------------------------------------# # Запустите эту часть сценария, удалив строки , стоящие выше. # Сценарий, приведенный выше, не работает с именами файлов, содержащими пробелы или символы перевода строки. # В связи с этим, Stephane Chazelas предложил следующий вариант: for filename in * # Нет необходимости использовать basename, # поскольку "*" возвращает имена, не содержащие "/". do n=`echo "$filename/" | tr '[:upper:]' '[:lower:]'` # символьные классы POSIX. # Завершающий слэш добавлен для того, чтобы символ перевода строки # не был удален при подстановке команды. # Подстановка переменной: n=$ # Удаление завершающего слэша, добавленного выше. [[ $filename == $n ]] || mv "$filename" "$n" # Проверка -- действительно ли изменилось имя файла. done exit 0Пример 12-16. du: Преобразование текстового файла из формата DOS в формат UNIX.
#!/bin/bash # du.sh: Преобразование текстового файла из формата DOS в формат UNIX. E_WRONGARGS=65 if [ -z "$1" ] then echo "Порядок использования: `basename $0` filename-to-convert" exit $E_WRONGARGS fi NEWFILENAME=$1.unx CR='\015' # Возврат каретки. # Строки в текстовых файлах DOS завершаются комбинацией символов CR-LF. tr -d $CR < $1 >$NEWFILENAME # Удалить символы CR и записать в новый файл. echo "Исходный текстовый файл: \"$1\"." echo "Преобразованный файл: \"$NEWFILENAME\"." exit 0Пример 12-17. rot13: Сверхслабое шифрование по алгоритму rot13.
#!/bin/bash # rot13.sh: Классический алгоритм шифрования rot13, # который способен "расколоть" даже 3-х летний ребенок. # Порядок использования: ./rot13.sh filename # или ./rot13.shПример 12-18. Более "сложный" шифр
#!/bin/bash # crypto-quote.sh: Ограниченное шифрование # Шифрование ограничивается простой заменой одних алфавитных символов другими. # Результат очень похож на шифры-загадки key=ETAOINSHRDLUBCFGJMQPVWZYXK # Здесь, "key" -- ни что иное, как "перемешанный" алфавит. # Изменение ключа "key" приведет к изменению шифра. # Конструкция 'cat "$@"' позволяет вводить данные как со stdin, так и из файла. # Если используется stdin, то ввод должен завершаться комбинацией Control-D. # Иначе, в командной строке, сценарию должно быть передано имя файла. cat "$@" | tr "a-z" "A-Z" | tr "A-Z" "$key" # | в верхний регистр | шифрование # Такой прием позволяет шифровать как символы в верхнем регистре, так и в нижнем. # Неалфавитные символы остаются без изменений. # Попробуйте зашифровать какой либо текст, например # "Nothing so needs reforming as other people's habits." # --Mark Twain # # Результат будет: # "CFPHRCS QF CIIOQ MINFMBRCS EQ FPHIM GIFGUI'Q HETRPQ." # --BEML PZERC # Для дешифрации можно использовать следующую комбинацию: # cat "$@" | tr "$key" "A-Z" # Этот нехитрый шифр может быть "взломан" 12-ти летним ребенком #+ с помощью карандаша и бумаги. exit 0Различные версии tr
Утилита tr имеет две, исторически сложившиеся, версии. BSD-версия не использует квадратные скобки ( tr a-z A-Z), в то время как SysV-версия использует их ( tr '[a-z]' '[A-Z]'). GNU-версия утилиты tr напоминает версию BSD, но диапазоны символов обязательно должны заключаться в квадратные скобки.
Очень простая утилита форматирования текста, чаще всего используемая как фильтр в конвейерах для того, чтобы выполнить "перенос" длинных строк текста.
Пример 12-19. Отформатированный список файлов.
#!/bin/bash WIDTH=40 # 40 символов в строке. b=`ls /usr/local/bin` # Получить список файлов. echo $b | fmt -w $WIDTH # То же самое можно выполнить командой # echo $b | fold - -s -w $WIDTH exit 0Эта утилита с обманчивым названием удаляет из входного потока символы обратной подачи бумаги (код ESC 7). Она так же пытается заменить пробелы на табуляции. Основная область применения утилиты col -- фильтрация вывода отдельных утилит обработки текста, таких как groff и tbl.
Форматирование по столбцам. Эта утилита преобразует текст, например какой либо список, в табличное, более "удобочитаемое" , представление, вставляя символы табуляции по мере необходимости.
Пример 12-20. Пример форматирования списка файлов в каталоге
#!/bin/bash # За основу сценария взят пример "man column". (printf "PERMISSIONS LINKS OWNER GROUP SIZE DATE TIME PROG-NAME\n" \ ; ls -l | sed 1d) | column -t # Команда "sed 1d" удаляет первую строку, выводимую командой ls, #+ (для локали "С" это строка: "total N", #+ где "N" -- общее количество файлов. # Ключ -t, команды "column", означает "табличное" представление. exit 0Утилита удаления колонок. Удаляет колонки (столбцы) сиволов из файла и выводит результат на stdout. colrm 2 4 -- удалит символы со 2-го по 4-й включительно, в каждой строке в файле filename.
Нумерует строки в файле. nl filename -- выведет файл filename на stdout, и в начале каждой строки вставит ее порядковый номер, счет начинается с первой непустой строки. Если файл не указывается, то принимается ввод со stdin.
Вывод команды nl очень напоминает cat -n, однако, по-умолчанию nl не нумерует пустые строки.
Пример 12-21. nl: Самонумерующийся сценарий.
#!/bin/bash # Сценарий выводит себя сам на stdout дважды, нумеруя строки сценария. # 'nl' вставит для этой строки номер 3, поскольку она не нумерует пустые строки. # 'cat -n' вставит для этой строки номер 5. nl `basename $0` echo; echo # А теперь попробуем вывести текст сценария с помощью 'cat -n' cat -n `basename $0` # Различия состоят в том, что 'cat -n' нумерует все строки. # Обратите внимание: 'nl -ba' -- сделает то же самое. exit 0Подготовка файла к печати. Утилита производит разбивку файла на страницы, приводя его в вид пригодный для печати или для вывода на экран. Разнообразные ключи позволяют выполнять различные манипуляции над строками и колонками, соединять строки, устанавливать поля, нумеровать строки, добавлять колонтитулы и многое, многое другое. Утилита pr соединяет в себе функциональность таких команд, как nl, paste, fold, column и expand.
pr -o 5 --width=65 fileZZZ | more -- выдаст хорошо оформленное и разбитое на страницы содержимое файла fileZZZ.
Хочу особо отметить ключ -d, который выводит строки с двойным интервалом (тот же эффект, что и sed -G).
GNU утилита, предназначена для нужд локализации и перевода сообщений программ, выводимых на экран, на язык пользователя. Не смотря на то, что это актуально, прежде всего, для программ на языке C, тем не менее gettext с успехом может использоваться в сценариях командной оболочки для тех же целей. См. info page.
Утилита преобразования текста из одной кодировки в другую. В основном используется для нужд локализации.
Может рассматриваться как разновилность утилиты iconv, описанной выше. Универсальная утилита для преобразования текстовой информации в различные кодировки.
TeX и Postscript -- языки разметки текста, используемые для подготовки текста к печати или выводу на экран.
TeX -- это сложная система подготовки к печати, разработанная Дональдом Кнутом (Donald Knuth). Эту утилиту удобнее использовать внутри сценария, чем в командной строке, поскольку в сценарии проще один раз записать все необходимые параметры, передаваемые утилите, для получения необходимого результата.
Ghostscript ( gs) -- это GPL-версия интерпретатора Postscript.
groff -- это еще один язык разметки текста и форматированного вывода. Является расширенной GNU-версией пакета roff/troff в UNIX-системах.
tbl -- утилита обработки таблиц, должна рассматриваться как составная часть groff, так как ее задачей является преобразование таблиц в команды groff.
eqn -- утилита преобразования математических выражений в команды groff.
lex -- утилита лексического разбора текста. В Linux-системах заменена на свободно распространяемую утилиту flex.
yacc -- утилита для создания синтаксических анализаторов, на основе набора грамматик, задаваемых разработчиком. В Linux-системах, эта утилита заменена на свободно распространяемую утилиту bison.
Примечания
Это верно только для GNU-версии команды tr, поведение этой команды, в коммерческих UNIX-системах, может несколько отличаться.
| Назад | К началу | Вперед |
| Команды для работы с датой и временем | Наверх | Команды для работы с файлами и архивами |
Linux.yaroslavl.ru
Bash - означает Bourne Again Shell и является оболочкой проекта GNU. Она будет оболочкой по умолчанию в операционной системе GNU. Как следует из названия, Bash основывается на оболочке Bourne, sh, созданной Стефеном Борном (Stephen Bourne).
Bash включает в себя свойства оболочек с (csh), tc (tcsh) и Korn (ksh), при этом лишь немногим отличаясь от оболочки Bourne, sh. Так, большинство сценариев sh могут выполняться в оболочке без каких-либо изменений. Различия между bash и sh обусловлены тем, что bash является реализацией спецификации IEEE POSIX 1003.2/ISO 9945.2 Shell and Tools.
Bash была написана Брайаном Фоксом (Brian Fox) (bfox@ gnu.ai.mit.edu) из Free Software Foundation, и в настоящее время поддерживается Четом Рэйми (Chet Ramey) из Case Western Reserve University.
Bash распространяется бесплатно, т.е. любой имеет право использовать и распространять ее при определенных условиях, но она не является общественным достоянием. Эта оболочка распространяется в соответствии с лицензией GNU General Public License, копия которой поставляется в распространяемом пакете. Как указывается в лицензии, bash поставляется без каких-либо гарантийных обязательств, поэтому автор и поддерживающий в настоящее время не должны рассматриваться в качестве источников технической поддержки.
На момент написания этой книги последней версией bash была 2.0.0, выпущенная 31 декабря 1996 г., но в настоящее время проходит бета-тестирование версия 2.0.1. Предшественницей версии 2.0.х была версия 1.14.7, выпущенная 28 августа 1996 г.
В этой главе основное внимание уделяется версии 2.0.0, поскольку в ней реализуются некоторые новые свойства, в том числе одномерные множества и встроенная shopt Если не оговаривается иное, все примеры будут выполняться и в среде версии 1.14.7.
Bash доступна посредством анонимного ftp на любом из архивных узлов GNU, в том числе на основном архивном узле GNU, ftp://prep.ai.mit.edu/pub/gnu/bash-2.0.tar.gz. Ее можно также получить с компьютера Чета Рэйми, ftp://slc2.ins.cwru.edu/pub/dist/bash-2.0.tar.gz.
Bash обладает замечательной переносимостью; ее можно скомпилировать из исходников в большинстве систем UNIX, поскольку многие из зависимых от среды переменных определяются во время компиляции. В качестве оболочки Bash может быть перенесена в несколько отличных от UNIX платформ, в том числе QNX, Minix, Windows 95 и Windows NT. Bash является оболочкой по умолчанию для BeOS.
Сборник часто задаваемых вопросов (FAQ) с ответами по Bash можно найти на ftp://slc2.ins.cwru.edu/ pub/bash/FAQ.
Дополнительная информация по bash может быть получена из таких групп новостей Usenet, как gnu.bash.bug и comp.unix.shell.
Bash обладает несколькими свойствами, которые делают ее прекрасной оболочкой для использования как новичками, так и экспертами. Многие ее свойства аналогичны свойствам оболочек csh, tcsh и ksh, что облегчает переход с Bash на одну из этих оболочек и обратно.
Определения
Следующие термины определяются в man-странице BASH(l) и в этом же контексте используются в данной главе:
Инсталляция Bash
Оболочка Bash доступна во многих системах, но для ее инсталляции следует выполнить процедуру, описанную в данном разделе.
Для установки и инсталляции bash требуются следующие приложения:
Чтобы убедиться, что эти программы доступны, используйте команду whereis.
Получив файл bash-2.0.tar.gz, для построения bash выполните следующую процедуру:
tar -xvf bash-2.0.tar
При этом создается каталог bash-2.0, в который помещаются исходные файлы.
4. С помощью команды cd выполните переход в каталог с исходными файлами:
5. Сконфигурируйте исходное дерево для своего компьютера:
Сценарий оболочки configure делает попытку определить правильные значения для зависимых от системы переменных, используемых во время компиляции, а затем создает соответствующий makefile, а также следующие файлы:
config.h - заголовочный файл, содержащий системно-зависимые определения;
config.status - сценарий оболочки, который воссоздает текущую конфигурацию;
config.cache - файл, который сохраняет результаты тестирования для ускорения реконфигурирования;
config.log - файл, содержащий вывод компилятора.
Конфигурация может быть настроена, но для большинства случаев инсталляции конфигурация по умолчанию вполне подходит. Команда конфигурирования имеет опцию справки, которая подробно описывает остальные опции конфигурирования:
Одна из опций конфигурирования определяет каталог, в котором bash должна быть инсталлирована вместо каталога по умолчанию /usr/local:
В некоторых устаревших версиях System V, если команда configure выполняется из csh, csh может пытаться выполнить configure как сценарий оболочки csh. Во избежания этого следует использовать:
Процесс конфигурирования может занять некоторое время: около 15 минут в Sun Spare 10 и около 10 минут в Sun Ultra 1.
6. Скомпилируйте bash:
По умолчанию команда make будет использовать компилятор gcc, даже если обычный ее инсталлирован и работает. Чтобы использовать ее:
make также занимает длительное время: от 20 до 25 минут в Sun Spare 10 и от 15 до 20 минут в Sun Ultra 1.
7. Протестируйте построение (не обязательно, но рекомендуется):
make tests
Тем самым будут созданы и запущены тесты, которые поставляются с исходным кодом для подтверждения надлежащей работы оболочки bash. При выявлении каких-либо проблем bash, по всей видимости, должна быть скомпилирована заново. После завершения тестов имеет смысл вызвать только что скомпилированную оболочку и выполнить несколько команд для подтверждения корректности работы оболочки.
8. Удалите из исполняемой программы отладочные символы (это не обязательно, но рекомендуется):
Чтобы увидеть, как влияет команда strip на размеры исполняемого модуля оболочки bash, выполните следующие команды:
ls -l bash ; strip bash ; ls -1 bash
Данная операция уменьшает размер исполняемого модуля примерно на 1 Мб в Sun Spare. Реальное уменьшение размера зависит от используемого компилятора, заданных для него опций, аппаратной платформы и т.п.
9. Инсталлируйте оболочку bash и ее документацию:
В результате bash помещается в каталог по умолчанию, /usr/local. Чтобы посмотреть, что выполняется при инсталляции по умолчанию, не инсталлируя оболочку, выполните команду:
make -n install Для инсталляции bash в каталог, отличный от заранее заданного:
make install prefix=[directory]
Оболочка bash может быть вызвана в нескольких различных режимах. Основными являются интерактивный и неинтерактивный режимы.
Интерактивные оболочки
Интерактивная оболочка - это оболочка, стандартный ввод и вывод которой связаны с терминалом. Тремя основными типами интерактивных оболочек являются регистрирующая (login), нерегистрирующая ( non -login) и ограниченная (restricted) оболочки.
Bash определяет, является ли оболочка интерактивной, используя вызов библиотеки isatty. В инициализационных файлах и сценариях интерактивные оболочки могут быть определены посредством использования команды tty -s или test -t, которая возвращает 0 (истинно), если стандартным вводом является tty. Интерактивные оболочки устанавливают переменную $PS1, поэтому проверка ее существования - еще один распространенный метод идентификации интерактивных оболочек.
Когда bash вызывается в качестве регистрирующей оболочки, она делает попытку считать несколько Инициализационных файлов и сообщает о всех встретившихся ошибках. Если инициализационные файлы
не существуют, то используется среда, определяемая по умолчанию. Сперва bash считывает и выполняет команды в файле /etc/profile. Затем она проверяет наличие файлов ~/.bash_profile, ~/.bashLogin и ~/.profile и выполняет команды из первого файла. Для предотвращения считывания любых инициализационных файлов оболочке bash может быть передана опция -noprofile. Когда регистрирующая оболочка осуществляет выход, если файл ~/.bashlogout существует, bash будет считывать и выполнять команды из него. Только регистрирующие оболочки будут считывать файл ~/.bashlogout при выходе.
Когда нерегистрирующая интерактивная оболочка запускается, bash считывает и выполняет команды из файла ~/.bashrc. Нерегистрирующую интерактивную оболочку можно заставить считывать различные инициализационные файлы посредством использования опции -rcfile file. Считывание любых инициализационных файлов может быть запрещено посредством опции -n огс.
Посредством опции -posix bash также может быть запущена в режиме posix (Portable Operating System for UNIX). В этом режиме bash сперва проверяет, определена ли переменная $ENV. Если да, то bash читает из $ENV имя файла, а затем считывает и выполняет команды из этого файла. При вызове в режиме posix оболочка bash не будет считывать никакие другие файлы запуска. В этом режиме поведение оболочки несколько изменяется в соответствии со стандартом POS IX.
В некоторых системах, в которых bash называется sh (например, Linux), bash будет запускаться подобно sh, а затем входить в режим posix. Регистрирующая bash, вызванная как sh, будет пытаться считать и выполнить команды в /etc/profile, а затем в ~/.profile. Опция -noprofile предотвратит считывание других инициализационных файлов. Если нерегистрирующая оболочка вызывается как sh, ее поведение при запуске аналогично поведению в режиме posix.
Последний представляющий интерес интерактивный режим - ограниченный режим. Оболочка bash может быть запущена в ограниченном режиме посредством опции - r или вызвана как rbash. В ограниченном режиме bash ведет себя как обычно, за исключением того, что не допускает некоторые операции, такие как смена каталогов, изменение переменных $SHELL или $РАТН, запуск ехес, выполнение команд, содержащих символ / и использование перенаправления. Ограниченный режим недоступен в bash 1-х.
Неинтерактивные оболочки
Неинтерактивные оболочки bash чаще всего используются для выполнения сценариев оболочки. Неинтерактивная оболочка также запускается, когда bash вызывается с опцией -с. Когда неинтерактивная оболочка bash запускается, она ищет переменную среды $BASH_ENV. Если она существует, bash пытается считать и выполнить команды из файла, название которого содержится в этой переменной. Поведение оболочки аналогично поведению при выполнении команды
if [ -n "$BASH_ENV" ] ; then . "$BASH_ENV"; fi
Имя файла, которое определяется переменной $BASH_ENV, не ищется в $РАТН.
Опции вызова
Как отмечалось выше, bash может вызываться с несколькими одно- и многосимвольными опциями. Ниже приводится описание этих опций и выполняемых ими функций:
Использование bash в качестве регистрирующей оболочки
Наиболее распространенный способ смены регистрирующей оболочки - использование команды смены оболочки chsh. В некоторых системах, в которых chsh недоступна, для смены оболочки может использоваться команда passwd -s или passwd -e. В других системах (в которых используется служба NIS) для смены оболочки должна использоваться команда ypchsh. Во многих системах (например, SunOS 5.5.x) полный путь к исполняемому модулю оболочки bash должен быть включен в файл /etc/shells, прежде чем bash можно будет указать в качестве допустимой регистрирующей оболочки.
Если регистрирующую оболочку, определенную по умолчанию, невозможно заменить, bash все же может быть запущена в качестве регистрирующей оболочки путем использования альтернативных файлов запуска оболочки. Если регистрирующая оболочка по умолчанию --csh или tcsh, a bash размещена в каталоге /usr/ local/bin/bash, то добавление следующей строки в файл ~/.login в начальном каталоге пользователя позволит bash запускаться в качестве регистрирующей оболочки:
if ( -f /usr/local/bin/bash ) exec /usr/local/bin/bash --login
Лучше вызывать bash в файле ~/.login, т.к. он считывается только во время входа в систему в отличие от файла ~/.cshrc, который считывается при каждом запуске csh. Выполнение bash в файле ~/.cshrc может привести к проблемам при попытке запуска сценариев csh. Лучший способ вызова bash в файле ~/.cshrc - запуск ее только в том случае, если csh интерактивна:
if ( $?prompt ) exec /usr/local/bin/bash -login
Если регистрирующей оболочкой является sh или ksh, необходимо выполнить два действия. Во-первых, в файл ~/.profile должна быть вставлена строка, аналогичная следующей:
[ -f /usr/local/bin/bash ] && exec /usr/local/bin/bash -login
Во-вторых, должен быть создан пустой файл ~/.bash_profile, чтобы помешать выполняющейся оболочке bash делать попытки считывания файла ~/.profile и повторного выполнения самой себя. Либо в файл ~/.profile можно было бы вставить следующее:
: "Bash already running";;
При использовании оператора case в файле ~/.profile пустой файл ~/.bash_profile создавать не нужно.
Bash поддерживает синтаксис, аналогичный синтаксису sh и ksh.
Bash 2.0 поддерживает как скалярные переменные, так и массивы. Для установки переменных в bash используется стандартный оператор присваивания оболочки sh:
имя=значение
Переменные-массивы можно определять двумя способами. В первой форме определяется и инициализируется единственный элемент:
имя [индекс] =значение
Вторая форма может использоваться для инициализации нескольких элементов (но не всего массива):
имя=( значение1 . значение п)
В этой форме используются последовательные индексы, начиная с 0. Например, оператор myarray=(derri terry mike gene) эквивалентен операторам
При установке нескольких элементов массива, индекс массива может быть помещен перед значением, этому третий способ инициализации элементов массива будет выглядеть так:
myarray=([0]=derri [3]-gene [2]=mike [1]=terri)
He существует ограничений ни на максимальное значение индексов массива, ни на последовательность использования.
Bash также поддерживает две встроенные команды declare и typeset, которые обеспечивают изменение атрибутов переменных. Эти две команды являются синонимами и допускают определение переменных как массивов, переменных целого типа и переменных только для чтения, а также позволяют помечать переменные для экспорта. Следует использовать команду declare, поскольку в настоящее время команда typeset является устаревшей.
При использовании в арифметических выражениях, переменная помеченная как целая, ведет себя аналогично переменным типа hit языка программирования С. Переменные только для чтения, будучи присвоены , не могут быть присвоены повторно; фактически, это константы. Команды declare и typeset воспринимают следующие опции:
declare -i foo # переменная foo будет обрабатываться как переменная целого типа
declare +i bar # переменная bar будет обрабатываться обычным образом
- [-/ + ] г Устанавливает для переменной атрибут только для чтения.
declare -r foo # значение переменной foo не может быть изменено
- [-/+] х Устанавливает/отменяет установку атрибута экспорта для переменной declare -х foo # переменная foo помечена для экспорта declare -х foo # переменная foo не будет экспортироваться
-р variable Показывает атрибуты переменной variable. Если переменная не указана, отображаются все переменные и их значения. Эта опция недоступна в bash l.x.
Экспорт переменных для использования в среде оболочки аналогичен экспорту в sh. Для пользователей csh и tcsh это аналогично созданию переменных среды с помощью команды setenv. Пометка переменной i экспорта означает, что она доступна для использования в среде дочернего процесса оболочки. Экспорт может быть выполнен двумя способами:
export name
export name=value
Первая форма помечает именованную переменную для экспорта. Вторая форма присваивает именованной переменной заданное значение, а затем помечает эту переменную для экспорта. Может быть указано бол ee одного имени пате или пар name-lvalue. Переменные могут быть неэкспортируемыми, если указана опция - n . Ели экспорт вызывается самостоятельно или с опцией -р, будет выводиться список экспортированных переменных. Оба следующих примера представляют допустимый способ экспорта переменной PATH:
В дополнение к этим атрибутам bash позволяет посредством использования встроенной команды local печать переменные как локальные. Это означает, что отдельный экземпляр переменной создается для функции, в которой используется команда local (эта команда может использоваться только в функциях). Существуют две формы команды:
Первая форма создает переменную с данным именем и помечает ее как локальную. Вторая создает песенную с заданным именем и заданным значением. Если команда local вызывается без параметра name или name=value, она будет выводить список существующих в данный момент локальных переменных. Во время запуска bash автоматически инициализирует несколько переменных, некоторые из которых 1адают специальными свойствами до тех пор, пока их установка не отменена. Ниже приводится сокращенный перечень этих переменных оболочки:
Следующие переменные используются оболочкой bash, но первоначально инициализируются другими программами:
Кроме этих типов переменных, bash поддерживает также два дополнительных типа параметров: позиционный и специальный. Значения обоих этих параметров присваиваются оболочкой bash, но только значения позиционных параметров могут изменяться.
Позиционные параметры обозначаются одной или несколькими цифрами, начиная с 1; доступ к ним можно получать индивидуально, передавая номер аргумента в качестве имени переменной. Если номер аргумента состоит из нескольких цифр, необходимо использовать фигурные скобки. Например, доступ к первому аргументу можно получить посредством $1, но для одиннадцатого аргумента необходимо использовать $.
Существует несколько специальных параметров, связанных с позиционными параметрами:
Позиционные параметры - это аргументы, с которыми вызывается функция или сценарий оболочки. означает, что значение $1 различно внутри и снаружи функции.
Остальные специальные параметры связаны с выполнением команд и освещаются в разделе "Переменные истории".
Инициализация как переменных, так и массивов, может быть отменена с помощью команды unset:
Опция -v во второй форме используется для указания команде unset того, что имя является переменной оболочки. Эта опция необязательна.
Интерпретация и подстановка значений
Когда bash встречает оператор присваивания в форме:
значение value присваивается переменной name после выполнения интерпретации символов тильды, переменных и строк. Перед присваиванием значения оболочка bash будет также выполнять подстановку команд, арифметические вычисления и удаление кавычек.
Интерпретация тильды выполняется, когда тильда (~) является первым символом в слове. В этом случае bash обрабатывает символы, следующие за тильдой, как регистрационное имя пользователя и пытается выполнить подстановку начального каталога, связанного с ними. Если тильда появляется самостоятельно или за ней следует косая черта (/), а переменная $НОМЕ установлена, bash подставляет вместо тильды значение переменной $НОМЕ. В противном случае она замещает тильду начальным каталогом текущего пользователя. Если вводится ^+, bash замещает их значением переменной $PWD, т.е. текущим каталогом. Символы ~- замещаются значением переменной $OLDPWD - предшествующим рабочим каталогом. Если ни одним из этих способов раскрытый тильду невозможно интерпретировать, bash оставляет тильду без изменений.
Оболочка bash выполняет подстановку значения переменной, когда встречает символ $. Простейшими формами являются
В этих примерах значение переменной $b аг присваивается переменной $foo. Во второй форме фигурные скобки используются для явного указания программе синтаксического анализа, где заканчивается имя переменной. Например,
осуществляет вывод значения переменной $footh, в то время как
выполняет вывод строки 24th, которая является значением переменной foo с добавленными символами "th". Подстановка значений переменных может также выполняться несколькими более сложными способами:
Оболочка bash поддерживает также подстановку подстрок переменных, что может использоваться для присвоения частей значения одной переменной другой:
offset - начальная позиция в $bar, a length - количество символов, подлежащих получению. Если длина length не указана, возвращаются все символы, следующие за offset. Подстановка команды выполняется, когда команда вводится в виде
Обе формы замещаются выводом команды. Если только команда не заключается в двойные кавычки, каждая строка вывода команды становится отдельным словом. В случае наличия двойных кавычек, вывод обрабатывается как единое слово, содержащее символы новых строк.
Арифметическое вычисление выполняется, когда встречается следующая конструкция:
выражение будет вычисляться в соответствии с правилами языка программирования С, и результат будет подставлен. Например,
foo=$(( ((5 + 3*2) - 4) / 2))
переменная foo получит значение, равное 3 (а не 3.5, т.к. данное число является целым).
Удаление кавычек выполняется после того, как выполнены все остальные подстановки, при этом удаляются все остающиеся символы, не связанные с кавычками: \ (обратная косая черта), ' (одиночная кавычка) и " (двойная кавычка).
Bash выполняет еще два типа интерпретации - интерпретацию фигурных скобок и путей. Это применяется прежде всего к командам, вводимых в командной строке. Фигурные скобки в основном используются для создания нескольких строк, имеющих общие элементы. Общей формой является
Оболочка bash раскрывает эту строку в строки, ограниченные квадратными скобками [], каждая из которых содержит одну из строк, перечисленных в фигурных скобках, имеющую префикс stringx и суффикс stringy. Строка префикса или ведущая строка может быть опущена, но минимальное количество строк в фигурных скобках, < >, равно одной, а элементы в фигурных скобках должны разделяться запятыми. Фигурные скобки в данном контексте могут применяться в ситуациях, подобных следующим:
Эти строки эквивалентны
mkdir -p /usr/local/bin/usr/local/lib/usr/local/man/manl/usr/local/man/man2/usr/local/man/man3/ usr/local/man/etc
Интерпретация фигурных скобок может применяться в сочетании с интерпретацией пути, что позволяет вставлять в пути некоторые специальные символы. Если эти символы вставлены, слово, в котором они присутствуют, считается шаблоном и замещается упорядоченным списком имен файлов, соответствующих шаблону. Специальными символами являются:
Кавычки используются для отмены значения определенных символов, которые оболочка обрабатывает специальным образом. Кавычки могут использоваться для создания строк путем помещения ряда символов в одиночные О или двойные (") кавычки. Например, следующие строки образованы с помощью кавычек:
"Hello, I am a string"
Одиночный символ также может быть помещен в кавычки, если ему предшествует обратная наклонная черта (\). Кроме того, кавычками отменяются значения следующих символов:
Использование кавычек в bash объединяет правила использования кавычек, имеющиеся в sh и csh. Значения всех специальных символов в строках, заключенных в одиночные кавычки, 'string', отменяются. В строках, заключенных в двойные кавычки, "string", отменяются значения всех специальных символов, за исключением !, $, \ \ и <. Обратная наклонная черта (\) отменяет специальное значение символов.
Кроме кавычек, bash распознает несколько стандартных escape-последовательностей, знакомых программистам -работающим на языке С, например \t для символа табуляции и \ n для символа новой строки.
Простые команды
Простыми командами в bash являются присваивания значений переменным, имена отдельных команд или имена отдельных команд, вывод которых перенаправляется. Bash обрабатывает первое слово командной строки в качестве команды, подлежащей выполнению, а остальные слова - в качестве аргументов команды, если только команде не предшествуют присвоения переменных. Простая команда будет возвращать свое состояние выхода или 128+SIG, если она прерывается сигналом с номером SIG.
Несколько простых команд могут быть объединены с помощью символов каналов, образуя конвейер. commandl | command2 | .
Символ канала | соединяет стандартный вывод команды command 1 со стандартным вводом команды command2 и т.д. Каждая команда выполняется в качестве отдельного процесса. Состояние выхода конвейера - это состояние выхода последней команды. Примерами конвейерных команд могут служить
tail -f /var/adm/messages | more
ps -ael | grep "$1110" ! more
В первом примере стандартный вывод команды tail передается стандартному вводу команды more, что позволяет просматривать вывод поэкранно. Во втором примере стандартный вывод команды ps соединяется со стандартным вводом команды grep, а стандартный вывод команды grep соединяется со стандартным вводом команды more, чтобы вывод команды grep можно было просматривать поэкранно. Третий пример ~ сложный, но иногда полезный для привилегированного пользователя, способ копировать файлы, не меняя их владельца.
Кроме конвейеров, команды могут выполняться в списках, когда несколько конвейеров объединятся с помощью операций ;, &, && или ||. Список может использоваться для последовательного выполнения команд и конвейеров:
commandl; command2; command3 .
commandl | command2; commands | command4 .
Обычно списки используются для таких задач, как
lpr foo; lpq;
ps -ael | head -1; ps -ael | grep "$UID"
которые не могут быть выполнены в одной команде.
Списки могут также использоваться для выполнения команд, основывающихся на состоянии выхода предыдущих команд, если применяются операции логического AND (И) или OR (ИЛИ):
Если используется операция логического AND, как в первом случае, команда command2 будет выполняться только если команда commandl возвратит состояние выхода равное 0. При использовании операции логического OR, как во втором случае, команда command2 будет выполняться только если команда commandl возвратит ненулевое состояние выхода. Логические операции часто используются вместо операторов if; эта форма должна казаться очевидной тем пользователям, которые знакомы с языком программирования С и его "ленивыми" логическими операторами.
Операция && обычно используется в ситуациях, подобных
mkdir foo && cd foo
где смена каталога может быть выполнена, только если каталог был успешно создан. А вот пример использования операции ||:
grep root /etc/passwd || echo "Help! No one in charge!"
Любой список может выполняться в среде текущей оболочки или в субоболочке. Заключение списка в фигурные скобки
приводит к тому, что список будет выполняться в текущей оболочке, а заключение его в круглые скобки
приводит к выполнению списка в субоболочке. Например, команда
выполняет список ps -ael | head -1; ps -ael | grep " $UID" в текущей оболочке, а затем передает вывод команде more. Этот же список можно было бы выполнить в субоболочке:
( ps -ael | head -1; ps -ael I grep " $UID " ; ) | more
но это, вероятно, не слишком удачная мысль, поскольку каждая выполняющаяся субоболочка занимает дополнительные системные ресурсы. Эффективней было бы выполнять все программы в текущей оболочке. Выполнение списков в субоболочках удобно, т.к. субоболочки, по-существу, делают все переменные локальными, а также потому, что субоболочки имеют собственные рабочие каталоги. Это иллюстрируется следующим примером:
pwd; ( cd /tmp ; pwd ) ; pwd;
Текущий рабочий каталог меняется только для субоболочки.
Перенаправление
Списки могут также содержать перенаправление ввода и вывода с использованием операций < и >. По умолчанию операция < перенаправляет стандартный ввод, а операция >- стандартный вывод, но операции перенаправления могут также использоваться для открытия и закрытия файлов. В общем случае перенаправление вывода имеет вид
Первая форма перенаправляет вывод команды command в файл file, а вторая перенаправляет вывод списка list в файл file. Например,
перенаправляет вывод команды date в файл now. Вывод списка также может быть перенаправлен.
перенаправит вывод всех команд date, uptime и who в файл mylog. Кроме такого перенаправления вывода, который переписывает файл вывода, существует добавляющее перенаправление вывода. Вывод будет добавляться к файлу, или файл будет создаваться, если он не существует, при использовании операции р. В общем случае добавляющее перенаправление вывода выглядит следующим образом:
list >> file
Чтобы файл mylog (в ранее приведенном примере) не удалялся при каждом добавлении данных, можно использовать следующее:
Оболочка bash допускает также, чтобы стандартный вывод и стандартный вывод ошибок перенаправлялись в один файл. В общем случае это делается следующим образом:
&> file >& file
Как утверждается в руководствах, первая форма предпочтительней, но все три являются эквивалентными. Третья форма работает посредством использования дескрипторов файлов стандартного вывода (дескриптор файла равен 1) и стандартных ошибок (дескриптор файла равен 2); по существу, она делает то же, что библиотечная функция dup2() языка С. Распространенная ситуация, когда требуется перенаправлять и стандартный вывод и стандартную ошибку, следующая
if type emacs &> /dev/null ; then
В данном случае только возвращаемое значение встроенной команды type представляет интерес, а ее вывод или любые сообщения об ошибках - нет, поэтому они перенаправляются в файл /dev/null.
Ввод также может быть перенаправлен аналогичным образом. В общем виде перенаправление ввода следующее:
В этом случае содержимое файла file станет вводом команды command. Например, следующая строка является обычным использованием перенаправления:
где вводом команды Mail, который становится телом почтового сообщения, будет файл Final_Exam_Answers. Перенаправления ввода находит дополнительное применение при создании документов Here, Общая форма документа Here следующая
Оболочка будет интерпретировать операцию р как инструкцию на считывание ввода до тех пор, пока не будет найдена строка," содержащая указанный ограничитель delimiter. Все строки ввода, включая строку, содержащую delimiter, передаются стандартному вводу команды command. Оболочка bash не выполняет никакой интерпретации данного ограничителя delimiter, но читает строки в документе Here. Например, для печати краткого списка URL можно было бы использовать следующий документ Here:
http: //www. csua.berkeley.edu/-"ranga/
Это обеспечивает удобную альтернативу созданию временных файлов. Для удаления символов табуляции в этом примере операции р может быть придана опция -.
Управление потоками
Оболочка bash обеспечивает два мощных механизма управления потоками: конструкции if-fi и case-esac. Оператор if обычно используется для условного выполнения команд, а оператор case обеспечивает выполнение любого числа последовательностей команд в зависимости от того, какой из нескольких шаблонов первым оказывается соответствующим указанной переменной. Часто проще создавать операторы if, чем операторы case, если в них используется соответствие переменной шаблону.
Общий синтаксис оператора if следующий: if list; then list; lelif list; then list; ] . [else list;] fi, что обычно записывается как:
elif list3 ; then
Операторы elif и else являются необязательными. Оператор if может содержать любое число операторов elif и может иметь только операторы if и elif. Списками в операторах if могут быть списки, описанные в предыдущем разделе.
В общем случае при интерпретации оператора if сперва вычисляется listl. Если код выхода списка listi равен 0, указывая на истинность условия, вычисляется list2 и оператор if осуществляет выход. В противном случае выполняется list3, а затем его код проверяется. Если list3 возвращает 0, то выполняется list4 и оператор if осуществляет выход. Если list3 возвращает ненулевое значение, выполняется list5. Простой пример использования оператора if показан ниже:
if uuencode koala.gif koala.gif > koala.uu ; then
echo "Encoded koala.gif to koala.uu"
echo "Error encoding koala.gif"
Строка "Encoded koala.gif to koala.uu" будет выводиться, если код выхода команды uuencode указывает на успешное выполнение. В противном случае будет выводиться сообщение об ошибке.
Чаще всего список list, включенный в оператор if, будет одной или несколькими командами test, которые могут вызываться в виде test expression или [expression]. После вычисления выражения expression команда test возвращает 0 (истинно) или 1 (ложно). Ниже приводится перечень наиболее часто используемых при выполнении команды test опций:
Примерами использования простого оператора if в сочетании с проверкой условий являются
if [ -d $HOME/bin ] ; then PATH="$PATH: $HOME/bin"; fi
if [ -s $HOME/.bash_aliai ] ; then . $HOME/bash_aliai ; fi
В первом примере проверка условия используется для определения того, существует ли каталог, после чего выполняется некоторое действие.
Во втором примере проверка используется для определения того, существует ли файл, имеющий ненулевой размер, перед выполнением любого действия.
Ниже приводятся еще два эквивалентные примера, демонстрирующие объединение проверок:
if [ -z "$DTHOME" ] && [ -d /usr/dt ] ; then DTHOME=/usr/dt ; fi
if [ -z "$DTHOME" -a -d /usr/dt ] ; then DTHOME=/usr/dt ; fi
Некоторые пользователи предпочитают первую форму, поскольку в ней более очевидно, какие проверки подлежат выполнению и каковы критерии вычисления. Другие предпочитают вторую форму, т.к. в ней команда [ используется только один раз и она может быть более эффективной.
Вторая форма управления потоками - конструкция case-esac. Общий синтаксис выглядит следующим образом: case word in [ pattern [ | pattern ] . ) list ;; ] рesac, но обычно это записывается как
case word in pattern) list ;;
в этой форме word - это либо строка, либо переменная, значение которой сравнивается с каждым шаблоном pattern, пока соответствие не будет найдено. Список list, следующий за совпадающим шаблоном, выполняется. Как только список выполнен, поток выполнения программы переключается на конец оператора case. Если ни одно совпадение не обнаружено, оболочка bash выполнит выход из оператора case. Некоторые действия по умолчанию могут выполняться посредством использования шаблона *, соответствующего любым значениям. Количество шаблонов не имеет значения, но должен существовать по меньшей мере один. Шаблоны могут использовать те же специальные символы, что и шаблоны для расширений путей, которые могут объединяться операцией OR (или), |. Символы ;; показывают оболочке bash, что список исчерпан, и аналогичны break в языке С. Ниже приведен пример простого оператора case
TERM=xterm ;;
Bash поддерживает три типа циклов: for, while и select. Цикл for используется, когда набор команд нужно просто выполнять повторно. Цикл while используется, когда набор команд должен выполняться до тех пор, пока определенное условие истинно. Общепринятое использование цикла select - обеспечение удобного интерфейса выбора.
Общий синтаксис цикла for следующий: for name [ in listi; ] do list2 ; done, но обычно это записывают как
for name in list1
В цикле for имя переменной устанавливается равным каждому элементу списка listi, а список list2 выполняется для каждого элемента списка listi. Если список не приводится, bash будет просматривать позиционные параметры. Если listi приведен в качестве слова, будет выполнена его интерпретация. Простой пример цикла for выглядит следующим образом:
for i in 123456789 10 do
Более распространенное применение цикла for показано ниже:
for files in -/.bash_*
echo "" >> $.html
chmod guo+r $.html
Цикл while имеет следующий общий синтаксис: while list1 ; do list2 ; done. Обычно это записывают как
В цикле while список list1 вычисляется каждый раз, и пока его значение истинно, список list2 выполняется. Это позволяет писать бесконечные циклы, имеющие /bin/true в качестве списка list1. Ниже приведен простой пример цикла while.
while [ $x -It 10 ]
Этот цикл while копирует свой вывод во ввод, подобно программе cat:
while read
Если используется перенаправление ввода, этот цикл запишет содержимое файла ввода в стандартный вывод, подобно программе cat.
Вариантом цикла while является цикл until:
В цикле until список list2 выполняется до тех пор, пока список list1 не становится истинным. Цикл until аналогичен циклу while в котором указано ! list1. Следующие циклы while и until эквивалентны:
x=1; while ! [ $х -де 10 ] do
x=l; until [ $x -де 10 ] do
Цикл select служит простым способом создания пронумерованных меню, из которых пользователи могут выбирать опции. Общий синтаксис цикла select выглядит как select name [ in list1; ] do list2 ; done и обычно записывается
select name in list1
В цикле select элементы в списке list1 выводятся в стандартную строку ошибки с номером в качестве префикса. Затем отображается приглашение и строка считывается. Если переменная $REPLY, содержащая значение считываемой строки, содержит номер отображаемого пункта, список list2 выполняется. В противном случае элементы списка list1 последовательно отображаются снова. Цикл select завершается, если считывается EOF (end of file - конец файла).
Следующий цикл select отображает нумерованный список файлов, находящихся в каталоге /tmp, и выполняет команду ls -1 по отношению к существующим файлам:
select file in /tmp/* QUIT
if [ -e $file ] ; then
Вывод будет аналогичен следующему:
1) /tmp/. 6) /tmp/job.control.ms
2) /tmp/.. 7) /tmp/job.control.ps
3) /tmp/.Xll-unix 8) /tmp/ps_data
4) /tmp/intro7.html 9) /tmp/sunpro. с.1.157.3.00
5) /tmp/java 10) QUIT #?
Где #? ~ приглашение, по которому пользователь вводит номер.
Все циклы в оболочке bash могут осуществлять немедленный выход, используя встроенную команду Weak. Эта команда также воспринимает в качестве аргумента целое значение, большее или равное 1, которое показывает число уровней вложенности, для которых требуется выполнить прерывание цикла. Это свойство удобно при использовании вложенных циклов.
Комментарии
Комментарии оболочки bash начинаются с символа #. Все символы между # и символом новой строки считаются частью комментария и игнорируются оболочкой. По умолчанию это справедливо как для интерактивных, так и не интерактивных оболочек. Интерактивные оболочки могут изменять это поведение, .используя встроенную функцию shopt.
Инициализационные файлы
Интерактивная регистрирующая оболочка bash считывает файлы ~/.bash_profile, ~/.bash_login и ~/.profile, а нерегистрирующая оболочка bash будет считывать файл ~/.bashrc. Число инициализационных файлов, которые bash должна считывать при запуске, приводят в растерянность многих пользователей.
Соображения по поводу инициализационного файла
Одна из основных проблем, встающая перед пользователем, который только начинает знакомиться с bash, - это какие инициализационные файлы создавать и что помещать в них. Простейшее решение, выработанное множеством пользователей bash, состоит в создании одного инициализационного файла, а остальные инициализационные файлы являются символическими ссылками на этот файл.
Большинство пользователей создают файл ~/bash_profile и делают файл ~/.bashrc ссылкой на ~/.bash_profiie, что обеспечивает одну и ту же среду для регистрирующих и нерегистрирующих интерактивных оболочек bash. Файл ~/.bash_profile больше подходит в качестве инициализационного, чем файл ~/.bash_login, поскольку именно его оболочка bash пытается считать первым.
Некоторые пользователи bash, применяющие sh и ksh вместе с bash, используют только файл ~/.profile и включают в него специальный раздел для bash, используя проверку условий, подобную следующей:
if [ -n "$BASH" ] ; then . . . (Bash specific code here) . ; fi
В этом случае файл ~/.bashrc будет символической ссылкой на файл ~/.profile. Если bash будет единственной используемой sh-подобной оболочкой, вероятно, лучше создать ~/.bash_profile, поскольку при этом можно избежать проблем совместимости, появляющихся в связи с использованием файла ~/.profile.
В наиболее общем случае инициализационные файлы должны устанавливать маску создания файлов и переменную $PATH, содержащую путь поиска команд, поскольку они используются и интерактивными и неинтерактивными оболочками. Большинство инициализационных файлов содержит, помимо этого, множество переменных и опций, применяемых только для интерактивных оболочек. Вот некоторые действия, которые обычно выполняются в инициализационных файлах для интерактивных оболочек:
Некоторые пользователи также определяют в инициализационных файлах псевдонимы и функции, но большинство предпочитает определять их в другом файле, называемом .bash_aliases или .bash_aliai. Одна из причин этого - желание избежать модификации инициализационного файла при каждом добавлении псевдонимов или функций. Поскольку использование файла, содержащего псевдонимы, не представляет сложности, использование дополнительного файла не усложняет инициализационный файл.
Переменные оболочки
Этот раздел содержит перечень некоторых переменных, используемых оболочкой bash, значения которых задаются в инициализационных файлах. В следующем примере показано, как задаются значения переменных в инициализационном файле.
Ниже приведен перечень переменных, являющихся списками имен каталогов, разделяемых двоеточиями (:), которые используются при поиске файлов:
Следующие переменные относятся к редактору, используемому по умолчанию, и обычно являются именем команды редактора, включая опции, используемые при его запуске:
Следующие переменные управляют тем, как и где bash помещает команды в перечне ранее вводившихся команд.
Оболочка bash использует также следующие переменные:
Оболочка bash имеет также несколько переменных приглашения, которые определяют облик приглашения. Они освещаются в разделе "Приглашение".
Приглашение
Приглашение - это строка, отображаемая оболочкой bash, когда она выполняется в интерактивном режиме и готова считать или завершить команду. Bash поддерживает четыре различные приглашения: $PS1, $PS2, $PS3 и $PS4. Из них обычно только переменные $PS1 и $PS2 представляют интерес в интерактивных оболочках. Первичная строка приглашения является значением $PS1 и отображается тогда, когда bash готова считать команду. Вторичное приглашение $PS2 отображается, когда bash нуждается в дополнительном вводе для завершения команды, которую уже начала считывать. Переменная $PS3 содержит приглашение, которое отображается при использовании оператора select. Переменная $PS4 отображается только во время трассировки выполнения. Большинство пользователей не слишком часто используют переменные $PS3 и $PS4, и поэтому обычно в инициализационных файлах этим переменным не задается никаких значений. Все приглашения настраиваются одинаково и воспринимают следующие последовательности специальных символов:
\d Дата в формате "День _ недели Месяц Число" (например, "Tue May 26")
\h Имя хоста вплоть до первой точки (.)
\Н Полное имя хоста
\t Текущее время в 24-часовом формате ЧЧ:ММ:СС
\Т Текущее время в 12-часовом формате ЧЧ:ММ:СС
\@ Текущее время в 12-часовом формате am/pm (до полудня/после полудня)
\и Имя текущего пользователя
\v Версия bash (например, 2.00)
\V Вариант версии оболочки bash (например, 2.00.0)
\w Текущий каталог
\W Базовое имя текущего каталога
\! Номер текущей команды в файле истории
\# Номер текущей команды с момента вызова оболочки, который обычно отличается от номера в истории
\$ Если действующим UID является 0, то #, в противном случае - $.
Ниже приведены несколько примеров обычных значений переменной $PS1 и соответствующие приглашения:
PSl="\t \H \#\$ " 19:10:21 soda.berkeley.edu 16$
Кроме этих последовательностей специальных символов в приглашения могут включаться переменные и команды, которые раскрываются, как описано в соответствующем разделе.
Bash также распознает переменную $PROMPT_COMMAND, в которой может быть задано имя команды, подлежащей выполнению перед установкой первичного приглашения. Некоторые пользователи предпочитают использовать эту переменную для отображения обычных приглашений того компьютера, на котором они работают:
PROMPT_COMMAND="uptime | cut -d: -f4"
Значение переменной $PROMPT_COMMAND может быть равным любой команде оболочки, от легкомысленного PROMPT_COMMAND="fortune" до грозного PROMPT_COMMAND="/bin/rm -rf *".
Команды set и shopt
Встроенные команды set и shopt могут использоваться для настройки поведения bash. Эта настройка обычно выполняется в инициализационном файле. Встроенная команда set доступна в версиях bash l.x и 2.0-х, а встроенная команда shopt - только в версии bash 2.0.X.
Синтаксис команды set выглядит следующим образом: set [+/->[options]. Например
set -о allexport
устанавливает опцию allexport, a
set +о allexport
отменяет установку опции allexport.
Команда set может использоваться интерактивно из командной строки для изменения поведения оболочки или запускаться в инициализационных файлах и сценариях оболочки. Ниже приводится перечень опций, распознаваемых командой set (эквивалентные опции приводятся вместе):
Если команда set -о дается без других аргументов, выводится список всех установленных в данный момент опций. Если set дается без каких-либо аргументов, отображаются все инициализированные в настоящий момент переменные.
Встроенная команда shopt в bash 2.0.х позволяет устанавливать еще несколько опций, воздействующих на поведение оболочки bash. В целом опции оболочки устанавливаются командой shopt -s, а отмена установки опции осуществляется посредством команды shopt -u. Например:
shopt +s cdable_vars
активизирует опцию оболочки cdable_vars, a
shopt +u cdable vars
отменяет ее. Вот некоторые опции оболочки, которые могут быть установлены с помощью команды shopt:
Команда shopt также распознает опцию -р, выводящую список всех установленных опций оболочки, и опцию -q, подавляющую вывод.
Псевдонимы - удобный способ сокращения длинных команд в интерактивных оболочках, выполнения нескольких команд посредством ввода одного слова или вызова определенных команд некоторыми часто используемыми опциями. В оболочке bash псевдонимы создаются (устанавливаются) посредством использования команды alias и уничтожаются посредством команды unalias. Общий синтаксис аналогичен оболочке sh:
alias name=value
Когда bash встречает команду, то проверяет, не содержит ли команда известные псевдонимы. Если да, то эти слова замещаются соответствующим текстом псевдонима. Результирующий текст также проверяется на предмет наличия псевдонимов, но рекурсивная подстановка не выполняется. Таким образом, при объявлении псевдонима подобного
и при вводе rm в качестве имени команды, как только rm -i введено, rm в результирующем тексте не интерпретируется.
Простейшие типы псевдонимов - те, которые используются для небольшого изменения работы команды. Например, следующие псевдонимы просто выполняют данную команду, каждый раз с некоторыми опциями по умолчанию:
alias m="more"
alias mv="mv -i" # выводит запрос на перезапись файла при перемещении файлов alias ср " # выводит запрос на перезапись файла при копировании файлов alias alias ls="ls -aFc"" # отображает в столбцах все файлы и их типы файлов
Простые псевдонимы также удобны при исправлении распространенных ошибок при наборе имен команд:
alias chomd="chmod" alias mroe="more"
Оболочка bash поддерживает также более сложные псевдонимы, подобные
alias mq="/usr/lib/sendmail -bp" # вывод текущей почтовой очереди alias psme=" < ps -ael | head -1 ; ps -ael | grep \" $\" ; > | more"
Псевдонимы могут быть замещены посредством предварения имени псевдонима обратной косой чертой (\), посредством встроенной команды command или вводом полного пути к исполняемому модулю. Если rm - псевдоним команды rm -i, то каждая из следующих строк будет замещать собой этот псевдоним:
Псевдонимы оболочки не поддерживают двух свойств: аргументов и присваивании. Если необходимо использовать эти свойства, придется создавать соответствующую функцию оболочки.
Функции служат той же цели, что и псевдонимы, но имеют гораздо большие возможности; они похожи на сценарии оболочки. Общий синтаксис определения функции следующий: function name () < list; >. Ключевое слово function не является обязательным, и функции часто записываются как
Когда имя функции name дано без круглых скобок, связанный с ним список команд выполняется. Круглые скобки после имени функции name используются оболочкой для идентификации функций и не означают, что аргумента у функции не существует.
Простейшие функции подобны псевдонимам. Например, следующие псевдоним и функция эквивалентны:
Функции также используются, когда в среде необходимо выполнить небольшие изменения. Например, следующая функция изменяет значение переменной $IFS таким образом, чтобы каждый каталог в пути выводился в отдельной строке:
В большинстве случаев функции используются для выполнения более сложных задач, когда требуются аргументы. Простейшим подобным примером является функция, которая использует только свой первый аргумент, $1:
echo "Created" 'pwd';
Ниже приводятся примеры функций, которые обрабатывают все переданные им аргументы:
if [ -e "$i" ] && uuencode $i $i >$.uu; then echo "uuencoded $i to $.uu";
else echo "unable to uunencode $i";
( for pattern in "$@";
ps -ef | grep "$pattern" | while read user pid junk; do
Первая функция - удобный способ кодирования файлов с помощью утилиты uuencode без необходимости ввода длинных команд, а вторая - быстрый способ прерывания процессов, соответствующих определенным шаблонам.
Одна из важных особенностей функций та, что они могут вызываться рекурсивно. Поскольку не существует ограничений на число рекурсивных обращений, простое замещение псевдонима функцией подобно следующему:
Пример инициализационного файла Этот раздел содержит пример инициализационного файла .bash__profile.
# Для версий 1.14.7 или последующих
# установка маски создания файла пользователя
# установка PATH, пути поиска команд
# Исполнение команд для интерактивных оболочек. Альтернативный тест: if tty -s; then
if [ -t ] ; then
# установка некоторых параметров/ специфичных для терминала
stty -decctlq >& /dev/null
stty erase '^H' kill '^U' intr '^C'
# установка TERM, типа терминала, равным vtlOO, если TERM не "действителен"
case "$TERM" in
network|diaiup|unknown)
export TERM
# установка MANPATH, пути поиска страницы руководства MANPATH="/usr/man:/usr/local/man"
if [ -d "$HOME/man" ] ; then
# установка LD_LIBRARY_PATH, пути поиска библиотеки
# установка uid, требуемого для некоторых сценариев csh (например, which) export uid="$UID"
# установка CDPATH, пути поиска для cd
export CDPATH=.:~:~/docs
# установка переменных, связанных с редактированием
if type emacs >/dev/null 2>&1; then
export EDITOR VISUAL FCEDIT
# установка утилиты постраничного вывода PAGER для просмотра файлов,
# man-страниц и т.п.
if type less >/dev/null 2>&1; then
# установка MAILCHECK, временных интервалов между проверкой почты export MAILCHECK=$((60*10))
# установка PS1 и PS2, строк первичного и вторичного приглашения
# установка переменных, связанных с историей
# установка PIGNORE, суффиксов, подлежащих игнорированию при
#завершении имен файлов
export FIGNORE=.out:. о :'~'
set -о notify ignoreeof nonclobber
# установка/отмена установки необязательного поведения оболочки
# доступно в V2.00.0 или последующих
if type shopt > /dev/null 2>&1 ; then
shopt -s checlchash checkwinsize cmdhist lithist dotglob
shopt -s histappend histreedit histverify
if [ -n "$MAILCHECK" ] ; then
shopt -s mailwarn
Командная строка и история
В последующих разделах освещается взаимодействие с командной строкой. При рассмотрении основных положений в этом разделе предполагается, что используется редактирование командной строки в режиме emacs.
Командная строка
В интерактивных оболочках команды вводятся в ответ на приглашение. Bash воспринимает строку для выполнения при вводе символов -line: newline (\n) или return. Например, при вводе в приглашении такой команды, как date, в интерактивной оболочке, bash делит ее на простые команды с аргументами. Если вводится полный путь команды, bash пытается выполнить ее; в противном случае bash сперва пытается найти функцию оболочки, соответствующую команде, затем встроенную команду оболочки и, наконец, команду, расположенную где-либо в пути поиска, приведенном в переменной $РАТН.
Редактирование командной строки
Часто при вводе команд допускаются ошибки. Bash обеспечивает дружественный интерфейс для исправления этих ошибок, совсем как в ksh и tcsh. Используя эти ключевые команды, пользователь может переместить курсор в любую позицию командной строки и отредактировать текст в этой позиции.
В последующих описаниях команд символ С- используется для указания управляющей клавиши control (префикса), а М- используется для указания метаклавиши meta (префикса); все остальные клавиши указаны буквально. Если приведены два управляющих символа, должны использоваться оба. Например, управляющая последовательность C-f означает нажатие клавиши f при удержании нажатой клавиши control, a управляющая последовательность C-q C-v означает нажатие клавиши q при нажатой клавише control, a затем нажатие клавиши v при нажатой клавише control.
Ниже приведен список команд для перемещения по командной строке:
Bash допускает существенное редактирование команд посредством удаления, вырезания и вставки текста. Вырезание и вставка аналогичны вырезанию и вставке в большинстве текстовых процессоров. Эти команды следующие:
Bash поддерживает также следующие команды, связанные с редактированием:
В некоторых случаях, при одновременном редактировании нескольких команд, инструментальных средств редактирования командной строки недостаточно. Для подобных случаев bash обеспечивает встроенную команду fc. Эта команда вызывает редактор для редактирования команды и запускает отредактированную команду сразу по выходе из редактора. По умолчанию fc вызывает редактор и помещает последнюю выполненную команду в его буфер, но команде fc можно указать номер подлежащей редактированию команды и используемый редактор. Например,
вызовет редактор для десятой выполненной команды с момента запуска оболочки, а
вызовет редактор для команды, которая была выполнена 10 команд назад. Вызываемый редактор может быть указан посредством опции -е, за которой следует имя редактора. Например,
вызовет emacs и поместит последнюю команду в буфер для редактирования. Если опция -е не вводится, в качестве имени редактора используется значение переменной $FCEDIT, если оно существует; в противном случае в качестве имени редактора используется значение $EDITOR. Если ни $FCEDIT, ни $EDITOR не установлены, в качестве редактора используется vi.
В дополнение к командам редактирования bash также завершает текст перед курсором. Оболочка bash обладает способностью завершать имена переменных, имена пользователей, имена хостов, команд и файлов. Для слов, начинающихся с символа $ делается попытка выполнить завершение переменных. Для слов, начинающихся с символа ~, bash делает попытку завершить имя пользователя. Для слов, начинающихся с @, делается попытка завершить имя хоста. Для остальных слов сперва предпринимается попытка завершения команды, а затем - завершения имени файла. В целом, команда завершения дается при каждом нажатии клавиши tab. Некоторыми другими командами завершения являются:
Повторный вызов команд из списка истории
История - это список команд, которые выполнялись ранее. По умолчанию bash хранит в истории до 500 команд, начиная с команды 1 и увеличивая номер на 1 при каждом принятии команды. Как только команда принята (например, при вводе return), она дописывается в конец файла истории ~/.bash_history.
Существуют несколько переменных, описанных в разделе, посвященном переменным оболочки, которые могут использоваться для настройки этого механизма. Кроме хранения команд в истории, bash распознает следующие команды повторного вызова ранее выполнявшихся команд:
Переменные истории
Bash поддерживает несколько специальных переменных только для чтения, относящихся к выполнявшимся командам. Ими являются:
Подстановка команд из списка истории
Во многих случаях повторный вызов и редактирование команд может оказаться не простым делом. Для подобных случаев bash обеспечивает средства для манипулирования (подстановки) историей, используя операции, подобные операциям оболочки chs. Подстановка истории начинается, когда bash встречает операцию !, за которой не следуют символы пробела, = или (. Если за операцией ! следует какой-либо из этих символов, bash выполняет операцию отрицания, а не подстановку истории.
Простой подстановкой истории является операция !, за которой следует номер команды, которую необходимо повторно выполнить. Например, операция
выполнит команду, хранящуюся в истории под номером 213. В общем случае такую подстановку истории записывают как !n, где n - номер команды. Если п отрицательно, команда вызывает и выполняет n -ю команду, предшествующую текущей. Например, следующая операция:
выполнит команду, которая была выполнена 10 команд назад, а последняя выполненная команда может быть повторно вызвана с помощью
Поскольку повторный вызов ранее выполнявшихся команд - распространенная задача, bash имеет для нее управляющую последовательность быстрого доступа . Кроме того, команда может быть повторно вызвана из истории посредством ввода части строки, с которой она начинается или которую содержит. Например, последняя команда mail может быть вызвана повторно операцией
Общий синтаксис повторного вызова команд, начинающихся с конкретной строки: ! string. В предыдущем примере подстановка истории не вызовет повторно команды, содержащие строку mail, как например, sendmail или rmail, но повторно вызовет команду mailtool, если она появляется в истории перед командой mail. Bash может вызывать команды, содержащие конкретные строки, если подстановка истории имеет форму !?string?. Например,
может использоваться для повторного вызова команд hostname, gethostname, ypcat hosts и echo $host
Иногда простого повторного вызова команд недостаточно, поэтому bash поддерживает несколько подстановок истории частичного повторного вызова и замещения. Простейшей из них является замещение ^string1^strillg2^, которая в предыдущей команде замещает строку string1 строкой string2. Если выполняется команда
а затем должно быть просмотрено изображение kangaroo.gif, может быть использована следующая быстрая подстановка:
Более сложные операции замещения могут повторно вызывать аргументы, переданные предыдущим командам. Простейшая из них !:0, которая повторно вызывает имя предшествующей команды. Например, если вводится команда
и отформатированная версия должна быть просмотрена посредством команды type, требуемый результат будет получен посредством следующей команды:
Как только отформатированная функция просмотрена, может потребоваться ее использование, поэтому следующая команда:
повторно вызовет имя функции, которая была передана в качестве первого аргумента команды type, т.к. подстановка !:^ повторно вызывает первый аргумент, переданный команде. Иногда необходимо вызвать последний аргумент, переданный команде, для этого может использоваться подстановка !:$. Эти операции - сокращенные варианты более общей подстановки !:n, которая повторно вызывает n -й аргумент, переданный команде. Если бы требовался третий аргумент команды, нужно было бы использовать подстановку !:3. Часто недостаточно просто повторно вызвать один аргумент команды. Например, если бы выполнялась команда
xman -background white -geometry 135х55
и требовался бы параметр такого же цвета фона и геометрии, подстановка
дала бы требуемые результаты, поскольку подстановки !* и !:* используются для повторного вызова всего списка аргументов, переданных команде. Эти подстановки - специальные формы подстановок истории !:х-у, которые повторно вызывают все аргументы между х и у, переданные команде. Например, если дается следующая команда:
javac -d . -O.rectPanel.java
и второй и третий аргументы (флаги компилятора) требуются для последующей компиляции, подстановка
javac !:1-3 javaStarDate.java
даст требуемый результат.
В общем виде подстановки истории могут быть записаны, как !string:option, где option - ранее описанные опции 0, n, ^ , х-у и *. Например, если выполняется следующая команда finger:
finger ranga@soda.berkeley.edu sriranga@ocf.berkeley.edu
и по выполнении нескольких других команд почта должна быть отправлена этим пользователям, следующая подстановка
даст надлежащий результат.
Bash - мощная оболочка, популярная как среди начинающих, так и среди опытных пользователей, поскольку она обеспечивает множество полезных свойств, таких как редактирование командной строки и завершение имен файлов. Ее сила и популярность возрастают благодаря интеграции свойств, присущих оболочкам Bourne, Kom и С. Bash также доступна на многих системах, отличных от UNIX, поэтому знания и навыки использования Bash обязательно пригодятся любому пользователю.
Источники информации
При написании этой главы использовались следующие источники:
Manual Page BASH(l), Free Software Foundation, 1996
BASH FAQ version 2.1, 1996
linux samba mail postfix FreeBSD Unix doc linux howto ALTLinux PHP faq bind sendmail apache iptables firewall kernel rpm apt-get Slackware openssh Cisco debian vmware GNU oracle sun awk /etc/ passwd linux установка учебник книга скачать