# Bash общая информация

Консоль работает с текстом, поэтому центральная задача - обработка текста.

<table border="1" id="bkmrk-echo-%D0%9F%D1%80%D0%BE%D1%81%D1%82%D0%BE-%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4%D0%B8%D1%82-" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 18.631%;"></col><col style="width: 81.4882%;"></col></colgroup><tbody><tr><td>echo</td><td>Просто выводит строку</td></tr><tr><td>printf</td><td>Выводит строку с модификаторами

printf "%s %d" "ff" 22

</td></tr></tbody></table>

Поиск приложения: whereis name

~ - домашняя директория, ~sergey домашняя директория пользователя sergey

cd без аргументов в домашнюю, cd - в предыдущую

Маски для ls

<table border="1" id="bkmrk-%3F-%D0%BE%D0%B4%D0%B8%D0%BD-%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB-%2A-%D0%BC%D0%BD%D0%BE%D0%B3" style="border-collapse: collapse; width: 100%; height: 152.781px;"><colgroup><col style="width: 18.631%;"></col><col style="width: 81.4882%;"></col></colgroup><tbody><tr style="height: 29.7969px;"><td style="height: 29.7969px;">?</td><td style="height: 29.7969px;">один символ</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">\*</td><td style="height: 29.7969px;">много символов</td></tr><tr style="height: 63.3906px;"><td style="height: 63.3906px;">\[set\]</td><td style="height: 63.3906px;">Набор символов, в данном случае s,e,t

\[a-c\] a,b,c

\[!0-9\] где нет цифр

</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">{}</td><td style="height: 29.7969px;">перечисляются наборы текста, например echo f{io,am}

</td></tr></tbody></table>

Утилиты фильтрации текста

<table border="1" id="bkmrk-cat-%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 25.6548%;"></col><col style="width: 74.4644%;"></col></colgroup><tbody><tr><td>cat</td><td>перенаправление ввода на вывод

-b - нумеровать только непустые строки;  
-E - показывать символ $ в конце каждой строки;  
-n - нумеровать все строки;  
-s - удалять пустые повторяющиеся строки

cat file1 file2 &gt; file3

</td></tr><tr><td>grep</td><td>поиск строк во вводе

Может анализировать один файл или директорию.

-e несколько регулярных выражений, например -e ... -e ...

-n номер строки, где найдено совпадение

-i, --ignore-case - не учитывать регистр символов;  
-v, --invert-match - вывести только те строки, в которых шаблон поиска не найден;  
-w, --word-regexp - искать шаблон как слово, отделенное пробелами или другими знаками препинания;  
-x, --line-regexp - искать шаблон как целую строку, от начала и до символа перевода строки;  
-c - вывести количество найденных строк;  
-L, --files-without-match - выводить только имена файлов, будут выведены все файлы в которых выполняется поиск;  
-l, --files-with-match - аналогично предыдущему, но будут выведены только файлы, в которых есть хотя бы одно вхождение;  
-m, --max-count - остановить поиск после того как будет найдено указанное количество строк;  
-o, --only-matching - отображать только совпавшую часть, вместо отображения всей строки;  
-h, --no-filename - не выводить имя файла;  
-s, --no-messages - не выводить ошибки чтения файлов;  
-A, --after-content - показать вхождение и n строк после него; Те -A2 строка + 2 строки после  
-B, --before-content - показать вхождение и n строк перед ним;  
-C - показать n строк до и после вхождения;  
-a, --text - обрабатывать двоичные файлы как текст;  
\--exclude - пропустить файлы имена которых соответствуют регулярному выражению;  
\--exclude-dir - пропустить все файлы в указанной директории;  
-I - пропускать двоичные файлы;  
\--include - искать только в файлах, имена которых соответствуют регулярному выражению;  
-r - рекурсивный поиск по всем подпапкам;  
-R - рекурсивный поиск включая ссылки;

```bash
grep -r "поисковой_запрос" /путь/к/директории/
```

</td></tr><tr><td>sort</td><td>сортировка строк

-b - не учитывать пробелы  
-d - использовать для сортировки только буквы и цифры  
-i - сортировать только по ASCII символах  
-n - сортировка строк linux по числовому значению  
-r - сортировать в обратном порядке  
-o - вывести результат в файл  
-u - игнорировать повторяющиеся строки  
-m - объединение ранее отсортированных файлов  
-k - указать столбец по которому нужно сортировать строки, если не задано, сортировка выполняется по всей строке.

ls -l | sort -k9  
-f - использовать в качестве разделителя полей ваш символ вместо пробела.

