Voglio assegnare il risultato di un'espressione
(ovvero l'output di un comando)
a una variabile e quindi manipolarla, ad esempio
concatenarla con una stringa, quindi riecheggiarla .
Ecco cosa ho:
#!/bin/bash
cd ~/Desktop;
thefile= ls -t -U | grep -m 1 "Screen Shot";
echo "Most recent screenshot is: "$thefile;
Ma questo produce:
Screen Shot 2011-07-03 at 1.55.43 PM.png
Most recent screenshot is:
Quindi, sembra che non venga assegnato a $thefile
, e viene stampato durante l'esecuzione.
Cosa mi sto perdendo?
Risposta accettata:
Un'assegnazione di shell è una singola parola, senza spazio dopo il segno di uguale. Quindi quello che hai scritto assegna un valore vuoto a thefile
; inoltre, poiché l'assegnazione è raggruppata con un comando, crea thefile
una variabile di ambiente e l'assegnazione è locale a quel particolare comando, cioè solo la chiamata a ls
vede il valore assegnato.
Vuoi acquisire l'output di un comando, quindi devi utilizzare la sostituzione del comando:
thefile=$(ls -t -U | grep -m 1 "Screen Shot")
(Alcuni documenti mostrano una sintassi alternativa thefile=`ls …`
; la sintassi delle virgolette è equivalente alla sintassi dollaro-parentesi tranne per il fatto che le virgolette all'interno delle virgolette a volte sono strane, quindi usa semplicemente $(…)
.)
Altre osservazioni sul tuo script:
-
Combinando
-t
(ordina per ora) con-U
(non ordinare con GNUls
) non ha senso; usa semplicemente-t
. -
Invece di usare
grep
per abbinare gli screenshot, è più chiaro passare un carattere jolly als
e usahead
per acquisire il primo file:thefile=$(ls -td -- *"Screen Shot"* | head -n 1)
-
In genere è una cattiva idea analizzare l'output di
ls
. Questo potrebbe fallire abbastanza gravemente se hai nomi di file con caratteri non stampabili. Tuttavia, l'ordinamento dei file per data è difficile senzals
, quindi è una soluzione accettabile se sai che non avrai caratteri non stampabili o barre rovesciate nei nomi dei file. -
Utilizza sempre le doppie virgolette per le sostituzioni di variabili , cioè qui scrivi
echo "Most recent screenshot is: $thefile"
Senza virgolette, il valore della variabile viene riespanso, il che causerà problemi se contiene spazi bianchi o altri caratteri speciali.
-
Non hai bisogno del punto e virgola alla fine di una riga. Sono ridondanti ma innocui.
-
In uno script di shell, è spesso una buona idea includere
set -e
. Questo dice alla shell di uscire se un comando fallisce (restituendo uno stato diverso da zero).
Se hai GNU find
e sort
(in particolare se stai utilizzando Linux o Cygwin non embedded), c'è un altro approccio per trovare il file più recente:have find
elenca i file e le loro date e usa sort
e read
(qui assumendo bash
o zsh
per -d ''
per leggere un record delimitato da NUL) per estrarre il file più recente.
IFS=/ read -rd '' ha ignorato il file <<( find -maxdepth 1 -type f -name "*Screen Shot*" -printf "%[email protected]/%p