if [ ! -f /tmp/foo.txt ]; then echo "File not found!"; else echo "file found"; fi
Objetivo: Verificar a presença de arquivo .tgz de backup contendo a data de hoje; saída 1 para OK, 0 para nenhum arquivo.
Eu sou um otário por um forro :) Por exemplo, em PHP (e bastante semelhante em Javascript), em vários cenários eu gosto de fazer algo como
<?php
echo (date("d")==1)?"Monday":"Not Monday";
?>
Existe sintaxe semelhante no Bash? Eu sei como verificar a presença de um arquivo regular usando -f FILENAME, eu só quero o comando para imprimir 1 ou 0:)
if [ ! -f /tmp/foo.txt ]; then echo "File not found!"; else echo "file found"; fi
Você pode simplesmente fazer isso:
#to check if it's a regular file
[ -f "/you/file.file" ] && echo 1 || echo 0
#to check if a file exist
[ -e "/you/file.file" ] && echo 1 || echo 0
No shell, isso significa [
test -e
se o arquivo existir ]
end of test &&
se o comando retornar true execute o comando depois, ||
se o comando retornar false execute comando after.
Isso deve funcionar em shell
e bash
zsh
: (){echo $#} *"$(date +%Y-%m-%d)"*.tgz(DN)
A saída do número de arquivos no diretório atual cujo nome contém a data atual no formato AAAA-mm-dd e termina em .tgz
como um número decimal. Substitua (DN)
por (DN[1])
se você quiser apenas 0 ou 1.
Para usar como condição em uma instrução if
, você pode fazer:
if ()(($#)) *"$(date +%Y-%m-%d)"*.tgz(DN); then
echo found
else
echo none found
fi
bash
o equivalente poderia ser:
(shopt -s nullglob dotglob; set -- *"$(date +%Y-%m-%d)"*.tgz; echo "$#")
(substitua "$#"
por "$(($#>0))"
para obter 0 ou 1).
e
if (shopt -s nullglob dotglob; set -- *"$(date +%Y-%m-%d)"*.tgz; (($#))); then
echo found
else
echo none found
fi
ksh93
: (FIGNORE='@(.|..)'; set -- ~(N)*"$(date +%Y-%m-%d)"*.tgz; echo "$#")
e
if (FIGNORE='@(.|..)'; set -- ~(N)*"$(date +%Y-%m-%d)"*.tgz; (("$#"))); then...
ls -qA | grep -c "$(date +%Y-%m-%d).*\.tgz$"
para a contagem.
ls -qA | grep -q "$(date +%Y-%m-%d).*\.tgz$"; echo "$(($? == 0))"
para 0 ou 1 e:
E:
if ls -qA | grep -q "$(date +%Y-%m-%d).*\.tgz$"; then...
Embora a sabedoria comum não seja analisar a saída de ls
, aqui com -q
, estamos nos certificando de que há um arquivo por linha e a substituição de caracteres não imprimíveis por ?
não deve afetar o grep
ing para o nosso padrão por isso deve ser relativamente seguro.
Você poderá ver diferenças se os nomes dos arquivos contiverem sequências de bytes que não formam caracteres válidos. Uma vantagem é que você receberá uma mensagem de erro se o diretório atual não for legível.
Você pode usar este comando:
test -e *$(date).tgz && echo 1 || echo 0
Como mais uma variante, se você soubesse o formato exato do nome do arquivo que procurava, poderia usar
[ ! -f FILENAME ]; echo $?
ou
echo '[ ! -f FILENAME ]' $?
no entanto, isso não poderia lidar com curingas, então os arquivos terminados em .tgz contendo a data de hoje precisariam de algo mais complexo, como
echo $( for entry in *$(date --rfc-3339=date)*.tgz; do [ -f "$entry" ] && exit 1; done; exit 0 ) $?
Eu sei que você pediu pelo Bash, mas se você está procurando por qualquer programa de linha de comando que funcione, eu recomendo o Python:
python -c "import os; exists = os.path.isfile('myFile.txt'); print(int(exists))"
ls filename 2> /dev/null && echo 1 || echo 0
Ou, se você quiser em uma variável
EXISTS=$(ls filename 2> /dev/null && echo 1 || echo 0)