</td></tr><tr><td>uniq f1 &gt; f2</td><td>Удаляет повторяющиеся строки

</td></tr><tr><td>cut</td><td>извлечение символов из ввода

-b 2-6, 8 отобразит символы от 2 по 6 из строки и 8

-b 5- символы с 5 до конца

-с нечто похожее на -b

-d ':' -f 1,3 считать разделителем : и оставить первый и третий столбцы

</td></tr><tr><td>sed</td><td>операции изменения данных перед выводом

Позволяет вырезать строки, поиск/замена по регулярке, вывод. Крутая штука.

</td></tr><tr><td>tr</td><td>транслирование символов на вводе в другие символы

-d набор - удаление символов

 tr -d '0-9'

-s заменяет последовательность повторяющихся символов в SET1 на один такой символ;

 tr -s ' ' заменит много пробелов на один

</td></tr><tr><td>head</td><td>-n кол-во Выводит первые кол-во строк</td></tr><tr><td>awk</td><td>Считывает построчно данные, выполняет действия и выводит в stdout. Включает целый язык для обработки текста.

awk опции 'условие {действие} условие {действие}'

Опции:

-F, --field-separator - разделитель полей, используется для разбиения текста на колонки;  
-f, --file - прочитать данные не из стандартного вывода, а из файла;  
-v, --assign - присвоить значение переменной, например foo=bar;  
-b, --characters-as-bytes - считать все символы однобайтовыми;  
-d, --dump-variables - вывести значения всех переменных awk по умолчанию;  
-D, --debug - режим отладки, позволяет вводить команды интерактивно с клавиатуры;  
-e, --source - выполнить указанный код на языке awk;  
-o, --pretty-print - вывести результат работы программы в файл;

Действия:

print(строка) - вывод чего либо в стандартный поток вывода;  
printf(строка) - форматированный вывод в стандартный поток вывода;  
system(команда) - выполняет команду в системе;  
length(строка) - возвращает длину строки;  
substr(строка, старт, количество) - обрезает строку и возвращает результат;  
tolower(строка) - переводит строку в нижний регистр;  
toupper(строка) - переводить строку в верхний регистр.

Переменные:

$NF - последняя строка

$(NF-1) - предпоследняя

NR - количество строк с начала

awk -F":" '{print $4}' Возьмет строку и по разделителю : выведет 4 элемент

Поддерживает регулярные выражения

echo -e 'one 1\\n two 2' | awk '{sum+=$2} END {print sum}' сумма элементов.

awk 'NR &lt; 10' log.txt

</td></tr><tr><td>sed</td><td>Тоже очень крутая штука, этим двум командам посвящена целая книга.

</td></tr><tr><td>diff file1 file2</td><td>Различие в строках

</td></tr><tr><td>ndiff</td><td>Различие в результатах сканирования nmap

```
${BIN_PATH}ndiff $BASE_RESULTS $NEW_RESULTS > $NDIFF_RESULTS
```

</td></tr><tr><td>jq</td><td>Утилита для анализа JSON.

jq -r '.first' возвращает значение ключа first

jq '.\[0\].plugins.HTTPServer.string\[0\] определяет следующий элемент:

```json
[
  {
    "plugins": {
      "HTTPServer": {
        "string": [
          "Werkzeug/3.0.1 Python/3.12.3"
        ]
      }
    }
  }
]
```

</td></tr><tr><td>tail -F filename</td><td>Отображения изменения в файле

</td></tr><tr><td>wget</td><td>Загрузка файлов

-q тихий режим

-r рекурсивное скачивание

-np скачивание файлов из данной директории или ниже

-R "index.html" исключить загрузку файлов вида index.html

-P foldername директория сохранения

</td></tr><tr><td>curl</td><td>Must have.

-s тихий режим

-X GET|POST|PUT|DELETE → явный выбор метода

-d "param=value" → данные формы (POST)

```
curl -X POST -H "Content-Type: application/json" \
     -d '{"name":"Alice"}' https://api.example.com/users
```

-H "Header: value" → добавить заголовок

```
curl -H "Authorization: Bearer TOKEN" https://api.example.com
```

-b "name=value" → передать cookie  
-c cookies.txt → сохранить cookie в файл  
-b cookies.txt → использовать cookie из файла

-o file → сохранить в файл

 -u user:pass → basic auth

-k → игнорировать ошибки сертификатов (небезопасно!)  
\--cacert file.crt → указать свой сертификат CA

-w "%{http\_code}\\n" → вывести только HTTP-код

</td></tr><tr><td>find / -name "file.txt"</td><td>Поиск файла

</td></tr></tbody></table>

