Linux: командная строка и скрипты bash

Навигация по файловой системе, работа с файлами и правами, конвейеры и перенаправление, поиск через grep и find, управление процессами, написание скриптов bash.

Лабораторные по операционным системам почти всегда проходят в Linux. Набор команд, который реально нужен, невелик — его можно освоить за вечер и потом использовать всю учёбу.

Навигация и файлы

pwd                      # где я нахожусь
ls -lah                  # подробно, с размерами и скрытыми файлами
cd /var/log              # переход, cd - вернёт в предыдущий каталог

mkdir -p proj/src/utils  # создать вложенные каталоги разом
cp -r src backup         # копирование каталога
mv old.txt new.txt       # переименование или перемещение
rm -rf temp/             # удаление без подтверждения — осторожно
touch file.txt           # создать пустой файл

cat file.txt             # вывести целиком
less file.txt            # постранично, выход q
head -20 file.txt        # первые 20 строк
tail -f /var/log/app.log # следить за дописываемым файлом
wc -l file.txt           # число строк
Команда rm -rf не спрашивает подтверждения и не имеет корзины. Перед её запуском проверьте текущий каталог через pwd: выполненная не там, она уничтожает данные безвозвратно.

Права доступа

Права записываются тремя группами по три бита:

  r (4) — чтение,  w (2) — запись,  x (1) — выполнение

  rwx r-x r--  =  754
  ↑    ↑   ↑
  владелец группа остальные

Частые значения:
  644 (rw-r--r--)  обычный файл
  755 (rwxr-xr-x)  скрипт или каталог
  600 (rw-------)  файл с паролями, ключи
  700 (rwx------)  приватный каталог
chmod 755 script.sh
chmod +x script.sh          # добавить право выполнения всем
chmod u+w,go-w file.txt     # владельцу запись, остальным запретить
chown user:group file.txt   # сменить владельца

umask                       # маска прав для новых файлов
sudo command                # выполнить от root

# Для каталога право x означает возможность войти в него,
# а r — прочитать список файлов. Без x каталог недоступен,
# даже если r установлено.

Конвейеры и перенаправление

command > file.txt        # вывод в файл (перезапись)
command >> file.txt       # дописать в конец
command 2> errors.txt     # только ошибки
command &> all.txt        # и вывод, и ошибки
command < input.txt       # ввод из файла

# Конвейер: выход одной команды на вход другой
cat access.log | grep '404' | wc -l

# Топ-10 самых частых IP в логе — классика лабораторной
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

# Найти пять самых больших файлов в каталоге
du -ah /var/log | sort -rh | head -5

tee file.txt              # и на экран, и в файл
xargs                     # передать вывод как аргументы

Поиск

# grep — поиск по содержимому
grep 'error' app.log
grep -i -n 'Error' app.log       # без учёта регистра, с номерами строк
grep -r 'TODO' ./src              # рекурсивно по каталогу
grep -v 'debug' app.log           # инвертировать: строки БЕЗ слова
grep -c 'error' app.log           # только количество
grep -E '^[0-9]{3}-[0-9]{4}$' f   # регулярное выражение

# find — поиск по свойствам файлов
find . -name '*.log'
find /var -size +100M             # больше 100 МБ
find . -mtime -7                  # изменённые за последние 7 дней
find . -type f -name '*.tmp' -delete
find . -name '*.txt' -exec grep -l 'важно' {} \;

# sed — потоковая замена
sed 's/старое/новое/g' file.txt          # вывод с заменой
sed -i 's/localhost/127.0.0.1/g' cfg     # правка на месте

Процессы

ps aux                    # все процессы
ps aux | grep python      # найти конкретный
top                       # монитор в реальном времени, htop нагляднее

kill 1234                 # мягкое завершение (SIGTERM)
kill -9 1234              # принудительное (SIGKILL), крайняя мера
pkill -f 'python app.py'  # по имени команды

command &                 # запуск в фоне
jobs                      # фоновые задачи текущей сессии
fg %1                     # вернуть на передний план
nohup command &           # продолжит работу после выхода из сессии

