Команда історії всередині скрипту bash


20

Історія - це команда, побудована в командній команді, я не зміг її використати в сценарії BASH. Отже, чи є спосіб досягти цього за допомогою сценарію BASH?
Ось ми для мого сценарію:

#!/bin/bash
history |  tail -100 > /tmp/history.log
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

Відповіді:


32

Bash вимикає історію в неінтерактивних оболонках за замовчуванням, але ви можете ввімкнути її.

#!/bin/bash
HISTFILE=~/.bash_history
set -o history
history | tail 

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

Якщо ви налагоджуєте сценарій, історія оболонок - не найкращий спосіб отримати корисну інформацію. Набагато кращим інструментом є інструмент відстеження налагодження: розмістити set -xбіля вершини сценарію. Слід записується до стандартної помилки.


Він відмовляється працювати за сценарієм:histtest.sh: 5: set: Illegal option -o history
Ken Sharp

4
@KenSharp Це тому, що ви намагалися використовувати його в скрипті sh (і вашому) sh тире судить за точним формулюванням повідомлення про помилку). Для доступу до історії bash вам потрібно використовувати bash (скрипт, що починається з #!/bin/bashабо #!/usr/bin/env bash).
Жиль "ТАК - перестань бути злим"

1
@KenSharp Так. Ви, очевидно, запустили його під тире, враховуючи повідомлення про помилку. У Bash немає повідомлення про помилку Illegal option(воно би сказало set: history: invalid option name).
Жил "ТАК - перестань бути злим"

Проблема в цьому полягає в тому, що він додає всі команди, що слідують set -o history за історією, яка потім буде заповнена записами, як if [... vars=$(...і т.д.
nath

1
@nath Ось до чого задалося питання. Як я зазначаю, це майже безглуздо. Моніторингова діяльність - це важка проблема, яку історія оболонок не вирішить. Якщо ви налагоджуєте сценарій, то set -xце набагато корисніше.
Жил "ТАК - перестань бути злим"

6

Я не впевнений, чи реально він використовує функцію історії під час запуску неінтерактивно, інакше кожен запущений сценарій оболонки збиватиме вашу історію команд.

Чому б не перейти безпосередньо до джерела ${HOME}/.bash_history, замінити history | tail -100на tail -100 ${HOME}/.bash_history. (Якщо ви використовуєте часові позначки, вам, ймовірно, доведеться щось робити в порядку grep -v ^# ${HOME}/.bash_history | tail -100).


Дійсно, із мітками часу, ви насправді повинні greq -v '^#[0-9]\+$'(я іноді "виконую" коментарі у своїй оболонці ...)
PlasmaBinturong

Насправді в моєму випадку мені потрібно використовувати правильний номер рядка історії , але є різниця між результатом historyі виходом grepметоду ...
PlasmaBinturong

Добре, виправлення було синхронізувати список історії з файлом історії , як це: history -a; history -c; history -r. (додати, очистити, прочитати)
PlasmaBinturong

2

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

Наприклад, ви можете створити псевдонім на зразок цього, припускаючи, що ім'я сценарію - script.sh:

alias hy_tmp='history | tail -100 > /tmp/history.log ; bash /patch/to/script.sh'

І змініть сценарій до цього:

#!/bin/bash
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

Це питання я знайшов під час написання процесу комбінування, сортування та синхронізації ~/bash_historyфайлів на двох комп’ютерах, щоб було легко шукати команди, які я використовував у минулому.

Набагато менше клопоту оновлювати мій накопичувальний файл історії, не потребуючи входу в нову оболонку ~/bash_history оновити. Для моніторингу сервера це, очевидно, не спрацює, як зазначено в інших відповідях.

Зокрема, моє використання:

alias hbye='history | cut -c 8- > /home/chris/.bash_history_c; bash /hby.sh

Потім сценарій hby.shвитягує всі унікальні записи з усіх ~/.bash_history*файлів.



1

Створіть сценарій, названий script.shнижче. Він створює сценарій під назвою X і додає в нього кількість рядків вашої історії.

#!/bin/bash
SCRIPT_NAME=$1
NUMBER_OF_LINES_BACK=$2

# Enable History in a non interactive shell
HISTFILE=~/.bash_history
set -o history

# echo shabang line and x number of lines of history to new script
echo \#\!\/bin\/bash > $SCRIPT_NAME.sh; history | tail -n $NUMBER_OF_LINES_BACK >> $SCRIPT_NAME.sh;
chmod u+x $SCRIPT_NAME.sh;

# Open the newly created script with vim
vim $SCRIPT_NAME.sh;
~

Тоді, якщо ви хочете створити сценарій для виконання завдання з назвою "завдання", над яким ви працювали протягом останніх 14 рядків запуску

script.sh task 14

Потім очистіть свою історію, щоб зробити хороший сценарій!


histtest.sh: 5: set: Illegal option -o history
Кен Шарп

1

Команда "Історія" відключена за замовчуванням у bash script, тому навіть команда "історія" не працюватиме у файлі .sh. для його перенаправлення будь ласка, перенаправляйте файл bash_history всередині .sh-файлу.

або механізм історії можна ввімкнути також шляхом згадування файла історії та зміни параметрів часу виконання, як зазначено нижче

#!/bin/bash
HISTFILE=~/.bash_history
set -o history 

Примітка: згадані вище два рядки у верхній частині файлу сценарію. тепер команда історії буде працювати в історії.


0

У кожного користувача є власний файл історії, який є результатом команд історії. Замість використання команди команд у вашому скрипті оболонки ви можете використовувати файл історії для користувача. У .bash_historyдомашньому каталозі користувача буде файл, який буде файлом історії для користувача.


-1

Коротка відповідь :

використовувати history -pдля явного розширення історії.

Приклад випливає.

Один із випадків використання для мене трапляється багато:

  • попередня команда отримає список назв файлів та роздрукує до stdout,
  • Мені потрібно відредагувати цей файл із vim.

Оскільки мій баш був set -o histexpand, зазвичай те, що я робив, набирає текст

vim $(!!)

редагувати файли, перелічені попередньою командою.

На жаль іноді трапляється помилка, тому я вмикаю перевірку shopt -s histverify .

Тепер я можу перевірити розширення з вартістю одного додаткового Returnключа.

Сьогодні я хочу перетворити ці деталі на функцію bash, оскільки я їх багато використовую,

function vk() {
    set -o history && set -o histexpand;
    vim -i ~/.viminfok $($(history -p !!));
}

Тут я використовую дві вкладені command substitution, внутрішню для розширення !!на попередню команду, зовнішню для її виконання та отримання результату.

Тепер я можу досягти такого ж ефекту, маючи лише три ключові, і один з них є Return!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.