Як використовувати команду history в Linux

Оболонка Linux запам’ятовує послідовність введених вами команд, надаючи можливість переглядати їх та повторно використовувати. Засвоївши особливості команди `history` у Linux, ви зможете значно підвищити свою продуктивність.

Керування історією команд

Як влучно зауважив Джордж Сантаяна, “Ті, хто не пам’ятає минулого, приречені його повторювати”. На жаль, в Linux, якщо ви не можете згадати введених раніше команд, ви не зможете їх відтворити, навіть якщо виникне така потреба.

Саме тут приходить на допомогу команда `history` в Linux. Вона дозволяє переглядати та повторювати попередні команди. Це не просто спосіб заощадити час або уникнути нудної роботи – це шлях до ефективності та точності. Чим довшою та складнішою є команда, тим важче її запам’ятати та ввести без помилок. Помилки бувають двох видів: ті, що перешкоджають виконанню команди, і ті, що дозволяють команді працювати, але призводять до непередбачуваних наслідків.

Команда `history` допомагає уникнути цих проблем. Як і більшість команд Linux, вона має більше можливостей, ніж здається на перший погляд. Навчившись використовувати команду `history`, ви значно покращите свою роботу з командним рядком Linux. Це розумна інвестиція часу. Існують значно ефективніші способи використання історії команд, ніж просто багаторазове натискання клавіші “стрілка вгору”.

Основи команди `history`

У найпростішому вигляді, щоб скористатися командою `history`, достатньо ввести її назву:

history

Після цього у вікні терміналу з’явиться перелік раніше введених команд.

Команди пронумеровані, причому останні використані мають найбільші номери.

Щоб переглянути певну кількість команд, можна передати число в команду `history` як аргумент. Наприклад, для виведення останніх 10 команд, введіть:

history 10

Аналогічного результату можна досягти, використовуючи конвеєр з командою `tail`. Для цього введіть:

history | tail -n 10

Повторення попередніх команд

Щоб повторно виконати команду зі списку історії, введіть знак оклику `!` та номер команди, без пробілів між ними.

Наприклад, щоб повторити команду під номером 37, потрібно ввести:

!37

Щоб повторити останню команду, введіть два знаки оклику `!!`, знову ж таки, без пробілів:

!!

Це особливо зручно, коли ви забули використати `sudo`. Просто введіть `sudo`, пробіл, `!!` і натисніть Enter.

У наступному прикладі ми спочатку ввели команду, яка потребує `sudo`. Замість повторного введення всього рядка, ми можемо заощадити час та натискання клавіш, просто ввівши `sudo !!`:

mv ./my_script.sh /usr/local/bin/
sudo !!

Ви можете використовувати номер команди зі списку, щоб повторити її, або `!!` для повторного виконання останньої команди. Але що робити, якщо потрібно повторити, наприклад, п’яту чи восьму команду з кінця?

Ви можете використати знак оклику `!`, дефіс `-` та номер попередньої команди, щоб повторити її (знову ж таки, без пробілів).

Для повторення 13-ї команди з кінця, потрібно ввести:

!-13

Пошук команд за частиною рядка

Щоб повторити останню команду, яка починається з певного рядка, введіть знак оклику `!` і потрібний рядок, без пробілів, а потім натисніть Enter.

Наприклад, для повторення останньої команди, що починається з `sudo`, введіть:

!sudo

Тут є певний ризик. Якщо остання команда, яка починалася з `sudo`, не та, що ви очікували, ви виконаєте неправильну команду.

Для додаткової безпеки можна використовувати модифікатор `:p` (print), як показано нижче:

!sudo:p

Це змусить `history` надрукувати команду у вікні терміналу, але не виконувати її. Це дає можливість перевірити команду перед її використанням. Якщо це потрібна команда, натисніть клавішу “стрілка вгору”, а потім Enter, щоб виконати її.

Якщо потрібно знайти команду, що містить певну послідовність символів, використовуйте знак оклику `!` та знак питання `?`.

Наприклад, щоб знайти та виконати першу команду, яка містить слово “aliases”, введіть:

!?aliases

Цей метод знайде будь-яку команду, що містить `aliases` у будь-якому місці рядка.

Інтерактивний пошук

Інтерактивний пошук дозволяє переглядати список команд, що відповідають критеріям пошуку, та вибирати потрібну.

