Usei o seguinte script para verificar se existe um arquivo:
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File $FILE exists."
else
echo "File $FILE does not exist."
fi
Qual é a sintaxe correta a ser usada se eu quiser apenas verificar se o arquivo não existe?
#!/bin/bash
FILE=$1
if [ $FILE does not exist ]; then
echo "File $FILE does not exist."
fi
if [ -f $FILE ]; then; else; echo "File $FILE does not exist."; fi;
Provavelmente bom que eu encontrei essa pergunta e aprendi a fazê-la de uma maneira mais adequada. :)-e
. -f não vai pegar diretórios, links simbólicos, etc.FILE=$1
->FILE="$1"
eif [ -f $FILE ];
->if [ -f "$FILE" ];
Respostas:
O comando test (
[
aqui) possui um operador lógico "não", que é o ponto de exclamação (semelhante a muitos outros idiomas). Tente o seguinte:fonte
if [ ! \( -f "f1" -a -f "f2" \) ] ; then echo MISSING; fi
if [ ! -f "f1" ] || [ ! -f "f2" ] ; then echo MISSING; fi
[ -f /tmp/foo.txt ] || echo "File not found!"
-e: Returns true value, if file exists
-f: Return true value, if file exists and regular file
-r: Return true value, if file exists and is readable
-w: Return true value, if file exists and is writable
-x: Return true value, if file exists and is executable
-d: Return true value, if exists and is a directory
! -f
com&&
versus usando-f
com||
. Isso tem a ver com o código de saída retornado pela verificação de inexistência. Se você precisa que sua linha sempre saia limpa com o código de saída 0 (e às vezes você não deseja essa restrição), as duas abordagens não são intercambiáveis. Como alternativa, basta usar umaif
instrução e você não precisa mais se preocupar com o código de saída da sua verificação de não existência.Teste de arquivo bash
-b filename
- Bloquear arquivo especial-c filename
- Arquivo de caractere especial-d directoryname
- Verificar a existência do diretório-e filename
- Verificar a existência do arquivo, independentemente do tipo (nó, diretório, soquete etc.)-f filename
- Verificar a existência regular do arquivo e não um diretório-G filename
- Verificar se o arquivo existe e é de propriedade de ID do grupo efetivo-G filename set-group-id
- Verdadeiro se o arquivo existir e estiver definido como id do grupo-k filename
- Bit fixo-L filename
- Link simbólico-O filename
- Verdadeiro se o arquivo existir e pertencer ao ID do usuário efetivo-r filename
- Verifique se o arquivo é legível-S filename
- Verifique se o arquivo é soquete-s filename
- Verifique se arquivo com tamanho diferente de zero-u filename
- Verifique se o bit do conjunto de IDs de usuário está definido-w filename
- Verifique se o arquivo é gravável-x filename
- Verifique se o arquivo é executávelComo usar:
Uma expressão de teste pode ser negada usando o
!
operadorfonte
-n String
- Verifique se o comprimento da string não é zero. Ou você quer dizerfile1 -nt file2
- Verifique se o arquivo1 é mais recente, em seguida, apresentar 2 (você também pode usar -ot para idosos seguida)The unary operator -z tests for a null string, while -n or no operator at all returns True if a string is not empty.
~ ibm.com/developerworks/library/l-bash-test/index.htmlVocê pode negar uma expressão com "!":
A página de manual relevante é
man test
ou, equivalentemente,man [
- ouhelp test
ouhelp [
para o comando bash interno.fonte
[
é um builtin. Portanto, as informações relevantes são obtidas porhelp [
... mas isso mostra que[
é um sinônimo para otest
builtin; portanto, as informações relevantes são obtidas porhelp test
. Consulte também a seção Expressão condicional do bash no manual .[
comando interno do bash se comporta de maneira muito semelhante ao[
comando externo , portanto,man test
ouman [
fornecerá uma boa idéia de como ele funciona.[
possui mais opções do que o comando externo[
encontrado no meu sistema ... De um modo geral, acredito que é melhor ler a documentação específica de uma determinada ferramenta, e não a documentação específica de outra vagamente relacionada. Eu posso estar errado, embora;)
Além disso, é possível que o arquivo seja um link simbólico quebrado ou um arquivo não regular, como, por exemplo, um soquete, dispositivo ou fifo. Por exemplo, para adicionar uma verificação de links simbólicos quebrados:
fonte
Vale ressaltar que, se você precisar executar um único comando, poderá abreviar
para
ou
fonte
Prefiro fazer o seguinte one-liner, no formato compatível com shell POSIX :
Para alguns comandos, como eu faria em um script:
Depois que comecei a fazer isso, raramente uso mais a sintaxe totalmente digitada !!
fonte
[
outest
embutido testaria a existência de arquivo do argumento por padrão (em oposição a-e
)? Isso não seria ambíguo? AFAIK (e AIUI a seção "EXPRESSÕES CONDICIONAIS"), a única coisa testada com sua abordagem é que o argumento não está vazio (ou indefinido), que é, nesse caso, uma tautologia (deixe$DIR = ''
e$FILE = ''
, então o argumento ainda está'//'
)ls /foo
resultadols: cannot access /foo: No such file or directory
.[ /foo ] && echo 42
, resultado42
. Lançamento do GNU bash, versão 4.2.37 (1) (i486-pc-linux-gnu).-f
opção, no momento em que escrevi esta resposta. Obviamente, você sempre pode usar-e
, se não tiver certeza, será um arquivo comum. Além disso, em todos os meus scripts, cito essas construções, devo ter acabado de submetê-las sem provas adequadas.[ $condition ] && if_true || if_false
é propenso a erros. De qualquer forma, acho[ ! -f "$file" ] && if_not_exists
mais fácil ler e entender do que[ -f "$file" ] || if_not_exists
.Para testar a existência do arquivo, o parâmetro pode ser qualquer um dos seguintes:
Todos os testes abaixo se aplicam a arquivos, diretórios e links simbólicos regulares:
Script de exemplo:
fonte
Você consegue fazer isso:
ou
Se você deseja procurar arquivos e pastas, use a
-e
opção em vez de-f
.-e
retorna true para arquivos regulares, diretórios, soquete, arquivos especiais de caracteres, bloquear arquivos especiais etc.fonte
[
Porém, ele tem uma vantagem limitada sobre o utilitário padrão .-f
) e diretórios são apenas dois dos muitos tipos diferentes de arquivos . Também existem soquetes, links simbólicos, dispositivos, fifos, portas ...[ -e
testará a existência de arquivos (de qualquer tipo, incluindo diretório regular, fifo, ...) após a resolução do link simbólico .-e
, ele precisa-f
.Você deve ter cuidado ao executar
test
uma variável não citada, pois ela pode produzir resultados inesperados:A recomendação é geralmente ter a variável testada entre aspas duplas:
fonte
[ ... ]
.Existem três maneiras distintas de fazer isso:
Negue o status de saída com bash (nenhuma outra resposta disse isso):
Ou:
Negue o teste dentro do comando test
[
(essa é a maneira que a maioria das respostas apresentou anteriormente):Ou:
Aja com o resultado negativo do teste (em
||
vez de&&
):Somente:
Isso parece bobo (IMO), não o use, a menos que seu código precise ser portátil para o shell Bourne (como o
/bin/sh
Solaris 10 ou anterior) que não possui o operador de negação de pipeline (!
):fonte
! [
e[ !
?! [
POSIX é para pipelines shell 2.9.2 (qualquer comando)Otherwise, the exit status shall be the logical NOT of the exit status of the last command
e[ !
é POSIX para teste.! expression True if expression is false. False if expression is true.
Portanto, ambos são POSIX e, na minha experiência, ambos são amplamente suportados.!
palavra - chave que foi introduzida pelo shell Korn. Exceto, talvez, pelo Solaris 10 e mais antigo, é improvável que você encontre um shell Bourne atualmente.No
o
[
comando faz umastat()
(nãolstat()
) chamada do sistema no caminho armazenado$file
e retorna true se a chamada do sistema for bem-sucedida e o tipo de arquivo retornado porstat()
" regular ".Portanto, se
[ -f "$file" ]
retorna true, você pode dizer que o arquivo existe e é um arquivo regular ou um link simbólico que eventualmente está sendo resolvido para um arquivo regular (ou pelo menos era no momento dostat()
).No entanto, se retornar falso (ou se
[ ! -f "$file" ]
ou! [ -f "$file" ]
retornar verdadeiro), há muitas possibilidades diferentes:stat()
chamada do sistema possa falhar.Em suma, deve ser:
Para ter certeza de que o arquivo não existe, precisaríamos que a
stat()
chamada do sistema retornasse com um código de erro deENOENT
(ENOTDIR
nos diz que um dos componentes do caminho não é um diretório, outro caso em que podemos dizer que o arquivo não existe) existir por esse caminho). Infelizmente, o[
comando não nos informa disso. Ele retornará false se o código de erro é ENOENT, EACCESS (permissão negada), ENAMETOOLONG ou qualquer outra coisa.O
[ -e "$file" ]
teste também pode ser feito comls -Ld -- "$file" > /dev/null
. Nesse caso,ls
informará o motivo dastat()
falha, embora as informações não possam ser facilmente usadas programaticamente:Pelo menos
ls
me diz que não é porque o arquivo não existe que falha. É porque ele não pode dizer se o arquivo existe ou não. O[
comando apenas ignorou o problema.Com o
zsh
shell, você pode consultar o código de erro com a$ERRNO
variável especial após o[
comando com falha e decodificar esse número usando a$errnos
matriz especial nozsh/system
módulo:(cuidado, o
$errnos
suporte foi quebrado com algumas versões dezsh
quando construído com versões recentes dogcc
).fonte
Para reverter um teste, use "!". Isso é equivalente ao operador lógico "não" em outros idiomas. Tente o seguinte:
Ou escrito de uma maneira um pouco diferente:
Ou você pode usar:
Ou, apresentando todos juntos:
Que pode ser escrito (usando o operador "and": &&) como:
Que parece mais curto assim:
fonte
A
test
coisa pode contar também. Funcionou para mim (com base no Bash Shell: verificar se o arquivo existe ou não ):fonte
Este código também está funcionando.
fonte
A maneira mais simples
fonte
Esse script de shell também funciona para encontrar um arquivo em um diretório:
fonte
read -p "Enter file name: " -r a
para solicitar e ler. Ele usa aspas em torno da variável; isso é bom, mas deve ser explicado. Seria melhor se ecoasse o nome do arquivo. E isso verifica se o arquivo existe e não está vazio (esse é o significado de-s
), enquanto a pergunta pergunta sobre qualquer arquivo, vazio ou não (para o que-f
é mais apropriado).às vezes pode ser útil usar && e || operadores.
Como em (se você tiver o comando "test"):
ou
fonte
Se você deseja usar em
test
vez de[]
, pode usar!
para obter a negação:fonte
Você também pode agrupar vários comandos em uma linha
[ -f "filename" ] || ( echo test1 && echo test2 && echo test3 )
ou
[ -f "filename" ] || { echo test1 && echo test2 && echo test3 ;}
Se o nome do arquivo não sair, a saída será
Nota: (...) é executado em um subshell, {...;} é executado no mesmo shell.
A notação de colchete funciona somente no bash.fonte
fonte