free -h                   # память
df -h                     # место на дисках
systemctl status nginx    # состояние службы
journalctl -u nginx -f    # её логи в реальном времени
Сигнал -9 не даёт процессу закрыть файлы и сохранить состояние. Сначала пробуйте обычный kill: большинство программ корректно завершаются по SIGTERM, а принудительное убийство может повредить данные.

Скрипты bash

#!/usr/bin/env bash
#
# Резервное копирование каталога с ротацией старых архивов.

set -euo pipefail        # выход при ошибке, при необъявленной переменной,
                          # и при сбое в любой части конвейера

SRC="${1:-/var/www}"      # первый аргумент или значение по умолчанию
DEST="${2:-/backup}"
KEEP=7                    # сколько архивов хранить

if [[ ! -d "$SRC" ]]; then
    echo "Каталог не найден: $SRC" >&2
    exit 1
fi

mkdir -p "$DEST"
STAMP=$(date +%Y-%m-%d_%H%M)
ARCHIVE="$DEST/backup_$STAMP.tar.gz"

echo "==> Архивирую $SRC"
tar -czf "$ARCHIVE" -C "$(dirname "$SRC")" "$(basename "$SRC")"

SIZE=$(du -h "$ARCHIVE" | cut -f1)
echo "    готово: $ARCHIVE ($SIZE)"

# Удаляем всё, кроме последних KEEP архивов
mapfile -t OLD < <(ls -1t "$DEST"/backup_*.tar.gz 2>/dev/null | tail -n +$((KEEP+1)))
for f in "${OLD[@]:-}"; do
    [[ -n "$f" ]] && { rm -f "$f"; echo "    удалён старый: $(basename "$f")"; }
done
# Основные конструкции

if [[ -f "$file" ]]; then echo 'файл есть'; fi
if [[ $n -gt 10 ]]; then echo 'больше 10'; fi
if [[ "$s" == "да" ]]; then echo 'согласие'; fi

for f in *.txt; do echo "$f"; done
for i in {1..10}; do echo $i; done
while read -r line; do echo "$line"; done < input.txt

case "$1" in
    start) echo 'запуск' ;;
    stop)  echo 'останов' ;;
    *)     echo 'использование: $0 {start|stop}'; exit 1 ;;
esac

function check() {
    local path="$1"
    [[ -e "$path" ]] && return 0 || return 1
}

# Проверки файлов: -f файл, -d каталог, -e существует,
# -r читаемый, -w записываемый, -x исполняемый, -z строка пуста

Строка set -euo pipefail в начале скрипта — самая полезная привычка: без неё скрипт продолжит выполняться после ошибки и может натворить бед, работая с пустыми переменными.

Автоматизация по расписанию

crontab -e               # редактировать расписание
crontab -l               # посмотреть

# Формат: минута час день месяц день_недели команда
0 3 * * *      /opt/backup.sh              # каждый день в 3:00
*/15 * * * *   /opt/check.sh               # каждые 15 минут
0 9 * * 1      /opt/weekly-report.sh       # по понедельникам в 9:00
@reboot        /opt/startup.sh             # при загрузке

# Вывод лучше писать в лог, иначе cron шлёт письма
0 3 * * * /opt/backup.sh >> /var/log/backup.log 2>&1

Что пригодится в лабораторных

Частые вопросы

Чем отличается sudo от su?

sudo выполняет одну команду с правами root, требуя ваш пароль. su переключает сессию на другого пользователя и требует его пароль. sudo безопаснее: действия логируются, а права выдаются точечно.

Почему скрипт не запускается, хотя файл есть?

Чаще всего не установлено право выполнения — нужен chmod +x. Вторая по частоте причина: файл сохранён с переносами строк Windows, и интерпретатор не находит путь в первой строке. Лечится командой dos2unix.

Как посмотреть, что занимает место на диске?

Сначала df -h для общей картины по разделам, затем du -sh /* для поиска тяжёлых каталогов, спускаясь вглубь. Утилита ncdu делает то же интерактивно и намного удобнее.

Читайте также

Сделаем работу по этой теме

Опишите задачу — ответим в течение 15 минут в личных сообщениях ВКонтакте, назовём срок и цену. Предоплаты за оценку нет.

  • Оценка заявки бесплатно
  • Правки по замечаниям преподавателя
  • Работы по всем техническим и IT-дисциплинам

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