Pergunta

Qual comando pode ser usado para verificar se um diretório existe ou não, dentro de um shell script?

Foi útil?

Solução

Para verificar se existe um diretório em um script de shell, você pode usar o seguinte:

if [ -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY exists.
fi

Ou para verificar se um diretório não existe:

if [ ! -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY doesn't exist.
fi

No entanto, como Jon Ericson aponta, os comandos subsequentes podem não funcionar conforme o esperado se você não levar em conta que um link simbólico para um diretório também passará nesta verificação.Por exemplo.executando isso:

ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then 
  rmdir "$SYMLINK" 
fi

Produzirá a mensagem de erro:

rmdir: failed to remove `symlink': Not a directory

Portanto, os links simbólicos podem ter que ser tratados de forma diferente, se os comandos subsequentes esperarem diretórios:

if [ -d "$LINK_OR_DIR" ]; then 
  if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here.
    rm "$LINK_OR_DIR"
  else
    # It's a directory!
    # Directory command goes here.
    rmdir "$LINK_OR_DIR"
  fi
fi

Preste atenção especial às aspas duplas usadas para agrupar as variáveis, a razão para isso é explicada por 8jean em outra resposta.

Se as variáveis ​​contiverem espaços ou outros caracteres incomuns, provavelmente causará falha no script.

Outras dicas

Lembre-se de sempre envolver variáveis entre aspas duplas ao referenciá-las um script bash.As crianças hoje em dia crescem com a ideia de que podem ter espaços e muitos outros personagens engraçados em seus nomes de diretórios.(Espaços!Na minha época, não tínhamos espaços chiques!;))

Um dia, uma daquelas crianças executará seu script com $DIRECTORY definido como "My M0viez" e seu script explodirá.Você não quer isso.Então use isso.

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi

Note o -d teste pode produzir alguns resultados surpreendentes:

$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory

Arquivo em:"Quando um diretório não é um diretório?" A resposta:"Quando é um link simbólico para um diretório." Um teste um pouco mais completo:

if [ -d t ]; then 
   if [ -L t ]; then 
      rm t
   else 
      rmdir t
   fi
fi

Você pode encontrar mais informações no manual do Bash em Expressões condicionais Bash e a [ comando interno e a [[ comando composto.

eu acho o colchete duplo versão de test torna a escrita de testes lógicos mais natural:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi

Forma mais curta:

[ -d "$DIR" ] && echo "Yes"

Para verificar se existe um diretório, você pode usar uma estrutura if simples como esta:

if [ -d directory/path to a directory ] ; then
#Things to do

else #if needed #also: elif [new condition] 
# things to do
fi

Você também pode fazer isso em negativo

if [ ! -d directory/path to a directory ] ; then
# things to do when not an existing directory

Observação:Tenha cuidado, deixe espaços vazios em ambos os lados dos colchetes de abertura e fechamento.

Com a mesma sintaxe você pode usar:

-e: any kind of archive 

-f: file 

-h: symbolic link 

-r: readable file 

-w: writable file 

-x: executable file 

-s: file size greater than zero 
if [ -d "$DIRECTORY" ]; then  
    # Here if $DIRECTORY exists  
fi

Você pode usar test -d (ver man test).

-d file Verdadeiro se o arquivo existir e for um diretório.

Por exemplo:

test -d "/etc" && echo Exists || echo Does not exist

Observação:O test comando é igual à expressão condicional [ (ver: man [), portanto, é portátil entre scripts de shell.

[ - Este é sinônimo de test embutido, mas o último argumento deve ser literal ], para combinar com a abertura [.

Para opções possíveis ou mais ajuda, verifique:

  • help [
  • help test
  • man test ou man [
  1. Um script simples para testar se o diretório ou arquivo está presente ou não:

    if [ -d /home/ram/dir ]   # for file "if [-f /home/rama/file]" 
    then 
        echo "dir present"
    else
        echo "dir not present"
    fi
    
  2. Um script simples para verificar se o diretório está presente ou não:

    mkdir tempdir   # if you want to check file use touch instead of mkdir
    ret=$?
    if [ "$ret" == "0" ]
    then
        echo "dir present"
    else
        echo "dir not present"
    fi
    

    Os scripts acima irão verificar se o diretório está presente ou não

    $? se o último comando for bem-sucedido, ele retornará "0", caso contrário, um valor diferente de zero.suponha tempdir já está presente então mkdir tempdir dará erro como abaixo:

    mkdir:não é possível criar o diretório ‘tempdir’:o arquivo existe

Ou para algo completamente inútil:

[ -d . ] || echo "No"

Aqui está uma expressão muito pragmática:

(cd $dir) || return # is this a directory,
                    # and do we have access?

Normalmente eu envolvo isso em uma função:

can_use_as_dir() { 
    (cd ${1:?pathname expected}) || return
}

Ou:

assert_dir_access() { 
    (cd ${1:?pathname expected}) || exit
}

O bom dessa abordagem é que não preciso pensar em uma boa mensagem de erro.

cd já me dará uma mensagem padrão de uma linha para stderr.Também fornecerá mais informações do que poderei fornecer.Ao realizar o cd dentro de um subshell ( ... ), o comando não afetará o diretório atual do chamador.Se o diretório existir, esse subshell e a função serão apenas autônomos.

A seguir está o argumento que passamos para cd: ${1:?pathname expected}.Esta é uma forma mais elaborada de substituição de parâmetros que é explicada com mais detalhes abaixo.

dr:Se a string passada para esta função estiver vazia, saímos novamente do subshell ( ... ) e retorne da função com a mensagem de erro fornecida.


Citando do ksh93 página de manual:

${parameter:?word}

Se parameter está definido e não é nulo, substitua seu valor;caso contrário, imprima word e saia do shell (se não for interativo).Se word é omitido, então uma mensagem padrão é impressa.

e

Se o cólon : é omitido das expressões acima, em seguida, o O shell verifica apenas se o parâmetro está definido ou não.

A frase aqui é peculiar à documentação do shell, como word pode referir-se para qualquer cadeia de caracteres razoável, incluindo espaço em branco.

Neste caso específico, sei que a mensagem de erro padrão 1: parameter not set não é suficiente, por isso amplio o tipo de valor que esperamos aqui - o pathname de um diretório.

Uma nota filosófica:O shell não é uma linguagem orientada a objetos, então a mensagem diz pathname, não directory.Neste nível, prefiro manter as coisas simples - os argumentos para uma função são apenas strings.

if [ -d "$Directory" -a -w "$Directory" ]
then
    #Statements
fi

O código acima verifica se o diretório existe e se é gravável.

Digite este código no prompt do bash

if [ -d "$DIRECTORY" ]; then
  # if true this block of code will execute
fi

Mais recursos usando find

  • Verifique a existência da pasta nos subdiretórios:

    found=`find -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where "myDirectory" is.
        # It may contain several lines if there are several folders named "myDirectory".
    fi
    
  • Verifique a existência de uma ou mais pastas com base em um padrão dentro do diretório atual:

    found=`find -maxdepth 1 -type d -name "my*"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where folders "my*" have been found.
    fi
    
  • Ambas as combinações.No exemplo a seguir, verifica a existência da pasta no diretório atual:

    found=`find -maxdepth 1 -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' is not empty => "myDirectory"` exists.
    fi
    

Na verdade, você deve usar várias ferramentas para obter uma abordagem à prova de balas:

DIR_PATH=`readlink -f "${the_stuff_you_test}"` # Get rid of symlinks and get abs path
if [[ -d "${DIR_PATH}" ]] ; Then # now you're testing
    echo "It's a dir";
fi

Não há necessidade de se preocupar com espaços e caracteres especiais, desde que você use "${}".

Observe que [[]] não é tão portátil quanto [], mas como a maioria das pessoas trabalha com versões modernas do Bash (afinal, a maioria das pessoas nem trabalha com linha de comando :-p), o benefício é maior que o problema.

Para verificar mais de um diretório use este código:

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi

Você já pensou em fazer o que quiser no if em vez de olhar antes de pular?

Ou seja, se você quiser verificar a existência de um diretório antes de acessá-lo, tente fazer o seguinte:

if pushd /path/you/want/to/enter; then
    # commands you want to run in this directory
    popd
fi

Se o caminho que você dá pushd existe, você entrará nele e sairá com 0, o que significa o then parte da instrução será executada.Se não existir, nada acontecerá (além de alguma saída dizendo que o diretório não existe, o que provavelmente é um efeito colateral útil para depuração).

Parece melhor do que isso, o que exige que você se repita:

if [ -d /path/you/want/to/enter ]; then
    pushd /path/you/want/to/enter
    # commands you want to run in this directory
    popd
fi

A mesma coisa funciona com cd, mv, rm, etc...se você experimentá-los em arquivos que não existem, eles sairão com um erro e imprimirão uma mensagem dizendo que não existe, e seu then bloco será ignorado.Se você experimentá-los em arquivos que existem, o comando será executado e sairá com um status de 0, permitindo que seu then bloco para executar.

Verifique se o diretório existe, caso contrário, crie um

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"

Observação:Citar variáveis ​​é uma boa prática.

[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"

Esta resposta embrulhado como um script de shell

Exemplos

$ is_dir ~                           
YES

$ is_dir /tmp                        
YES

$ is_dir ~/bin                       
YES

$ mkdir '/tmp/test me'

$ is_dir '/tmp/test me'
YES

$ is_dir /asdf/asdf                  
NO

# Example of calling it in another script
DIR=~/mydata
if [ $(is_dir $DIR) == "NO" ]
then
  echo "Folder doesnt exist: $DIR";
  exit;
fi

is_dir

function show_help()
{
  IT=$(CAT <<EOF

  usage: DIR
  output: YES or NO, depending on whether or not the directory exists.

  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

DIR=$1
if [ -d $DIR ]; then 
   echo "YES";
   exit;
fi
echo "NO";

Usando o -e check irá verificar se há arquivos e isso inclui diretórios.

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi

Conforme Jônatas Comente:

Se você deseja criar o diretório e ele ainda não existe, então a técnica mais simples é usar mkdir -p que cria o diretório - e quaisquer diretórios ausentes no caminho - e não falha se o diretório já existir, então você pode fazer tudo de uma vez com:

mkdir -p /some/directory/you/want/to/exist || exit 1
if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists
fi

Isto não é completamente verdadeiro...Se quiser ir para esse diretório, você também precisa ter direitos de execução no diretório.Talvez você precise ter direitos de gravação também.

Portanto:

if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then
    # ... to go to that directory (even if DIRECTORY is a link)
    cd $DIRECTORY
    pwd
fi

if [ -d "$DIRECTORY" ] && [ -w "$DIRECTORY" ] ; then
    # ... to go to that directory and write something there (even if DIRECTORY is a link)
    cd $DIRECTORY
    touch foobar
fi

O ls comando em conjunto com -l A opção (lista longa) retorna informações de atributos sobre arquivos e diretórios.
Em particular, o primeiro personagem de ls -l saída geralmente é um d ou um - (traço).No caso de um d o listado é um diretório com certeza.

O comando a seguir em apenas uma linha dirá se o dado ISDIR variável contém um caminho para um diretório ou não:

[[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
    echo "YES, $ISDIR is a directory." || 
    echo "Sorry, $ISDIR is not a directory"

Uso prático:

    [claudio@nowhere ~]$ ISDIR="$HOME/Music" 
    [claudio@nowhere ~]$ ls -ld "$ISDIR"
    drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." ||
        echo "Sorry, $ISDIR is not a directory"
    YES, /home/claudio/Music is a directory.

    [claudio@nowhere ~]$ touch "empty file.txt"
    [claudio@nowhere ~]$ ISDIR="$HOME/empty file.txt" 
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." || 
        echo "Sorry, $ISDIR is not a directoy"
    Sorry, /home/claudio/empty file.txt is not a directory
file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;

Se você quiser verificar se existe um diretório, independentemente de ser um diretório real ou um link simbólico, use isto:

ls $DIR
if [ $? != 0 ]; then
        echo "Directory $DIR already exists!"
        exit 1;
fi
echo "Directory $DIR does not exist..."

Explicação:O comando "ls" dá um erro "ls:/x:Nenhum arquivo ou diretório" se o diretório ou link simbólico não existir, e também define o código de retorno, que você pode recuperar via "$?", como não nulo (normalmente "1").Certifique-se de verificar o código de retorno diretamente após chamar "ls".

(1)

[ -d Piyush_Drv1 ] && echo ""Exists"" || echo "Not Exists"

(2)

[ `find . -type d -name Piyush_Drv1 -print | wc -l` -eq 1 ] && echo Exists || echo "Not Exists"

(3)

[[ -d run_dir  && ! -L run_dir ]] && echo Exists || echo "Not Exists"

Se for encontrado um problema com uma das abordagens fornecidas acima.

Com ls comando;os casos em que o diretório não existe - uma mensagem de erro é mostrada

$ [[ ls -ld SAMPLE_DIR| grep ^d | wc -l -eq 1 ]] && echo existe || não existe -Ksh:não:não encontrado [Esse arquivo ou diretório não existe]

Existem ótimas soluções, mas no final das contas todos os scripts falharão se você não estiver no diretório correto.Então codifique assim:

if [ -d "$LINK_OR_DIR" ]; then 
if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here
    rm "$LINK_OR_DIR"
else
    # It's a directory!
    # Directory command goes here
    rmdir "$LINK_OR_DIR"
fi
fi

será executado com sucesso somente se no momento da execução você estiver em um diretório que possui um subdiretório que você verifica.

Eu entendo a pergunta inicial assim:para verificar se um diretório existe independentemente da posição do usuário no sistema de arquivos.Portanto, usar o comando 'find' pode resolver o problema:

dir=" "
echo "Input directory name to search for:"
read dir
find $HOME -name $dir -type d

Esta solução é boa porque permite o uso de curingas, um recurso útil na busca por arquivos/diretórios.O único problema é que, se o diretório pesquisado não existir, o comando 'find' não imprimirá nada no stdout (o que não é uma solução elegante para o meu gosto) e, no entanto, terá uma saída zero.Talvez alguém possa melhorar isso.

Abaixo encontrar pode ser usado,

find . -type d -name dirname -prune -print
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top