notby.NET Logo

Улучшение командной оболочки Bash

Во многих дистрибутивах Linux в терминале и скриптах используется Bash по умолчанию. В статье я рассмотрю улучшения Bash, которые я использую для повседневной работы. По ходу моей деградации и развития статья может дорасти до новых фишек, если меня что-то зацепит или кто-то подкинет идею.

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

1. Поиск по истории по ходу ввода команды

Если в Bash например ввести ping и нажать стрелку или , то произойдет переключение на предыдущую команду, которая была введена ранее. Учитывая, что я сильно привык к оболочке csh, которая в FreeBSD из коробки выполняет поиск окончания команды по начальному вводу команды. Так что нужно сделать подобное поведение и в Bash.

Открываем файл настройки оболочки Bash пользователя

nano ~/.bashrc

В конец файла добавляем две строки

bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-forward'

Сохраняем и закрываем файл.

В текстовой редакторе nano открыт файл ~/.bashrc, внутри файла добавлены три строки: # Search through input history with arrows, bind '"\e[A": history-search-backward', bind '"\e[B": history-search-forward' и задан вопрос "Save modified buffer?" для сохранения изменений

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

logout

Заходим вновь в учетную запись пользователя.

Вводим команду ping и нажимаем стрелки или . Поиск осуществляется по истории команд, которые начинаются с ping, например, там в выводе будет:

ping 1.1.1.1
ping 192.168.0.1
ping 8.8.8.8

Это очень удобно пользоватся, особенно с длинными командами.

Чтобы стереть текст после курсора нажимаем Ctrl + K

2. Увеличение размера истории команд

Открываем файл настройки оболочки Bash пользователя

nano ~/.bashrc

Находим параметры HISTSIZE, HISTFILESIZE, раскомментируем (если необходимо) их и увеличиваем значения

HISTSIZE=5000
HISTFILESIZE=10000
  • HISTSIZE — количество хранимых команд во время сессии Bash, до выхода из терминала;
  • HISTFILESIZE — количество хранимых команд в файле .bash_history.

Сохраняем и закрываем файл.

В текстовой редакторе nano открыт файл ~/.bashrc, внутри файла заменено значение HISTSIZE на 5000, а значение HISTFILESIZE на 10000 и задан вопрос "Save modified buffer?" для сохранения изменений

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

3. Удаление дубликатов команд из истории

По умолчанию в файл .bash_history истории команд Bash сохраняется каждая введенная команда, даже если она уже была ранее введена множество раз. Из-за этого файл начинает разрастатся и становится сложнее работать с историей.

3.1. Скрипт для удаления дубликатов

Создаем скрипт очистки дубликатов истории Bash в домашней директории пользователя

nano ~/dedup_bash_history.sh

Добавляем следующий скрипт

#!/bin/bash

# Путь к основному файлу истории
HISTFILE=~/.bash_history

# Проверяем, существует ли файл истории
if [ ! -f "$HISTFILE" ]; then
    echo "Error: file $HISTFILE does not exist."
    exit 1
fi

# Создаём резервную копию
BACKUP_FILE="$HISTFILE.bak.$(date +%Y%m%d_%H%M%S)"
cp "$HISTFILE" "$BACKUP_FILE"

# Удаляем дубликаты, сохраняя последнее вхождение каждой команды
tac "$HISTFILE" | awk '!seen[$0]++' | tac > "$HISTFILE.tmp"
mv "$HISTFILE.tmp" "$HISTFILE"

# Подсчитываем количество удалённых строк
ORIGINAL_LINES=$(wc -l < "$BACKUP_FILE")
NEW_LINES=$(wc -l < "$HISTFILE")
REMOVED_LINES=$((ORIGINAL_LINES - NEW_LINES))

# Выводим информацию работы скрипта
echo "Cleaning duplicates from command history for user: $USER"
echo "Original number of lines: $ORIGINAL_LINES"
echo "New number of lines: $NEW_LINES"
echo "Duplicates removed: $REMOVED_LINES"

# Удаляем резервную копию
rm "$BACKUP_FILE" # закомментировать, если нужно хранить копию с дубликатами

Делаем скрипт исполняемым

chmod +x ~/dedup_bash_history.sh

Выполняем скрипт

~/dedup_bash_history.sh
В терминале Debian выполнена команда “nano ~/dedup_bash_history.sh”, затем скрипт был сделан исполняемым командой “chmod +x ~/dedup_bash_history.sh” и запущен командой “~/dedup_bash_history.sh”. Выведена информация о работе скрипта, в которой сказано, что было удалено 268 дубликатов из истории Bash.

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

3.2. Автоматическая очистка дубликатов

Открываем редактор crontab

crontab -e

и добавляем в конец файла строку

10 20 * * 5 ~/dedup_bash_history.sh > /dev/null 2>&1

Данная строка будет запускать скрипт каждую пятницу (5) в 20 часов 10 минут. Весь вывод будет подавлен > /dev/null 2>&1, ведь скрипт при запуске выводит информацию о своей работе.

Добавлять исполнение по времени для рабочего компьютера, не так логично, как для сервера. Ведь компьютер может быть выключен в момент выполнения скрипта.

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

@reboot ~/dedup_bash_history.sh > /dev/null 2>&1
В терминале Debian выполнена команда “crontab -e”, которая открыла текстовой редакторе nano для редактирования файла crontab в безопасном режиме, в конец файла добавлены строки “#10 20 * * 5 ~/dedup_bash_history.sh > /dev/null 2>&1” и “@reboot ~/dedup_bash_history.sh > /dev/null 2>&1”

Выбираем желаемый вариант запуска скрипта или выбираем оба и выходим из редактора crontab.