¿La salida de un comando Bash está almacenada en algún registro? Por ejemplo, algo similar a $?
capturar la salida en lugar del estado de salida.
Podría asignar la salida a una variable con:
output=$(command)
pero eso es más escribir ...
¿La salida de un comando Bash está almacenada en algún registro? Por ejemplo, algo similar a $?
capturar la salida en lugar del estado de salida.
Podría asignar la salida a una variable con:
output=$(command)
pero eso es más escribir ...
Respuestas:
Puede usar $(!!)
para volver a calcular (no reutilizar) la salida del último comando.
El !!
solo ejecuta el último comando.
$ echo pierre
pierre
$ echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre
$(your_cmd)
a través de las teclas de retroceso: de `your_cmd`
acuerdo con el manual de Gnu Bash, son funcionalmente idénticas. Por supuesto, esto también está sujeto a la advertencia planteada por @memecs
git diff $(!!)
donde el comando anterior era una find
invocación.
$()
lugar de backticks. Pero probablemente nada para perder el sueño. github.com/koalaman/shellcheck/wiki/SC2006
$()
.
La respuesta es no. Bash no asigna ninguna salida a ningún parámetro o bloque en su memoria. Además, solo se le permite acceder a Bash por sus operaciones de interfaz permitidas. No se puede acceder a los datos privados de Bash a menos que los piratee.
Una forma de hacerlo es mediante el uso de trap DEBUG
:
f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUG
Ahora el comando stdout y stderr ejecutados más recientemente estarán disponibles en /tmp/out.log
El único inconveniente es que ejecutará un comando dos veces: una para redirigir la salida y el error a /tmp/out.log
otra y normalmente. Probablemente hay alguna forma de prevenir este comportamiento también.
rm -rf * && cd ..
, cuando escribo , no solo se borrará el directorio actual, sino también el directorio principal. este enfoque me parece muy peligroso
trap '' DEBUG
Si está en Mac y no le importa almacenar su salida en el portapapeles en lugar de escribir en una variable, puede usar pbcopy y pbpaste como solución alternativa.
Por ejemplo, en lugar de hacer esto para buscar un archivo y diferenciar su contenido con otro archivo:
$ find app -name 'one.php'
/var/bar/app/one.php
$ diff /var/bar/app/one.php /var/bar/two.php
Podrías hacer esto:
$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.php
La cadena /var/bar/app/one.php
está en el portapapeles cuando ejecuta el primer comando.
Por cierto, pb en pbcopy
y pbpaste
significa cartón, sinónimo de portapapeles.
$ find app -name 'one.php' | xclip $ diff $(xclip -o) /var/bar/two.php
pbpaste
junto con la sustitución de comandos.
Inspirado por la respuesta de anubhava, que creo que en realidad no es aceptable, ya que ejecuta cada comando dos veces.
save_output() {
exec 1>&3
{ [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
exec > >(tee /tmp/current)
}
exec 3>&1
trap save_output DEBUG
De esta manera, la salida del último comando está en / tmp / last y el comando no se llama dos veces.
grep
o git diff
+1 de todos modos
Como dijo konsolebox, tendrías que hackear el propio bash. Aquí hay un buen ejemplo de cómo se puede lograr esto. El repositorio stderred (en realidad destinado a colorear stdout) da instrucciones sobre cómo construirlo.
Lo intenté: definiendo un nuevo descriptor de archivo dentro .bashrc
como
exec 41>/tmp/my_console_log
(el número es arbitrario) y modifique en stderred.c
consecuencia para que el contenido también se escriba en fd 41. Funcionó un poco , pero contiene muchos bytes NUL, formatos extraños y es básicamente información binaria, no legible. Tal vez alguien con buenos conocimientos de C podría probar eso.
Si es así, todo lo necesario para obtener la última línea impresa es tail -n 1 [logfile]
.
Sí, ¿por qué escribir líneas adicionales cada vez que se acuerde? Puede redirigir devuelto a la entrada, pero la salida a la entrada (1> & 0) es no. Además, no querrá escribir una función una y otra vez en cada archivo para la misma.
Si no está exportando los archivos a ninguna parte y tiene la intención de usarlos solo localmente, puede hacer que Terminal configure la declaración de la función. Tiene que agregar la función en el ~/.bashrc
archivo o en el ~/.profile
archivo. En el segundo caso, debe habilitar Run command as login shell
desde Edit>Preferences>yourProfile>Command
.
Haga una función simple, diga:
get_prev()
{
# option 1: create an executable with the command(s) and run it
echo $* > /tmp/exe
bash /tmp/exe > /tmp/out
# option 2: if your command is single command (no-pipe, no semi-colons), still it may not run correct in some exceptions
#echo `$*` > /tmp/out
# return the command(s) outputs line by line
IFS=$(echo -en "\n\b")
arr=()
exec 3</tmp/out
while read -u 3 -r line
do
arr+=($line)
echo $line
done
exec 3<&-
}
En guión principal:
#run your command:
cmd="echo hey ya; echo hey hi; printf `expr 10 + 10`'\n' ; printf $((10 + 20))'\n'"
get_prev $cmd
#or simply
get_prev "echo hey ya; echo hey hi; printf `expr 10 + 10`'\n' ; printf $((10 + 20))'\n'"
Bash guarda la variable incluso fuera del alcance anterior:
#get previous command outputs in arr
for((i=0; i<${#arr[@]}; i++)); do echo ${arr[i]}; done
Uno que he usado por años.
.bashrc
o .bash_profile
)# capture the output of a command so it can be retrieved with ret
cap () { tee /tmp/capture.out}
# return the output of the most recent command that was captured by cap
ret () { cat /tmp/capture.out }
$ find . -name 'filename' | cap
/path/to/filename
$ ret
/path/to/filename
Tiendo a agregar | cap
al final de todos mis comandos. De esta forma, cuando descubro que quiero procesar texto en la salida de un comando de ejecución lenta, siempre puedo recuperarlo res
.
cat -
en cap () { cat - | tee /tmp/capture.out}
esta lista? ¿Tiene cap () { tee /tmp/capture.out }
algún hipo que me falta?
cat - | cat - | cat -
antemano solo para hacerlo más interesante? 😉 Lo arreglaré una vez que lo haya probado para asegurarme de que sea realmente un spandrel
No estoy seguro exactamente para qué necesita esto, por lo que esta respuesta puede no ser relevante. Siempre puede guardar la salida de un comando: netstat >> output.txt
pero no creo que sea lo que está buscando.
Sin embargo, existen opciones de programación; simplemente puede obtener un programa para leer el archivo de texto anterior después de ejecutar ese comando y asociarlo con una variable, y en Ruby, mi idioma de elección, puede crear una variable fuera de la salida del comando usando 'backticks':
output = `ls` #(this is a comment) create variable out of command
if output.include? "Downloads" #if statement to see if command includes 'Downloads' folder
print "there appears to be a folder named downloads in this directory."
else
print "there is no directory called downloads in this file."
end
Pegue esto en un archivo .rb y ejecútelo: ruby file.rb
creará una variable fuera del comando y le permitirá manipularlo.
Tengo una idea que no tengo tiempo para intentar implementar de inmediato.
Pero qué pasa si haces algo como lo siguiente:
$ MY_HISTORY_FILE = `get_temp_filename`
$ MY_HISTORY_FILE=$MY_HISTORY_FILE bash -i 2>&1 | tee $MY_HISTORY_FILE
$ some_command
$ cat $MY_HISTORY_FILE
$ # ^You'll want to filter that down in practice!
Puede haber problemas con el almacenamiento intermedio de E / S. Además, el archivo puede ser demasiado grande. Uno tendría que encontrar una solución a estos problemas.
Creo que usar el comando de script podría ayudar. Algo como,
script -c bash -qf fifo_pid
Uso de las funciones de bash para configurar después del análisis.
Si no desea volver a calcular el comando anterior, puede crear una macro que escanee el búfer de terminal actual, intente adivinar la salida -supuesta- del último comando, la copie en el portapapeles y finalmente la escriba en la terminal.
Se puede usar para comandos simples que devuelven una sola línea de salida (probado en Ubuntu 18.04 con gnome-terminal
).
Instalar las siguientes herramientas: xdootool
, xclip
,ruby
En gnome-terminal
ir a Preferences -> Shortcuts -> Select all
y configurarlo en Ctrl+shift+a
.
Cree el siguiente script de ruby:
cat >${HOME}/parse.rb <<EOF
#!/usr/bin/ruby
stdin = STDIN.read
d = stdin.split(/\n/)
e = d.reverse
f = e.drop_while { |item| item == "" }
g = f.drop_while { |item| item.start_with? "${USER}@" }
h = g[0]
print h
EOF
En la configuración del teclado, agregue el siguiente método abreviado de teclado:
bash -c '/bin/sleep 0.3 ; xdotool key ctrl+shift+a ; xdotool key ctrl+shift+c ; ( (xclip -out | ${HOME}/parse.rb ) > /tmp/clipboard ) ; (cat /tmp/clipboard | xclip -sel clip ) ; xdotool key ctrl+shift+v '
El atajo anterior: