Estoy tratando de crear un script bash que guardará el historial del terminal en un archivo llamado hist.txt. El uso history > hist.txt
no parece funcionar en el script bash, pero funciona bien cuando se ejecuta en la línea de comando.
Cualquier orientación es muy apreciada.
Gracias Judy
~/.bash_history
archivo del usuario .Respuestas:
Respuesta corta
Ejecute el script con
source
o.
:o
Este último es ligeramente más compatible en diferentes conchas.
Respuesta larga
Esta pregunta destaca un punto importante, que es que los scripts de shell se ejecutan en su propio contexto. Para ver lo que esto significa, considere el siguiente script de shell:
Si ejecuta esto, obtendrá un resultado similar a este:
Pero notará que después de ejecutar el script, todavía está en el directorio en el que se encontraba antes de ejecutarlo: el
cd /
interior del script no ha afectado realmente su sesión, solo afectó el contexto en el que se estaba ejecutando el script, que se crea para que se ejecute el script y se destruye una vez que vuelve.El
source
comando 'leerá y ejecutará comandos del argumento del nombre de archivo en el contexto actual del shell', por lo que cualquier comando comocd
este afectará su sesión actual. Sisource
tuviera que ejecutar el script anterior al pasarlo, encontraría que termina dentro del directorio raíz después de que se ejecutó.En este caso, el problema es que el
history
comando le proporciona el historial del contexto actual del shell; el contexto de shell en el que se ejecuta su script sin usarsource
no tiene historial, por lo que no escribe nada en el archivo de salida. Si lo usasource
, se ejecutará en el contexto correcto y funcionará como se espera.NB:
source
es un shell integrado, no un programa en sí mismo ; en Bash,source
es sinónimo de.
, pero en algunos shells solo.
funcionará. Lo he usadosource
en esta respuesta porque es más fácil de leer que.
, pero para una compatibilidad máxima,.
debería ser usado.fuente
En primer lugar, tenga en cuenta que su historial ya está en un archivo. Si está ejecutando bash, su nombre suele ser
~/.bash_history
. Más específicamente, es lo que sea que haya configurado la variableHISTFILE
. Si desea copiarlo a otro archivo, simplemente ejecutecat "$HISTFILE" > hist.txt
Ahora, por qué el
history
comando no funciona en un script de shell bash, es porque los scripts se ejecutan en un shell hijo no interactivo de su sesión de shell actual. Los shells secundarios no heredan todo el entorno del padre (por lo tanto, no todas las variables establecidas), solo las variables que se han exportado. Para ilustrar, el siguiente script hará eco del valor de la variable$var
:Ahora, establece
$var
algo y ejecuta el script:A continuación, exporte la variable primero:
Como puede ver, cuando la variable se ha exportado, está disponible para shells secundarios.
Como mencioné antes, el historial se almacena en el archivo señalado por la variable
$HISTFILENAME
. Como eso no se exporta de forma predeterminada, no se establece cuando se ejecuta un script:Como puede ver en el ejemplo anterior, la variable
HISTFILE
se establece en mi sesión de shell normal, pero está vacía cuando se ejecuta el script.Entonces, para obtener el historial, tiene algunas opciones:
El valor predeterminado
HISTFILE
valor es$HOME/.bash_history
. Si no ha cambiado eso, simplemente puede ejecutar este comando en su script:Puede pasar la
$HISTFILE
variable a su script ycat
eso:Guarde lo anterior como
foo.sh
y ejecute así:Asegúrese de que la variable se exporte. Agregue esta línea a sus archivos
~/.bash_profile
(si existe) o~/.profile
(si~/.bash_profile
no existe):Luego, cierre la sesión y vuelva a iniciarla y debería poder ejecutar
history > hist.txt
desde un script como se esperaba. Esto se debe a queexport VAR
significa "poner $ VAR a disposición de los shells secundarios". En términos prácticos, esto significa que el valor deHISTFILE
será heredado por el shell no interactivo que utiliza para ejecutar su script.Ahora, aunque
HISTFILE
se establecerá, el shell no lo ha leído al ejecutar el script. Entonces, para que funcione,history -r
primero debes leerlo . El guión completo se vería así:Alternativamente, simplemente expórtelo manualmente antes de ejecutar el script:
Pero aún lo necesitarás
history -r
en el guión.Puede
source
hacerlo como lo sugiere la respuesta de @ p0llard .fuente