**Редиректы**

Вывод в файл:

<table id="bkmrk-%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80-%D0%97%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%9F%D1%80"><thead><tr><th>Оператор</th><th>Значение</th><th>Пример</th></tr></thead><tbody><tr><td>`>`</td><td>Перенаправить вывод (перезаписать файл)</td><td>`echo "hi" > file.txt`</td></tr><tr><td>`>>`</td><td>Перенаправить вывод (добавить в файл)</td><td>`echo "hi" >> file.txt`</td></tr></tbody></table>

Вывод из файла:

<table id="bkmrk-%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80-%D0%97%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%9F%D1%80-1"><thead><tr><th>Оператор</th><th>Значение</th><th>Пример</th></tr></thead><tbody><tr><td>`<`</td><td>Чтение из файла</td><td>`wc -l < file.txt`</td></tr><tr><td>`<<`</td><td>**Here document** — передаёт блок текста как stdin</td><td>cat &lt;&lt; EOFстрока1строка2EOF</td></tr><tr><td>`<<<`</td><td>**Here string** — передаёт одну строку (или переменную)</td><td>`grep foo <<< "foo bar baz"`</td></tr></tbody></table>

**Фоновые задачи**

Фоновые задачи не получают данные от клавиатуры

<table id="bkmrk-%D0%9A%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0-%D0%A7%D1%82%D0%BE-%D0%B4%D0%B5%D0%BB%D0%B0%D0%B5%D1%82-c" style="width: 99.6429%;"><thead><tr><th style="width: 22.294%;">Команда</th><th style="width: 77.706%;">Что делает</th></tr></thead><tbody><tr><td style="width: 22.294%;">`command &`</td><td style="width: 77.706%;">Запускает процесс в фоне</td></tr><tr><td style="width: 22.294%;">`jobs`</td><td style="width: 77.706%;">Показывает список фоновых задач (с job ID: `%1`, `%2` …)</td></tr><tr><td style="width: 22.294%;">`fg %N`</td><td style="width: 77.706%;">Переводит задачу номер N в передний план</td></tr><tr><td style="width: 22.294%;">`bg %N`</td><td style="width: 77.706%;">Возобновляет приостановленную задачу в фоне</td></tr><tr><td style="width: 22.294%;">`Ctrl+Z`</td><td style="width: 77.706%;">Приостанавливает текущий процесс (отправляет в «stopped»)</td></tr><tr><td style="width: 22.294%;">`kill %N`</td><td style="width: 77.706%;">Завершает задачу по её job ID</td></tr><tr><td style="width: 22.294%;">`kill PID`</td><td style="width: 77.706%;">Завершает задачу по PID</td></tr><tr><td style="width: 22.294%;">`kill -9 PID`</td><td style="width: 77.706%;">Жёсткое завершение (если обычный `kill` не помог)</td></tr><tr><td style="width: 22.294%;">`disown %N`</td><td style="width: 77.706%;">«Отвязывает» задачу от текущего терминала (будет жить после выхода)</td></tr><tr><td style="width: 22.294%;">`ps aux</td><td style="width: 77.706%;">grep name`</td></tr><tr><td style="width: 22.294%;">`pkill -f pattern`</td><td style="width: 77.706%;">Завершение процессов по шаблону</td></tr></tbody></table>

Задачи завершаются при закрытии сессии. Через команду nohup можно сделать задачу, работающую после закрытия сессии.

```
nohup ./myscript.sh &
```

**История ввода команд**

Хранится где-то в сессии, сохраняется в .bash\_history при закрытии сессии. Для просмотра введенных команд в пределах сессии используется утилита fc

<table border="1" id="bkmrk--l-%D0%9F%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BD%D0%B8%D0%B5-15-%D0%BA%D0%BE%D0%BC%D0%B0" style="border-collapse: collapse; width: 100%; height: 368.953px;"><colgroup><col style="width: 31.4882%;"></col><col style="width: 68.631%;"></col></colgroup><tbody><tr style="height: 80.1875px;"><td style="height: 80.1875px;">-l</td><td style="height: 80.1875px;">Последние 15 команд

4 выведет четвертую команду

4 7 команды с 4 по 7

строка - выведет с первого вхождения строки (из 15) и далее

</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">-n</td><td style="height: 29.7969px;">без вывода номеров</td></tr><tr style="height: 80.1875px;"><td style="height: 80.1875px;">-e nano</td><td style="height: 80.1875px;">без дальнейших аргументов - редактирование последней команды и затем исполнение

Чтобы не вводить редактор, можно в .bash\_profile добавить переменную

