Me gustaría poder usar el resultado del último comando ejecutado en un comando posterior. Por ejemplo,
$ find . -name foo.txt
./home/user/some/directory/foo.txt
Ahora digamos que quiero poder abrir el archivo en un editor, o eliminarlo, o hacer algo más con él, por ejemplo
mv <some-variable-that-contains-the-result> /some/new/location
¿Cómo puedo hacerlo? Tal vez usando alguna variable bash?
Actualizar:
Para aclarar, no quiero asignar cosas manualmente. Lo que busco es algo así como variables de bash incorporadas, por ejemplo
ls /tmp
cd $_
$_
contiene el último argumento del comando anterior. Quiero algo similar, pero con la salida del último comando.
Actualización final:
La respuesta de Seth ha funcionado bastante bien. Un par de cosas a tener en cuenta:
- no olvides
touch /tmp/x
probar la solución por primera vez - el resultado solo se almacenará si el código de salida del último comando fue exitoso
linux
bash
command-line
Armandino
fuente
fuente
Respuestas:
Esta es una solución realmente hacky, pero parece funcionar en su mayor parte del tiempo. Durante las pruebas, noté que a veces no funcionaba muy bien al obtener un ^Cen la línea de comando, aunque lo modifiqué un poco para que se comportara un poco mejor.
Este truco es solo un modo interactivo, y estoy bastante seguro de que no se lo recomendaría a nadie. Es probable que los comandos en segundo plano causen un comportamiento aún menos definido de lo normal. Las otras respuestas son una mejor manera de obtener resultados mediante programación.
Dicho esto, aquí está la "solución":
Establezca esta variable de entorno bash y emita comandos como desee.
$LAST
generalmente tendrá el resultado que está buscando:fuente
PROMPT_COMMAND='last="$(cat /tmp/last)";lasterr="$(cat /tmp/lasterr)"; exec >/dev/tty; exec > >(tee /tmp/last); exec 2>/dev/tty; exec 2> >(tee /tmp/lasterr)'
que proporciona ambos$last
y$lasterr
.No such file or directory
2> >(tee /tmp/lasterr 1>&2)
porque la salida estándar detee
debe ser redirigida nuevamente al error estándar.No conozco ninguna variable que haga esto automáticamente . Para hacer algo aparte de simplemente copiar y pegar el resultado, puede volver a ejecutar lo que acaba de hacer, por ejemplo
¿Dónde
!!
está la expansión de la historia que significa 'el comando anterior'?Si espera que haya un solo nombre de archivo con espacios u otros caracteres que puedan evitar el análisis adecuado de los argumentos, cite el resultado (
vim "$(!!)"
). Dejarlo sin comillas permitirá que se abran varios archivos a la vez, siempre que no incluyan espacios u otros tokens de análisis de shell.fuente
vim `!!`
date "+%N"
y luegoecho $(!!)
Bash es una especie de lenguaje feo. Sí, puedes asignar la salida a la variable
Pero es mejor que espere lo más difícil quefind
solo haya devuelto un resultado y que ese resultado no tuviera ningún carácter "extraño", como retornos de carro o saltos de línea, ya que se modificarán en silencio cuando se asignen a una variable Bash.¡Pero mejor tenga cuidado de citar su variable correctamente cuando la use!
Es mejor actuar directamente sobre el archivo, por ejemplo, con
find
's-execdir
(consulte el manual).o
fuente
echo "${MY_VAR}"
para ver que este es el caso.Hay más de una forma de hacer esto. Una forma es usar
v=$(command)
cuál asignará la salida del comando av
. Por ejemplo:Y también puedes usar comillas inversas.
De Bash Beginners Guide ,
EDITAR: después de la edición en la pregunta, parece que esto no es lo que el OP está buscando. Hasta donde yo sé, no hay una variable especial como
$_
la salida del último comando.fuente
Es bastante fácil Use comillas inversas:
Y luego puedes usar eso en cualquier momento en el futuro
fuente
Descargos de responsabilidad:
Al ejecutar un shell interactivo en tmux, puede acceder fácilmente a los datos que se muestran actualmente en un terminal. Echemos un vistazo a algunos comandos interesantes:
Sí, esto nos da muchas posibilidades ahora :) En cuanto a mí, configuré un alias simple:
alias L="tmux capture-pane; tmux showb -b 0 | tail -n 3 | head -n 1"
y ahora cada vez que necesito acceder a la última línea simplemente uso$(L)
para obtenerla.Esto es independiente de la secuencia de salida que utiliza el programa (ya sea stdin o stderr), el método de impresión (ncurses, etc.) y el código de salida del programa; los datos solo deben mostrarse.
fuente
Creo que es posible que pueda hackear una solución que implica configurar su shell en un script que contenga:
Luego, si configura la
$PROMPT_COMMAND
salida de un delimitador, puede escribir una función auxiliar (tal vez llamada_
) que le permita obtener el último fragmento de ese registro, para que pueda usarlo como:fuente
Puede configurar el siguiente alias en su perfil de bash:
Luego, al escribir 's' después de un comando arbitrario, puede guardar el resultado en una variable de shell 'it'.
Entonces, el uso de ejemplo sería:
fuente
grab
función que copia la enésima línea del último comando al portapapeles gist.github.com/davidhq/f37ac87bc77f27c5027eAcabo de destilar esta
bash
función de las sugerencias aquí:Entonces, solo haces:
Actualización : un usuario anónimo sugirió reemplazar
echo
por elprintf '%s\n'
cual tiene la ventaja de que no procesa opciones como-e
en el texto capturado. Entonces, si espera o experimenta tales peculiaridades, considere esta sugerencia. Otra opción es usarcat <<<$grab
en su lugar.fuente
cat <<<$grab
opción?man bash
: "Aquí cadenas: una variante de los documentos aquí, el formato es:<<<word
la palabra se expande y se suministra al comando en su entrada estándar". Por lo tanto, el valor de$grab
se alimenta acat
stdin, ycat
solo lo retroalimenta a stdout.Al decir "Me gustaría poder usar el resultado del último comando ejecutado en un comando posterior", supongo que se refiere al resultado de cualquier comando, no solo a encontrar.
Si ese es el caso, xargs es lo que estás buscando.
find . -name foo.txt -print0 | xargs -0 -I{} mv {} /some/new/location/{}
O si está interesado en ver primero la salida:
find . -name foo.txt -print0
!! | xargs -0 -I{} mv {} /some/new/location/{}
Este comando trata con múltiples archivos y funciona como un encanto, incluso si la ruta y / o el nombre del archivo contienen espacios.
Observe la parte mv {} / some / new / location / {} del comando. Este comando se crea y ejecuta para cada línea impresa por el comando anterior. Aquí la línea impresa por el comando anterior se reemplaza en lugar de {} .
Extracto de la página de manual de xargs:
Para más detalles vea la página del manual:
man xargs
fuente
Capture la salida con backticks:
fuente
Usualmente hago lo que los otros aquí han sugerido ... sin la tarea
Puedes ponerte más elegante si quieres:
fuente
Si todo lo que desea es volver a ejecutar su último comando y obtener la salida, una variable bash simple funcionaría:
Entonces puede ejecutar su comando en la salida con:
Esto generará un nuevo proceso y volverá a ejecutar su comando, luego le dará la salida. Parece que lo que realmente le gustaría sería un archivo de historial de bash para la salida del comando. Esto significa que necesitará capturar la salida que bash envía a su terminal. Podría escribir algo para ver el / dev o / proc necesario, pero eso es desordenado. También podría crear una "tubería especial" entre su término y bash con un comando tee en el medio que redirige a su archivo de salida.
Pero ambas son soluciones extravagantes. Creo que lo mejor sería Terminator, que es un terminal más moderno con registro de salida. Simplemente revise su archivo de registro para ver los resultados del último comando. Una variable bash similar a la anterior lo haría aún más simple.
fuente
Aquí hay una forma de hacerlo después de que haya ejecutado su comando y haya decidido que desea almacenar el resultado en una variable:
O si sabe de antemano que deseará obtener el resultado en una variable, puede usar los backticks:
fuente
Como alternativa a las respuestas existentes: utilícelo
while
si los nombres de sus archivos pueden contener espacios en blanco como este:Como escribí, la diferencia solo es relevante si tiene que esperar espacios en blanco en los nombres de archivo.
NB: el único elemento integrado no se trata del resultado, sino del estado del último comando.
fuente
puedes usar !!: 1. Ejemplo:
fuente
Tenía una necesidad similar, en la que quería usar la salida del último comando en el siguiente. Muy parecido a un | (tubo). p.ej
a algo como
Solución: creó esta tubería personalizada. Muy simple, usando xargs -
Básicamente nada al crear una mano corta para xargs, funciona de maravilla y es realmente útil. Solo agrego el alias en el archivo .bash_profile.
fuente
Se puede hacer usando la magia de los descriptores de archivos y la
lastpipe
opción de shell.Tiene que hacerse con un script: la opción "lastpipe" no funcionará en modo interactivo.
Aquí está la secuencia de comandos que he probado con:
Lo que estoy haciendo aquí es:
configurando la opción de shell
shopt -s lastpipe
. No funcionará sin esto, ya que perderá el descriptor de archivo.asegurándome de que mi stderr también sea capturado con
2>&1
canalizar la salida a una función para que se pueda hacer referencia al descriptor de archivo stdin.
configurando la variable obteniendo el contenido del
/proc/self/fd/0
descriptor de archivo, que es stdin.Estoy usando esto para capturar errores en un script, por lo que si hay un problema con un comando, puedo dejar de procesar el script y salir de inmediato.
De esta manera, puedo agregar
2>&1 | exit_tests ; [[ "${PIPESTATUS[0]}" == "0" ]] || error_msg
detrás de cada comando que me interesa verificar.¡Ahora puedes disfrutar de tu salida!
fuente
Esta no es estrictamente una solución bash, pero puede usar tuberías con sed para obtener la última fila de salida de comandos anteriores.
Primero veamos lo que tengo en la carpeta "a"
Entonces, su ejemplo con ls y cd se convertiría en sed y tubería en algo como esto:
Por lo tanto, la magia real ocurre con sed, canaliza cualquier salida de lo que se ordena en sed y sed imprime la última fila que puede usar como parámetro con ticks de retroceso. O puedes combinar eso con xargs también. ("man xargs" en shell es tu amigo)
fuente
El shell no tiene símbolos especiales similares a Perl que almacenan el resultado de eco del último comando.
Aprende a usar el símbolo de tubería con awk.
En el ejemplo anterior, podrías hacer:
fuente
es otra forma, aunque sucia.
fuente
Me resulta molesto recordar que canalizar la salida de mis comandos en un archivo específico es un poco molesto, mi solución es una función en mi
.bash_profile
que captura la salida en un archivo y devuelve el resultado cuando lo necesita.La ventaja de este es que no tiene que volver a ejecutar todo el comando (al usar
find
u otros comandos de ejecución prolongada que pueden ser críticos)Bastante simple, pegue esto en su
.bash_profile
:Guión
Uso
En este punto, tiendo a agregar
| catch
al final de todos mis comandos, porque no tiene costo hacerlo y me ahorra tener que volver a ejecutar comandos que tardan mucho tiempo en finalizar.Además, si desea abrir la salida del archivo en un editor de texto, puede hacer esto:
fuente