Uma designação de shell é uma única palavra, sem espaço após o sinal de igual. Então, o que você escreveu atribui um valor vazio a thefile
; além disso, como a atribuição é agrupada com um comando, ela transforma thefile
em uma variável de ambiente e a atribuição é local nesse comando específico, ou seja, somente a chamada para ls
vê o valor atribuído.
Você deseja capturar a saída de um comando, portanto, é necessário usar a substituição de comando :
thefile=$(ls -t -U | grep -m 1 "Screen Shot")
(Algumas literaturas mostram uma sintaxe alternativa thefile='ls …'
; a sintaxe backquote é equivalente à sintaxe entre parênteses e dolar, exceto que a citação dentro de backquotes é estranha às vezes, então use apenas $(…)
.)
Outras observações sobre o seu script:
- A combinação de
-t
(classificar por tempo) com-U
(não classificar) não faz sentido; use apenas-t
. -
Em vez de usar
grep
para corresponder a capturas de tela, fica mais claro passar um caractere curinga als
e usarhead
para capturar o primeiro arquivo:thefile=$(ls -t *"Screen Shot"* | head -n 1)
-
Geralmente, é uma má idéia analisar a saída de
ls
. Isso pode falhar bastante se você tiver nomes de arquivos com caracteres não imprimíveis. No entanto, classificar arquivos por data é difícil semls
, portanto, é uma solução aceitável se você souber que não terá caracteres não imprimíveis ou barras invertidas nos nomes de arquivos. -
Sempre use aspas duplas em torno de substituições de variáveis , ou seja, aqui escreva
echo "Most recent screenshot is: $thefile"
Sem aspas duplas, o valor da variável é reexpandido, o que causará problemas se contiver espaços em branco ou outros caracteres especiais.
- Você não precisa de ponto-e-vírgula no final de uma linha. Eles são redundantes, mas inofensivos.
- Em um script de shell, geralmente é uma boa ideia incluir
set -e
. Isso diz ao shell para sair se algum comando falhar (retornando um status diferente de zero).
Se você tiver o GNU find (em particular se estiver executando o Linux ou o Cygwin não embarcado), há outra abordagem para localizar o arquivo mais recente: ter find
listar os arquivos e suas datas e usar sort
e tail
para extrair o arquivo mais novo.
thefile=$(find -maxdepth 1 -type f -name "*Screen Shot*" -printf "%T@ %p" |
sort -k 1n | tail -n 1)
Se você estiver disposto a escrever este script em zsh em vez de bash, há uma maneira muito mais fácil de capturar o arquivo mais recente, porque zsh tem qualificadores de globo que permitem correspondências curinga não apenas em nomes, mas também em metadados de arquivos. A parte (om[1])
após o padrão é os qualificadores glob; om
ordena as correspondências aumentando a idade (ou seja, pelo tempo de modificação, o mais recente primeiro) e [1]
extrai apenas a primeira correspondência. A correspondência inteira precisa estar entre parênteses porque é tecnicamente uma matriz, já que globbing retorna uma lista de arquivos, mesmo que [1]
signifique que, nesse caso específico, a lista contém (no máximo) um arquivo.
#!/bin/zsh
set -e
cd ~/Desktop
thefile=(*"Screen Shot"*(om[1]))
echo "Most recent screenshot is: $thefile"