Quiero asignar el resultado de una expresión
(es decir, la salida de un comando)
a una variable y luego manipularla; por ejemplo,
concatenarla con una cadena y luego repetirla .
Esto es lo que tengo:
#!/bin/bash
cd ~/Desktop;
thefile= ls -t -U | grep -m 1 "Screen Shot";
echo "Most recent screenshot is: "$thefile;
Pero eso da como resultado:
Screen Shot 2011-07-03 at 1.55.43 PM.png
Most recent screenshot is:
Entonces, parece que eso no se está asignando a $thefile
, y se imprime a medida que se ejecuta.
¿Qué me estoy perdiendo?
Respuesta aceptada:
Una asignación de shell es una sola palabra, sin espacio después del signo igual. Entonces, lo que escribiste asigna un valor vacío a thefile
; además, dado que la asignación se agrupa con un comando, hace que thefile
una variable de entorno y la asignación es local para ese comando en particular, es decir, solo la llamada a ls
ve el valor asignado.
Desea capturar la salida de un comando, por lo que debe usar la sustitución de comandos:
thefile=$(ls -t -U | grep -m 1 "Screen Shot")
(Alguna literatura muestra una sintaxis alternativa thefile=`ls …`
; la sintaxis de comillas inversas es equivalente a la sintaxis de paréntesis de dólar, excepto que citar entre comillas inversas a veces es extraño, así que solo use $(…)
.)
Otros comentarios sobre su guión:
-
Combinando
-t
(ordenar por tiempo) con-U
(no ordenar con GNUls
) no tiene sentido; solo usa-t
. -
En lugar de usar
grep
para hacer coincidir las capturas de pantalla, es más claro pasar un comodín als
y usahead
para capturar el primer archivo:thefile=$(ls -td -- *"Screen Shot"* | head -n 1)
-
Generalmente es una mala idea analizar la salida de
ls
. Esto podría fallar bastante si tiene nombres de archivo con caracteres no imprimibles. Sin embargo, ordenar archivos por fecha es difícil sinls
, por lo que es una solución aceptable si sabe que no tendrá caracteres no imprimibles ni barras invertidas en los nombres de los archivos. -
Use siempre comillas dobles alrededor de las sustituciones de variables , es decir, aquí escribe
echo "Most recent screenshot is: $thefile"
Sin comillas dobles, el valor de la variable se vuelve a expandir, lo que causará problemas si contiene espacios en blanco u otros caracteres especiales.
-
No necesita punto y coma al final de una línea. Son redundantes pero inofensivos.
-
En un script de shell, a menudo es una buena idea incluir
set -e
. Esto le dice al shell que salga si algún comando falla (devolviendo un estado distinto de cero).
Si tiene GNU find
y sort
(en particular, si está ejecutando Cygwin o Linux no integrado), hay otro enfoque para encontrar el archivo más reciente:tenga find
liste los archivos y sus fechas, y use sort
y read
(aquí asumiendo bash
o zsh
para -d ''
para leer un registro delimitado por NUL) para extraer el archivo más reciente.
IFS=/ read -rd '' ignoró el archivo <<( find -max depth 1 -type f -name "*Screen Shot*" -printf "%[email protected]/%p