Просто натисніть Ctrl+r, щоб розпочати пошук.

Введіть пошуковий запит, і з’явиться перша команда, яка йому відповідає. Символи, що ви вводите, з’являються між зворотними лапками \` і апострофом \`. Команди оновлюються по мірі введення нових символів.

Кожне натискання Ctrl+r приводить до пошуку в зворотному напрямку по історії команд.

Коли ви натиснете Enter, команда, що відображається, буде виконана.

Щоб відредагувати команду перед виконанням, натисніть клавішу зі стрілкою вліво або вправо.

Команда з’явиться у командному рядку і може бути відредагована.

Можна використовувати й інші інструменти Linux для пошуку в списку історії. Наприклад, щоб передати вивід `history` в `grep` та знайти команди, що містять рядок “aliases”, можна скористатись командою:

history | grep aliases

Зміна останньої команди

Якщо потрібно виправити друкарську помилку, а потім повторно виконати команду, можна скористатися символом каретки `^`. Це корисний прийом, коли ви ввели команду з помилкою або хочете виконати її з іншим параметром.

Щоб скористатись цим методом, введіть (без пробілів) каретку `^`, текст, що потрібно замінити, ще одну каретку, текст, яким потрібно замінити, ще одну каретку та натисніть Enter.

Наприклад, припустимо, ви вводите команду і випадково ввели “shhd” замість “sshd”:

sudo systemctl start shhd

Це легко виправити, ввівши:

^shhd^sshd^

Команда буде виконана зі “shhd”, виправленим на “sshd”.

Видалення команд зі списку історії

Команди можна видалити зі списку історії за допомогою опції `-d` (delete). Немає потреби зберігати команди з помилками в історії.

Використайте `grep`, щоб знайти команду, передайте її номер в команду `history` з параметром `-d`, щоб видалити її, а потім знову пошукайте, щоб переконатися, що її немає:

history | grep shhd
history -d 83
history | grep shhd

Опції `-d` можна передати діапазон команд. Для видалення всіх записів з 22 по 32 включно, введіть:

history -d 22 32

Щоб видалити лише останні п’ять команд, можна використовувати від’ємне число, наприклад:

history -d -5

Ручне оновлення файлу історії

Коли ви входите в систему або відкриваєте сеанс терміналу, список історії зчитується з файлу історії. У Bash, файлом історії за замовчуванням є `.bash_history`.

Будь-які зміни, що ви вносите протягом сеансу, записуються у файл історії лише після закриття вікна терміналу або виходу із системи.

Припустимо, ви хочете відкрити інше вікно терміналу та отримати доступ до повного списку історії, включаючи команди, введені у першому вікні. Параметр `-a` (all) дозволяє синхронізувати історію у першому терміналі перед тим, як відкрити другий.

Щоб скористатись цим, введіть:

history -a

Команди будуть безшумно записані до файлу історії.

Якщо потрібно записати усі зміни списку історії до файлу (наприклад, якщо ви видалили старі команди), використайте параметр `-w` (write), наприклад:

history -w

Очищення історії команд

Щоб видалити всі команди зі списку історії, використовуйте параметр `-c` (clear), як показано нижче:

history -c

Якщо ви також хочете примусово записати ці зміни до файлу історії, використайте параметр `-w`, наприклад:

history -w

Безпека та файл історії

Якщо ви використовуєте програми, що вимагають введення конфіденційної інформації (наприклад, паролів) у командному рядку, пам’ятайте, що ця інформація також буде збережена у файлі історії. Якщо ви не бажаєте, щоб певна інформація зберігалася, можна скористатись такою структурою команд, щоб одразу видалити її зі списку історії:

special-app my-secret-password;history -d $(history 1)
history 5

Ця структура містить дві команди, розділені крапкою з комою (;). Розглянемо її детальніше:

`special-app`: назва програми, яку ви використовуєте.
`my-secret-password`: секретний пароль, який потрібно ввести в командному рядку. Це кінець першої команди.
`history -d`: у другій команді ми викликаємо параметр `-d` (видалити) команди `history`. Те, що ми видаляємо, знаходиться в наступній частині команди.
`$(history 1)`: тут використовується підстановка команд. Частина команди, що міститься в $(), виконується в підоболонці. Результат виконання виводиться як текст у вихідній команді. Команда `history 1` повертає попередню команду. Отже, можна розглядати другу команду як `history -d “<попередня команда>”`.

Команда `history 5` дозволяє переконатися, що команда, що містила пароль, видалена зі списку історії.

Проте, є простіший спосіб це зробити. Оскільки Bash ігнорує рядки, що починаються з пробілу, просто додайте пробіл на початку рядка, як показано нижче:

 special-app another-password
history 5

Команда з паролем не буде додана до списку історії. Причина цього в файлі `.bashrc`.

Файл `.bashrc`

Файл `.bashrc` виконується щоразу, коли ви входите в систему або відкриваєте вікно терміналу. Він також містить значення, які керують поведінкою команди `history`. Давайте відредагуємо цей файл за допомогою `gedit`.

Введіть наступне:

gedit .bashrc

У верхній частині файлу ви побачите два записи:

`HISTSIZE`: максимальна кількість записів, яку може містити список історії.
`HISTFILESIZE`: обмеження на кількість рядків, що може містити файл історії.

Ці два значення взаємодіють наступним чином:

Коли ви входите в систему або відкриваєте вікно терміналу, список історії заповнюється з файлу `.bash_history`.
Коли ви закриваєте вікно терміналу, максимальна кількість команд, встановлена у `HISTSIZE`, зберігається у файлі `.bash_history`.
Якщо параметр оболонки `histappend` увімкнено, команди додаються до `.bash_history`. Якщо `histappend` не встановлено, `.bash_history` буде перезаписано.
Після збереження команд зі списку історії у `.bash_history`, файл історії обрізається, щоб містити не більше ніж `HISTFILESIZE` рядків.

Також у верхній частині файлу ви побачите запис для значення `HISTCONTROL`.

Ви можете встановити це значення, щоб виконати будь-яку з наступних дій:

`ignorespaces`: рядки, що починаються з пробілу, не додаються до списку історії.
`ignoredups`: повторювані команди не додаються до файлу історії.
`ignoreboth`: вмикає обидва з перелічених вище параметрів.

Також можна вказати певні команди, які не потрібно додавати до списку історії. Розділіть їх двокрапкою `:` і візьміть у лапки `“…”`.

Для додавання рядка до файлу `.bashrc` та заміни команд, які ви бажаєте ігнорувати, використовуйте таку структуру:

export HISTIGNORE="ls:history"

Використання міток часу

Щоб додати мітки часу до списку історії, використовуйте параметр `HISTTIMEFORMAT`. Для цього додайте рядок, подібний до наведеного нижче, до вашого файлу `.bashrc`:

export HISTTIMEFORMAT="%c "

Зверніть увагу, що перед закриваючими лапками є пробіл. Це запобігає злиттю мітки часу з командами у списку.

Тепер, коли ви виконуєте команду `history`, ви побачите мітки дати та часу. Зауважте, що команди, що були в списку до додавання міток часу, матимуть мітку часу, яка збігається з датою та часом першої команди, що отримала мітку часу. У прикладі нижче це була команда 118.

Це досить довга мітка часу. Проте, можна використовувати інші маркери, ніж `%c`, для її уточнення. Ось інші токени, які можна використовувати:

`%d`: день
`%m`: місяць
`%y`: рік
`%H`: година
`%M`: хвилини
`%S`: секунди
`%F`: повна дата (формат рік-місяць-день)
`%T`: час (формат година:хвилини:секунди)
`%c`: повна дата та час (формати день-дата-місяць-рік та години:хвилини:секунди)

Давайте поекспериментуємо та використаємо декілька різних токенів:

export HISTTIMEFORMAT="%d n%m %T "

Вивід показує день, місяць та час.

Однак, якщо прибрати день та місяць, буде показано лише час.

Будь-які зміни, внесені до `HISTTIMEFORMAT`, застосовуються до всього списку історії. Це можливо, оскільки час для кожної команди зберігається як кількість секунд з епохи Unix. Директива `HISTTIMEFORMAT` лише вказує формат, який використовується для відтворення цієї кількості секунд у зручний для читання формат, наприклад:

export HISTTIMEFORMAT="%T "

Результати тепер виглядають більш чітко.

<img loading=”lazy” decoding=”async” src=”https://techukraine.net/wp-content/uploads/2021/12/1640830296_299_Як-використовувати-команду-history-в-Linux.png” width=”