FCEDIT=nano

</td></tr></tbody></table>

!! исполнение предыдущей команды

**Специальные файлы**

.bash\_profile, .bash\_logout, .bashrc Если отсутствуют - используются файл /etc/profile и файлы из /etc/profile.d

**.bash\_profile - сейчас не используется.**

В .profile переменные окружения, .bashrc - скрипты. .bash\_login при входе. Но идея осталась.

Последовательность поиска при авторизации, исполняется первый найденный

- `~/.bash_profile`
- `~/.bash_login`
- `~/.profile`

Исполняет команды при каждом входе в систему.

Итого:

~/.bashrc

Используется в интерактивных (обычных) shell-ах. Сюда кладём то, что нужно только в терминале:

- алиасы (alias ll='ls -lh')
- функции (mkcd() { mkdir -p "$1" &amp;&amp; cd "$1"; })
- настройки PS1 (prompt, цвета)
- shopt и настройки истории (HISTSIZE, HISTCONTROL)
- подключение fzf, автодополнений и прочих «тюнингов»

~/.profile

Используется при login-shell (и не только Bash, а sh/dash/zsh тоже могут его читать). Сюда кладём:

- переменные окружения (PATH, EDITOR, LANG, JAVA\_HOME)
- настройки, которые должны работать и в GUI-программах (например, экспорт GTK\_THEME или XMODIFIERS)
- запуск программ при логине (например, ssh-agent или gnome-keyring-daemon)

~/.bash\_profile или ~/.bash\_login

Сегодня почти не нужны. Если они есть, то Bash не будет читать ~/.profile.

source .profile - перечитать файл

**Alias, options и переменные окружения**

Алиасы для команд. Создание алиасов: alias cdvoy='cd sipp/demo/animation/voyager'

Пробел перед закрывающей ' означает ожидание ввода пользователя.

unalias name - удаление

set +o optionname установить опцию, -o убрать. Фиксированный набор. Не впечатлило.

**Переменные**

Синтаксис: varname='something', использование $varname удаление unset varname

Формат timestamp:

<table border="1" id="bkmrk-%25a%2C-%25a-%D0%90%D0%B1%D0%B1%D1%80%D0%B5%D0%B2%D0%B8%D0%B0%D1%82%D1%83%D1%80%D0%B0-" style="border-collapse: collapse; width: 100%; height: 268.172px;"><colgroup><col style="width: 17.0441%;"></col><col style="width: 82.9559%;"></col></colgroup><tbody><tr style="height: 29.7969px;"><td style="height: 29.7969px;">%a, %A</td><td style="height: 29.7969px;">Аббревиатура дня недели, Полное имя дня недели</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">%b, %B, %m</td><td style="height: 29.7969px;">Аббревиатура имени месяца, Полное имя месяца, Номер месяца в числовом формате</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">%c</td><td style="height: 29.7969px;">Дата и время локали</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">%C</td><td style="height: 29.7969px;">Последние 2 цифры года

</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">%H, %I, %p</td><td style="height: 29.7969px;">Час в 24-часовом формате, Час в 12-часовом формате, эквивалент am/pm</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">%d, %e</td><td style="height: 29.7969px;">Цифра дня, цифра дня с пробелом в случае одной цифры</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">%D</td><td style="height: 29.7969px;">Дата в американском формате (%m/%d/%y)</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">%j</td><td style="height: 29.7969px;">День года 001-366</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">%M</td><td style="height: 29.7969px;">Минута в десятичном представлении</td></tr><tr><td>%n, %t</td><td>Новая строка, табуляция</td></tr><tr><td>%R</td><td>Время в 24-часовом формате</td></tr><tr><td>%S</td><td>Секунда в десятичном формате</td></tr><tr><td>%T</td><td>Время (час:минута:секунда)</td></tr><tr><td>%u</td><td>Номер дня недели в десятичном формате</td></tr><tr><td>%U</td><td>Номер недели в году</td></tr><tr><td>%Y</td><td>Год</td></tr></tbody></table>

Строка приглашения

PS1 - основное приглашение

PS2 - при незавершенной строке

В переменной PS1

