Команда History внутри скрипта bash

20

History - это встроенная в оболочку команда, которую я не смог использовать в скрипте 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
Кен Шарп
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=$(...т.д.
Нат
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*файлов.

CLK
источник
1

Создайте скрипт с именем script.shкак показано ниже. Он создает скрипт с именем X и помещает в него Y Количество строк вашей истории.

#!/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

Команда history по умолчанию отключена в скрипте bash, поэтому даже команда history не будет работать в файле .sh. для его перенаправления, пожалуйста, перенаправьте файл bash_history в файл .sh.

или механизм истории может быть включен также путем упоминания файла истории и изменения параметров времени выполнения, как указано ниже

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

примечание: упомянутые выше две строки в верхней части файла скрипта. теперь команда истории будет работать в истории.

linux.cnf
источник
0

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

Amit Singh
источник
-1

Краткий ответ :

использовать history -pдля явного расширения истории.

Пример следует.

Один случай использования часто случается для меня:

  • предыдущая команда получает список имен файлов и печатает на стандартный вывод,
  • Мне нужно отредактировать этот файл с помощью vim.

Так как мой bash был 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!

qeatzy
источник