Puede evitar escribir $(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
En la práctica, la salida de los comandos es determinista, por lo que no me preocuparía que vuelva a calcular. Ciertamente es útil cuando quieres hacer algo como git diff $(!!)donde el comando anterior era una findinvocación.
@ user2065875 aunque los backticks todavía funcionan en Bash, están en desuso a favor $().
kurczynski
87
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.
¿Es posible tener alguna función personalizada de bash 'middleware' que se ejecute antes de cada comando, donde todo lo que hace es guardar la salida resultante en algo que actúa como un portapapeles interno (por ejemplo, BASH_CLIPBOARD)?
Pat Needham
@PatNeedham No estoy seguro. Verifique los módulos cargables. Vea si puede escribir uno.
konsolebox el
11
Una forma de hacerlo es mediante el uso de trap 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.logotra y normalmente. Probablemente hay alguna forma de prevenir este comportamiento también.
Entonces rm -rf * && cd .., cuando escribo , no solo se borrará el directorio actual, sino también el directorio principal. este enfoque me parece muy peligroso
phil294
1
Ahora, ¿cómo deshago esta acción?
Kartik Chauhan
55
@KartikChauhan: Just dotrap '' DEBUG
anubhava
7
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:
en linux $ find app -name 'one.php' | xclip $ diff $(xclip -o) /var/bar/two.php
si-mikey
interesante, nunca pensé en usarlo pbpastejunto con la sustitución de comandos.
Sridhar Sarnobat
¿Qué sucede si hago lo primero y luego me doy cuenta de que era ineficiente? ¿Cómo puedo ahorrar tiempo de cálculo sin volver a ejecutar con la segunda opción?
NelsonGon
4
Inspirado por la respuesta de anubhava, que creo que en realidad no es aceptable, ya que ejecuta cada comando dos veces.
Una desventaja que he encontrado en esto es que ninguno de sus comandos cree que ya se está ejecutando en un tty, lo que significa que necesita atención especial para que los códigos de color funcionen para utilidades como grepo git diff+1 de todos modos
Marty Neal
2
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 .bashrccomo
exec 41>/tmp/my_console_log
(el número es arbitrario) y modifique en stderred.cconsecuencia 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 ~/.bashrcarchivo o en el ~/.profilearchivo. En el segundo caso, debe habilitar Run command as login shelldesde 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<&-}
# 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 }
Uso
$ find .-name 'filename'| cap
/path/to/filename
$ ret
/path/to/filename
Tiendo a agregar | capal 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.
¿Cuál es el punto de cat -en cap () { cat - | tee /tmp/capture.out}esta lista? ¿Tiene cap () { tee /tmp/capture.out }algún hipo que me falta?
Watson
1
@Watson buen punto! No sé por qué tengo eso allí, probablemente hábito. ¿Debo agregar de 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
Connor
0
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.txtpero 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 commandif 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.rbcreará una variable fuera del comando y le permitirá manipularlo.
"No estoy seguro exactamente para qué necesita esto" Bueno, digamos que (con lo que quiero decir que yo ) simplemente ejecuté un script de larga duración, quería buscar la salida y olvidé estúpidamente redirigir la salida antes de ejecutarla. Ahora quiero intentar remediar mi estupidez sin volver a ejecutar el script.
jscs
0
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.
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-terminalir a Preferences -> Shortcuts -> Select ally 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:
Respuestas:
Puede usar
$(!!)
para volver a calcular (no reutilizar) la salida del último comando.El
!!
solo ejecuta el último comando.fuente
$(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 @memecsgit diff $(!!)
donde el comando anterior era unafind
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.
fuente
Una forma de hacerlo es mediante el uso de
trap 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.fuente
rm -rf * && cd ..
, cuando escribo , no solo se borrará el directorio actual, sino también el directorio principal. este enfoque me parece muy peligrosotrap '' 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:
Podrías hacer esto:
La cadena
/var/bar/app/one.php
está en el portapapeles cuando ejecuta el primer comando.Por cierto, pb en
pbcopy
ypbpaste
significa cartón, sinónimo de portapapeles.fuente
$ 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.
De esta manera, la salida del último comando está en / tmp / last y el comando no se llama dos veces.
fuente
grep
ogit diff
+1 de todos modosComo 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(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]
.fuente
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 habilitarRun command as login shell
desdeEdit>Preferences>yourProfile>Command
.Haga una función simple, diga:
En guión principal:
Bash guarda la variable incluso fuera del alcance anterior:
fuente
Solución muy simple
Uno que he usado por años.
Script (agregar a su
.bashrc
o.bash_profile
)Uso
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 recuperarlores
.fuente
cat -
encap () { cat - | tee /tmp/capture.out}
esta lista? ¿Tienecap () { 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 spandrelNo 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':
Pegue esto en un archivo .rb y ejecútelo:
ruby file.rb
creará una variable fuera del comando y le permitirá manipularlo.fuente
Tengo una idea que no tengo tiempo para intentar implementar de inmediato.
Pero qué pasa si haces algo como lo siguiente:
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.
fuente
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.
fuente
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 aPreferences -> Shortcuts -> Select all
y configurarlo enCtrl+shift+a
.Cree el siguiente script de ruby:
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:
fuente