В данной статье читателю предлагается окунуться в бескрайнее море возможностей, что предоставляют unix-like системы. Здесь собраны воедино многие понятия и команды, которые полезно было бы знать для повседневной работы с командной строкой. Разумеется, автор отдаёт себе отчёт в том, что охватить всё в одной заметке невозможно. Тем не менее, было принято решение объединить в ней наиболее употребительные термины и решение некоторых распространённых задач. Сделано это по соображениям удобства поиска, дабы материал не приходилось искать на разных страницах.

Приведёные ниже команды можно вводить как раздельно, так и в одну строку. Во втором случае следует разделять команды знаком ;. Каждый из разделов только коротко описывает назначение и употребление команд. Для получения более подробной информации по каждой из них предлагается обратиться к справочным руководствам.

Содержание

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

Список команд для ежедневного использования.

командаописание
mv file1 file2переместить/переименовать файл
rm file1удалить файл
rm -rf dirудалить директорию
rm -rf dir/*удалить содержимое директории
rmdir dirудалить пустой каталог dir
touch file1 file2создать два файла
cp file1 file2копировать файл
pwdотобразить текущий каталог
cd /home/user/workперейти в каталог work пользователя user
echo “hello” > file1записать “hello” в файл (сотрёт всё остальное)
echo “hello” » file1дописать “hello” в конец файла
ctrl-sприостановить вывод команды
ctrl-qвозобновить вывод команды
ctrl-dвыйти из оболочки
ctrl-cпрервать выполнение
ls -lt ~/workсортировать вывод по дате последнего изменения
ls -luпо времени последнего использования
cat hello.cвывести на экран содержимое файла hello.c
wc hello.cподсчитать строки(-l), слова(-w), символы(-m) в файле hello.c
wc -L hello.cузнать максимальную длину строки
df -hинформация о свободном месте на смонтированных устройствах
du -hсколько места занимают файлы каталога и подкаталогов
free -mиспользование оперативной памяти (-m мегабайт, -g гигабайт)
ps -auxинформация о запущенных процессах
killall PIDснять задачу по её PID (или по имени)
sleep 1; echo “hello”вывести ‘hello’ через секунду
whereis emacsнайти местоположение emacs
file file.pdfвывод информации о типе файла

Поиск по шаблону

Grep просматривает файл в поиске строк, соответствующих шаблону. Можно указать несколько файлов сразу.

$ grep Hello hello.c  # найти слово 'Hello' в файле hello.c
  printf("Hello, world!\n");
$ grep Hello hello.c hello.cpp
  hello.c:    printf("Hello, world!\n");
  hello.cpp:    cout << "Hello!\n";

При указании ключа -v ищет строки, не соответствующие шаблону, -n выводит номера строк:

$ grep -v Hello hello.c
#include <stdio.h>
int main(){
    return 0;
}

Также grepegrep) может работать с регулярными выражениями. К сожалению, метасимволы, используемые этими программами, не всегда совпадают.

метасимволописание
^начало строки
$конец строки
.одиночный символ
[…]любой из символов множества
r*0 или больше вхождений r
r+1 или больше вхождений r (egrep)
r?0 или одно вхождение r (egrep)

Сортировка и замена строк

Команда sort применяется для сортировки данных по алфавиту: сначала пробелы, затем буквы в верхнем регистре, затем буквы в нижнем регистре.

Вывести последние 10 строк файла может команда tail. Если необходимо изменить количество выводимых строк, нужно сказать tail об этом. Например, затребуем последние 12 строк файла english-alphabet.cpp:

$ tail -12 english-alphabet.cpp
#include <iostream>
using namespace std;

int main(){
    char letter;

    for(letter = 'A'; letter <= 'Z'; letter++ )
        cout << letter << " ";
        cout << "\n";

    return 0;
}

Во многих случаях имеет смысл применить команду sed, которая построчно читает входной файл и поочерёдно выполняет команды над каждой его строкой.

$ sed -n '10,50p'     # вывести строки с 10 по 50
$ sed '1,10d'         # удалить строки с 1 по 10
$ sed '$d'            # удалить последнюю строку
$ sed 's/UNIX/LINUX/g' unix > linux
$ cat unix linux
UNIX
LINUX

В последнем примере мы заменили слово UNIX на слово LINUX в одноимённом файле. Исходный файл остался неизменённым.

А теперь совместим работу sed и wc для выполнения часто встречающейся задачи — подсчёта слов без пробелов:

$ cat $1 | sed 's/ //g' | sed 's/.$//;N;s/\n/ /g' | wc -m

Здесь cat принимает на вход пользовательский аргумент (файл), sed очищает файл от лишних для нашей задачи символов, wc подсчитывает количество оставшихся символов.

Хорошую службу может сослужить awk. Это язык сканирования и обработки шаблонов. На вход принимает аргумент вида шаблон {действие} и имена файлов. К примеру, нужно выбрать третье поле из вывода df:

$ df -ah /home
Файловая система Размер Использовано  Дост Использовано% Cмонтировано в
/dev/sda6          104G          55G   45G           56% /home
$ df -ah /home | awk '{print $3}'
Размер
55G

Сравнение файлов

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

$ diff english-alphabet.cpp reverse-alphabet.cpp
7c7
<     for(letter = 'A'; letter <= 'Z'; letter++ )
---
>     for(letter = 'Z'; letter >= 'A'; letter-- )

В примере diff отображает имеющиеся различия между двумя файлами и указывает различающиеся строки. В данном примере оба файла имеют лишь одно отличие и находится оно на седьмой строке.

Метасимволы

Весьма удобны в использовании шаблонные символы или метасимволы.

символописание
>направить стандартный вывод в файл
»добавить вывод в конец файла
<взять стандартный вывод из файла
*любая строка символов
[…]любой из символов в скобках
?любой отдельный символ
;разделитель команд
(…)выполнить команду в дочерней оболочке
‘…’выполнить без интерпретации метасимволов
“…”интерпретировать метасимволы внутри
&выполнение последующей команды, не дожидаясь завершения предыдущей
&&выполнение последующей команды только при завершении предыдущей

Чтобы экранировать шаблонный символ возьмите его в одинарные кавычки '*' или используйте знак экранирования \ (обратная косая черта).

Конвейеры

Здесь следовало бы начать с определения канала как такового, что и мы и сделаем. Канал (pipe) — способ подключения вывода одной программы на вход другой без использования временных файлов.

Конвейер (pipeline) — соединение двух и более программ посредством таких каналов.

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

В случае, когда имена файлов не указаны, команда читает свой стандартный ввод (по-умолчанию терминал), перенаправляет ответ на стандартный вывод (который также связан с терминалом).

Например:

$ who | wc -l # подсчитать кол-во пользователей

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

Процессы

Упоминая UNIX, нельзя не сказать несколько слов об управлении процессами.

Процесс — экземпляр выполняющейся программы. Важно различать программы и процессы: wc — это программа; каждый раз, когда она запускается, создаётс новый процесс.

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

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

# nice emerge-webrsync && sudo emerge -auvDN world

Если выполнение программы обещает быть очень долгим, а ждать времени нет, можно воспользоваться услугами программы nohup. Её формат nohup command &. При этом есть возможность спокойно выйти из оболочки, не опасаясь того, что выполнение программы завершится, а вывод прочесть в специально созданном nohup файле nohup.out. Nohup использует nice, поэтому указывать приоритет дополнительно нет необходимости.

При использовании конвейера совместно со знаком амперсанда (&) идентификатор процесса тлько один, не смотря на то, что в конвейере запущено несколько команд.

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

# emerge -av sys-process/at  # установить at в gentoo
# atd                        # запуск демона at
$ at 00:27                   # установить время
$ at> emerge-webrsync        # дать команду
$ Ctrl-D                     # выйти
$ sleep 5; echo "Good bye"   # запуск после пяти секунд

Настройка окружения

Если в домашнем каталоге имеется файл .bash_profile, .zshenv или подобный им (зависит от используемой оболочки), при входе в систему будут выполняться прописанные в нём команды. Например:

export DISPLAY=:0.0
echo "Hello, $USER!\nToday `date`"
export EDITOR=/usr/bin/emacs

Последняя запись определяет встроенную переменную $EDITOR, тем самым устанавливая в качество текстового редактора по-умолчанию emacs. Для просмотра всех имеющихся переменных введите команду set.

Чтобы изменения вступили в силу «перечитайте» соответствующий файл (в нашем случае используется Z Shell):

$ source .zshenv

Часто может возникнуть потребность указания путей поиска, которые хранятся в переменной PATH. Чтобы узнать в каких каталогах происходит поиск, нужно вывести значение этой переменной на экран. В случае, если этих значений недостаточно, добавить нужные в .zshenv. Пути разделены двоеточием, точка обозначает текущий каталог и не является обязательной:

$ echo $PATH                           # вывести содержимое на экран
$ cat .zshenv
export PATH=.:/bin:/usr/local/bin      # переопределение всех путей
export PATH=$PATH:/home/redvi/.rvm/bin # добавление пути к уже существующим

Также бывает удобно создавать свои команды. Самый простой пример: комбинация уже существующих команд в одну.

$ echo '#!/bin/sh\nls $1 && cat $1' > lc
$ chmod +x lc
$ sh lc file.txt

Здесь нужные строки записываются в файл lc, которому даются права на исполнение. Впоследующем файл запускается при помощи оболочки. Если поместить каталог, где находится lc в переменную PATH, можно будет опустить sh.

Если подытожить: команда создаётся в пользовательском каталоге. Например, /home/user/usr/bin/mycommand. После чего в файл, который читается оболочкой, добавляется соответствующий путь поиска команд.

Также нужно пояснить значение позиционного параметра $1. Он служит переменной, передающей первый аргумент при вызове команды lc. В нашем случае на это место ставится имя файла. Само имя программы — это $0. Если количество аргументов заранее неизвестно, подставляется шаблонное выражение $*.

Если переменные, содержащиеся в .profile должны быть глобальными, рекомендуется задать их в /etc/profile.

Права доступа и файлы

Запомнить обозначения прав доступа не составит большого труда. По большому счёту они сводятся к чтению (read), записи (write) и исполнению (execute).

$ ls -l sort.py
-rwxr-xr-x 1 mark users 388 ноя 26  2013 sort.py*

Из приведённой выше записи можно понять следующее:

это файл, а не каталог (-); владельцу (пользователю mark) он доступен на запись, чтение и исполнение; группе владельца users и всем остальным на чтение и выполнение.

Весьма демократично, не так ли? Для изменения прав используются две команды: chmod и chown, первая из которых меняет права доступа к файлу, вторая — меняет владельца и/или группу файла.

$ chmod 644               # изменить права доступа
# chown root:adm sort.py  # теперь владелец root, группа adm

Как видно из примера, права можно задавать лишь числами. Но разобраться с ними ничуть не сложнее: их тоже три.

  • 4 read
  • 2 write
  • 1 execute

Так, чтобы назначить права только на чтение и запись (read - 4, write - 2), нужно к 4 прибавить 2. В итоге мы получаем заветную шестёрку, которая и фигурирует в примере.

Что касается chmod, при необходимости добавить или запретить права доступа, можно использовать + и - соответственно:

$ chmod +x sort.py  # дать всем права на выполнение

Помимо этого существует бит SUID, но в данной статье он не рассматривается, ибо применяется достаточно редко и теоретически небезопасен.

если для записи доступен каталог, пользователи могут удалять из него файлы независимо от прав доступа к этим файлам

Дабы проиллюстрировать сказанное выше, создадим каталог и поиграем с правами доступа к нему:

$ mkdir catalog && ls -ld catalog
drwxr-xr-x 2 redvi users
$ chmod 644 catalog && ls -ld catalog
drw-r--r-- 2 redvi users
$ touch catalog/sc.css
touch: невозможно выполнить touch для «catalog/sc.css»: Отказано в доступе
$ chmod 744 catalog
$ touch catalog/sc.css

Также у каждого файла имеется служебная информация (время модификации, последнего доступа), которая хранится в индексном дескрипторе (inode). Интересно, что сам файл скорее представляет собой ссылку — указание на индексный дескриптор: например, при удалении командой rm происходит удаление ссылки, и только если нигде больше не осталось других ссылок на файл удаляется сам индексный дескриптор, а значит и сам файл. Возможно, это звучит немного запутанно, но я не знаю как объяснить лучше.

Создание жёсткой ссылки на файл возможно при использовании команды ln, просмотр всех имеющихся ссылок — ls -li:

$ ln link link2
$ ls -li
5519273 -rw-r--r-- 2 link
5519273 -rw-r--r-- 2 link2
5256834 -rwxr-xr-x 1 sort.py*

Так, оба файла имеют один и тот же индексный дескриптор (5519273), и по выводу команды ls видно, что у него два счётчика (2). При удалении одного из них, индексный дескриптор (и содержимое файла) никуда не исчезнет.

У читателя может возникнуть вопрос: чем же тогда создание жёсткой ссылки отличается от простого копирования файла? Всё просто: при копировании создаются два разных файла, если внести изменения в один, то они никак не повлияют на другой. Жёсткая ссылка обеспечивает полную идентичность содержимого: при редактировании первого файла все изменения отражаются и во втором.

С другой стороны мы можем создать символическую ссылку, которая всего лишь указывает на местонахождение файла. Если хотите, можете сравнить это с программой и её ярлыком в OS Windows.

При удалении или перемещении файла, символическая ссыка перестаёт работать, ибо ведёт к несуществующему файлу.

Отключение системного звукового сигнала

Если вы не в силах выносить системный звуковой сигнал в linux, что с вероятностью в 100% возникает при неверном вводе, можно воспользоваться нижеизложенными командами.

Консоль:

$ echo 'set bell-style none' >> .inputrc

X11:

$ echo 'xset b off' >> .xinitrc

Те, кто пользуется самосборным ядром, могут отключить досадную особенность в самом ядре:

Device Drivers → Input device support → Miscellaneous devices → PC Speaker support

Работа с архивами

$ tar -zxvf archive.gz         # распаковать .gz
$ tar -cf archive.tar folder/  # создать tar-архив
$ unzip archive.zip            # распаковать zip-архив
$ zip -r archive folder        # создать zip-архив из каталога folder
$ unrar -x                     # распаковать rar-архив

Возможно, соответствующие программы для работы с архивами придётся предварительно установить.

Полный backup и восстановление (tar)

Полная копия linux-машины, за исключением каталога /backup и служебных каталогов с сохранением прав доступа. Для создания таковой понадобится LiveCD диск, загрузившись с которого можно приступать к задаче.

# tar -cvpf /backup/mybackup.tar --directory=/ --exclude=proc --exclude=dev/pts --exclude=backup --exclude=dev

Копия системы будет создана под именем backup/mybackup.tar. Для сжатия (и экономия места на носителе-приёмнике) к указанной команде можно добавить ключ -z.

Восстановление копии на ту же машину (в случае использования другой машины следует поправить соответствующие строки в /etc/fstab и установить загрузчик):

# tar -xvpf /mybackup.tar

В случае восстановления сжатого архива также добавляется ключ -z.

Инкременальный backup (rsync)

Идеально подходит для периодического создания копии домашнего каталога.

# rsync -PavHx --delete-after /home/* /mnt/backup/

Скачивание файлов/сайтов по сети

Делается это при помощи программы wget, где ключ -c позволит докачать файл при обрыве соединения, а ключ -r используется в случае, если необходимо рекурсивное скачивание:

$ wget -c http://distfiles.gentoo.org/*/install-amd64-minimal-*.iso

Создание загрузочного usb-flash

Предполагается, что лучший способ для этого — использование dd. Если есть необходимость разметить usb-flash, запустите команду fdisk, вот её флаги:

ключописание
aустановить/снять флаг загрузочного раздела
cпереключить флаг совместности с dos
dудалить раздел
lвывести список известных типов разделов
mпоказать меню
nдобавить новый раздел
oсоздать новую пустую таблицу разделов в стиле DOS
pпоказать существующею таблицу разделов
qвыйти без сохранения изменений
tизменить метку типа раздела
vпроверить таблицу разделов
wсохранить изменения и выйти
xдополнительные возможности (только для экспертов)
# fdisk -l
Устр-во   Загрузочный     Start Конец    Blocks  Id System
/dev/sda1*            1xxx 4xxx 10xxx+ 83 Linux
/dev/sda2             1xxx 1xxx 5xxx  82 Linux swap / Solaris
/dev/sda5             4xxx 6xxx 11xxx+ 83 Linux

Устр-во   Start   Конец   Size Тип
/dev/sdb1  2048     15644671   7,5G Microsoft basic data

# fdisk /dev/dsb
# dd if=/home/user/ISO/linux.iso of=/dev/sdb

Кто в системе

Кто сейчас находится в системе, когда и кем был выполнен последний вход и прочее. Для получения более подробных сведений используйте ключ -a.

$ who
redvi ~  who
root     tty3         2014-07-30 20:43
redvi    :0.0         2014-07-30 18:22

Установка даты и времени

Первая из приведённых ниже программ отобразит текущие дату и время. Вторая установит нужные параметры (формат MMDDhhmmCCYY/месяц-день-часы-минуты-год)

$ date
# date 073021502014
⤧  Следующая запись Emacs как IDE для web-разработки