Comando de historia dentro del script bash

20

History es un comando integrado en shell que no pude usar en un script BASH. Entonces, ¿hay alguna manera de lograr esto usando el script BASH?
Aquí vamos mi guión para ti:

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

Respuestas:

32

Bash deshabilita el historial en shells no interactivos de forma predeterminada, pero puede activarlo.

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

Pero si está intentando monitorear la actividad en ese servidor, el historial de shell no sirve para nada (es trivial ejecutar comandos que no aparecen en el historial). Consulte ¿Cómo puedo registrar todos los inicios de procesos en Linux ?

Si está depurando un script, el historial de shell no es la mejor manera de obtener información útil. Una herramienta mucho mejor es la función de seguimiento de depuración: coloque set -xcerca de la parte superior de la secuencia de comandos. La traza se escribe en error estándar.

Gilles 'SO- deja de ser malvado'
fuente
Esto se niega a trabajar en un guión:histtest.sh: 5: set: Illegal option -o history
Ken Sharp
44
@KenSharp Esto se debe a que trataste de usarlo en un script sh (y tu shguión está marcado por la redacción exacta del mensaje de error). Para acceder al historial de bash, debe usar bash (secuencia de comandos que comienza con #!/bin/basho #!/usr/bin/env bash).
Gilles 'SO- deja de ser malvado'
1
@KenSharp Sí, lo es. Obviamente lo ejecutó debajo del tablero, dado el mensaje de error. Bash no tiene el mensaje de error Illegal option(diría set: history: invalid option name).
Gilles 'SO- deja de ser malvado'
El problema con esto es que añade todos los comandos siguientes set -o history a la historia que luego va a ser rellenado con entradas como if [... vars=$(...etc.
Nath
1
@nath Eso es lo que preguntó la pregunta. Es bastante inútil, como señalo. La actividad de monitoreo es un problema difícil que el historial de shell no resolverá. Si está depurando un script, set -xes mucho más útil.
Gilles 'SO- deja de ser malvado'
6

No estoy seguro de si realmente usa la capacidad de historial cuando se ejecuta de forma no interactiva, de lo contrario, cada script de shell que ejecute desordenaría su historial de comandos.

¿Por qué no ir directamente a la fuente ${HOME}/.bash_history, reemplazar history | tail -100con tail -100 ${HOME}/.bash_history. (Si usa marcas de tiempo, probablemente tenga que hacer algo similar grep -v ^# ${HOME}/.bash_history | tail -100).

Kjetil Jorgensen
fuente
De hecho, con las marcas de tiempo, deberías greq -v '^#[0-9]\+$'(a veces "ejecuto" comentarios en mi shell ...)
PlasmaBinturong
Y en realidad, en mi caso, necesito usar el número correcto de línea de historial , pero hay una diferencia entre la salida historyy la salida del grepmétodo ...
PlasmaBinturong
Ok, la solución era para sincronizar la lista histórica con el archivo histórico de la siguiente manera: history -a; history -c; history -r. (agregar, borrar, leer)
PlasmaBinturong
2

Si desea usar la salida del historycomando desde una sesión de shell activa en un script, puede usar un alias para ejecutar el comando primero. Luego, en el mismo alias, puede llamar al resto del script. Con dicha configuración, puede lograr esencialmente el mismo resultado que tener el historycomando en el script real.

Por ejemplo, puede crear un alias como este, suponiendo que el nombre del script sea script.sh:

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

Y cambie el guión a esto:

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

Encontré esta pregunta mientras escribía un proceso para combinar, ordenar y sincronizar ~/bash_historyarchivos en dos computadoras para que sea fácil buscar comandos que he usado en el pasado.

Es mucho menos complicado actualizar mi archivo de historial acumulativo sin tener que iniciar sesión en un nuevo shell para ~/bash_historyactualizarlo. Para monitorear un servidor esto obviamente no funcionará, como se menciona en las otras respuestas.

Mi uso en particular es:

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

El script hby.shluego extrae todas las entradas únicas de todos los ~/.bash_history*archivos.

clk
fuente
1

Cree una secuencia de comandos con el nombre a script.shcontinuación. Crea un script llamado X y pone Y Número de líneas de su historial en él.

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

Luego, si desea crear un script para realizar una tarea llamada "tarea" en la que ha estado trabajando durante las últimas 14 líneas ejecutadas

script.sh task 14

¡Luego limpia tu historial para hacer un buen guión!

Eric
fuente
histtest.sh: 5: set: Illegal option -o history
Ken Sharp
1

El comando de historial está deshabilitado de manera predeterminada en el script bash, por eso incluso el comando de historial no funcionará en el archivo .sh. para su redirección, redirija amablemente el archivo bash_history dentro del archivo .sh.

o el mecanismo de historial también se puede habilitar al mencionar el archivo de historial y cambiar los parámetros de tiempo de ejecución como se menciona a continuación

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

nota: mencionado anteriormente dos líneas en la parte superior del archivo de script. ahora el comando de historia funcionará en la historia.

linux.cnf
fuente
0

Cada usuario tiene su propio archivo de historial que es el resultado del comando de historial. En lugar de usar el comando de historial en su script de shell, puede usar el archivo de historial para el usuario. Habrá un .bash_historyarchivo en el directorio de inicio del usuario, que será el archivo de historial para el usuario.

amit singh
fuente
-1

Respuesta corta :

se usa history -ppara realizar una expansión de historial explícitamente.

Un ejemplo sigue.

Un caso de uso que me sucede mucho es:

  • el comando anterior obtiene una lista de nombres de archivos e imprime en stdout,
  • Necesito editar esos archivos con vim.

Como ha sido mi fiesta set -o histexpand, generalmente lo que hice fue escribir

vim $(!!)

para editar aquellos archivos listados por comando anterior.

Lamentablemente, a veces ocurre un error, así que habilito verificar por shopt -s histverify .

Ahora puedo verificar la expansión, con el costo de una Returnclave adicional .

Hoy quiero envolver esos detalles en una función bash ya que los uso mucho,

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

Aquí uso dos anidados command substitution, el interno para expandir !!al comando anterior, el externo para ejecutarlo y obtener el resultado.

¡Ahora puedo lograr el mismo efecto, con solo tres teclas, y una de ellas es Return!

qeatzy
fuente