Uma atribuiçã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 torna thefile
uma variável de ambiente e a atribuição é local para esse comando específico, ou seja, apenas a chamada para ls
ver o valor atribuído.
Você deseja capturar a saída de um comando, portanto, você precisa usar a substituição de comando :
thefile=$(ls -t -U | grep -m 1 "Screen Shot")
(Alguma literatura mostra uma sintaxe alternativa thefile=`ls …`
; a sintaxe de aspas é equivalente à sintaxe entre parênteses em dólar, exceto que, por vezes, as aspas dentro de aspas são estranhas, então use $(…)
.)
Outras observações sobre o seu script:
- Combinar
-t
(classificar por tempo) com -U
(não classificar) não faz sentido; apenas use -t
.
Em vez de usar grep
para corresponder às capturas de tela, é mais claro passar um curinga ls
e usar head
para capturar o primeiro arquivo:
thefile=$(ls -t *"Screen Shot"* | head -n 1)
Geralmente, é uma má ideia analisar a saída dels
. Isso pode falhar bastante se você tiver nomes de arquivos com caracteres não imprimíveis. No entanto, é difícil classificar arquivos por data sem ls
, portanto, é uma solução aceitável se você souber que não terá caracteres não imprimíveis ou barras invertidas nos nomes dos arquivos.
Sempre use aspas duplas nas substituições de variáveis , ou seja, escreva aqui
echo "Most recent screenshot is: $thefile"
Sem aspas duplas, o valor da variável é reexpandido, o que causará problemas se contiver espaço 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 informa ao shell para sair se algum comando falhar (retornando um status diferente de zero).
Se você encontrar o GNU (em particular se estiver executando Linux ou Cygwin não incorporado), existe outra abordagem para encontrar o arquivo mais recente: find
listar os arquivos e suas datas, e usar sort
e tail
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ê deseja escrever esse script no zsh, em vez do bash, há uma maneira muito mais fácil de capturar o arquivo mais recente, porque o zsh possui qualificadores globais que permitem correspondências curinga não apenas nos nomes, mas também nos metadados do arquivo. A (om[1])
parte após o padrão são os qualificadores glob; om
classifica as correspondências aumentando a idade (ou seja, pela hora da modificação, a mais nova primeiro) e [1]
extrai apenas a primeira correspondência. A correspondência inteira precisa estar entre parênteses, porque é tecnicamente uma matriz, pois o globbing retorna uma lista de arquivos, mesmo que [1]
isso signifique que, nesse caso específico, a lista contenha (no máximo) um arquivo.
#!/bin/zsh
set -e
cd ~/Desktop
thefile=(*"Screen Shot"*(om[1]))
echo "Most recent screenshot is: $thefile"