<table id="bkmrk-%D0%9A%D0%BE%D0%B4-%D0%A7%D1%82%D0%BE-%D0%BF%D0%BE%D0%BA%D0%B0%D0%B7%D1%8B%D0%B2%D0%B0%D0%B5%D1%82-%5C"><thead><tr><th>Код</th><th>Что показывает</th></tr></thead><tbody><tr><td>`\u`</td><td>Имя текущего пользователя</td></tr><tr><td>`\h`</td><td>Имя хоста (до первой точки)</td></tr><tr><td>`\H`</td><td>Полное имя хоста</td></tr><tr><td>`\w`</td><td>Текущая директория (полный путь, с `~` для home)</td></tr><tr><td>`\W`</td><td>Текущая директория (только имя последней папки)</td></tr><tr><td>`\!`</td><td>Номер текущей команды в истории</td></tr><tr><td>`\#`</td><td>Номер команды (считает все команды с момента запуска shell)</td></tr><tr><td>`\$`</td><td>Отображает `$` для обычного пользователя и `#` для root</td></tr><tr><td>`\t`</td><td>Время в формате `HH:MM:SS`</td></tr><tr><td>`\T`</td><td>Время в формате `HH:MM` (12-часовой формат)</td></tr><tr><td>`\@`</td><td>Время в формате `hh:mm AM/PM`</td></tr><tr><td>`\d`</td><td>Дата (например: `Mon Aug 26`)</td></tr><tr><td>`\n`</td><td>Перенос строки</td></tr><tr><td>`\s`</td><td>Имя используемой оболочки (обычно `bash`)</td></tr><tr><td>`\v`</td><td>Версия Bash (например: `5.2`)</td></tr><tr><td>`\V`</td><td>Версия Bash с патч-уровнем</td></tr><tr><td>`\j`</td><td>Количество фоновых задач, запущенных из shell</td></tr><tr><td>`\!`</td><td>Номер команды в истории</td></tr><tr><td>`\#`</td><td>Номер команды (считает все команды в текущей сессии)</td></tr><tr><td>`\e` или `\033`</td><td>Escape-символ (для цветов/ANSI-последовательностей)</td></tr></tbody></table>

Пример: PS1="\\u@\\h:\\w\\$ "

**PATH**

Просмотр последовательно всех путей.

Добавление в пути: PATH=$PATH":/home/you/bin"

Для ускорения поиска пути к приложениям хранятся в хэш таблице в каждой сессии.

hash -r очищает таблицу хэшей путей.

**CDPATH**

Аналог path для директорий поиска при использовании cd.

**Переменные окружения**

Вызванная программа не знает переменных консоли. Для видимости нужно экспортировать переменную в переменную окружения.

<table border="1" id="bkmrk-export-varnames-%D0%9C%D0%BE%D0%B6%D0%B5" style="border-collapse: collapse; width: 100%; height: 147.172px;"><colgroup><col style="width: 31.4882%;"></col><col style="width: 68.631%;"></col></colgroup><tbody><tr><td>env</td><td>Список переменных окружения</td></tr><tr style="height: 37.1875px;"><td style="height: 37.1875px;">export varnames</td><td style="height: 37.1875px;">Может быть список через пробел</td></tr><tr style="height: 29.7969px;"><td style="height: 29.7969px;">export varname=value command</td><td style="height: 29.7969px;">Доступность переменной только для определенной команды</td></tr></tbody></table>

source .envfile догружает переменные из файла

Переменные по умолчанию

<table border="1" id="bkmrk-bash_version-%D0%92%D0%B5%D1%80%D1%81%D0%B8%D1%8F-" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 21.7263%;"></col><col style="width: 78.3929%;"></col></colgroup><tbody><tr><td>BASH\_VERSION</td><td>Версия</td></tr><tr><td>BASHPID</td><td>  
</td></tr><tr><td>GROUPS</td><td>Группы текущего пользователя</td></tr><tr><td>HOSTNAME</td><td>Имя хоста</td></tr><tr><td>OSTYPE</td><td>  
</td></tr><tr><td>PWD</td><td>Текущая рабочая директория</td></tr><tr><td>RANDOM</td><td>Случайное число от 0 до 32767</td></tr><tr><td>UID</td><td>Идентификатор пользователя</td></tr><tr><td>SHELL</td><td>Полный путь к текущей консоли</td></tr></tbody></table>

**Периферийные функции**

<table border="1" id="bkmrk-sleep-n-%D0%9F%D0%B0%D1%83%D0%B7%D0%B0-%D0%BD%D0%B0-n-%D1%81" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 25.9781%;"></col><col style="width: 74.0219%;"></col></colgroup><tbody><tr><td>sleep n</td><td>Пауза на n секунд</td></tr><tr><td>seq 1 10</td><td>Последовательность чисел от 1 до 10</td></tr><tr><td>date '+%Y-%m-%d %H:%M:%S'</td><td>Текущая дата и время</td></tr><tr><td>tail -f fname</td><td>Выводит изменения файла в текущую консоль</td></tr></tbody></table>