Como mkdir somente se um dir ainda não existe?

1987

Estou escrevendo um script de shell para executar no KornShell (ksh) no AIX. Eu gostaria de usar o mkdircomando para criar um diretório. Mas o diretório já pode existir, caso em que eu não quero fazer nada. Então, eu quero testar para ver se o diretório não existe ou suprimir o erro "O arquivo existe" que é mkdirlançado quando ele tenta criar um diretório existente.

Alguma idéia sobre a melhor forma de fazer isso?

Spike Williams
fonte

Respostas:

3294

Tente mkdir -p:

mkdir -p foo

Observe que isso também criará diretórios intermediários que não existem; por exemplo,

mkdir -p foo/bar/baz

criará diretórios fooe foo/bar, foo/bar/bazse eles não existirem.

Algumas implementações como o GNU mkdirincluem mkdir --parentsum alias mais legível, mas isso não é especificado na especificação POSIX / Single Unix e não está disponível em muitas plataformas comuns, como macOS, vários BSDs e vários Unixes comerciais, portanto deve ser evitado.

Se você desejar um erro quando os diretórios-pai não existirem e quiser criar o diretório, se ele não existir, primeiro poderá testexistir o diretório:

[ -d foo ] || mkdir foo
Brian Campbell
fonte
11
o exemplo abreviado que você usa é exatamente o que não deve fazer. Está invertendo a lógica para economizar espaço de codificação, mas deve ser usado! e && e faz mais sentido para quem lê.
Mike Q
16
@AndreasLarsen Esta pergunta é sobre mkdirsistemas tipo Unix, não sobre Windows. -pé necessário para conformidade com a especificação POSIX / Single Unix, portanto tudo o que pretenda cumprir com essas especificações será suportado -p. O Windows é totalmente diferente, a menos que você use uma camada de emulação POSIX como Cygwin ou MSYS.
Brian Campbell
22
Descobri algo interessante hoje com mkdir -p, você pode usar colchetes! {}para criar uma árvore de diretórios "complexa" em um comando. Veja aqui: technosophos.com/2010/04/15/…
herve
12
@ MikeQ Eu prefiro, em ||vez de, &&porque então toda a linha tem o status de saída correto. Importante se o seu shell é executado com errexitou se essa linha é a última de uma função, caso de comutação, qualquer que seja.
Rudimeier 13/03/16
9
@ herve Isso não tem nada a ver com mkdir; o shell expande essa expressão para uma lista discreta de argumentos que são passados ​​para mkdir.
chepner
176

Isso deve funcionar:

$ mkdir -p dir

ou:

if [[ ! -e $dir ]]; then
    mkdir $dir
elif [[ ! -d $dir ]]; then
    echo "$dir already exists but is not a directory" 1>&2
fi

que criará o diretório se ele não existir, mas avisará se o nome do diretório que você está tentando criar já está sendo usado por algo que não seja um diretório.

Alnitak
fonte
Eu não acho que exista um operador -d no korn, e -e é usado para arquivos / diretórios e apenas verifica a existência. Além disso, todos eles retornam 0 após o sucesso, então! é redundante. Corrija-me se eu estiver errado.
Alkar
1
errado em ambos os aspectos, AFAIK. testes retornar verdadeiro caso de sucesso, e -d também existe (pelo menos no MacOS X)
Alnitak
5
vale a pena mencionar que isso não é totalmente seguro para threads. entre o momento em que você verifica se o diretório existe e o tempo que você tenta escrever, as coisas podem mudar.
Justin L.
89

Use o sinalizador -p.

man mkdir
mkdir -p foo
jimmyorr
fonte
73

Definindo árvores de diretório complexas com um comando

mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}
Oleg
fonte
nenhum erro se, diretórios pai make existentes, conforme necessário
Fedir RYKHTIK
18
Lembre-se de que isso não é um recurso em mkdirsi, mas o shell que executa o comando. É chamado de expansão entre chaves - AFAIK, apenas Bash, ksh, zsh e o shell C o suportam.
Daniel Kamil Kozar
3
se você tiver espaços ao redor das vírgulas, poderá obter resultados inesperados. Cuidado.
Atlas7
1
@ Atlas7 declarou, você precisará escapar dos caracteres que normalmente fazem parte do regex. (ou seja, em vez de usar folder nameo que você precisa para uso folder\ name)
John Hamilton
1
Esta não é uma resposta; este é um tópico separado que seria mais apropriado como um comentário.
####
40

Se você não deseja mostrar nenhuma mensagem de erro:

[ -d newdir ] || mkdir newdir

Se você deseja mostrar sua própria mensagem de erro:

[ -d newdir ] && echo "Directory Exists" || mkdir newdir
Jahid
fonte
20

O velho experimentado e verdadeiro

mkdir /tmp/qq >/dev/null 2>&1

fará o que quiser com nenhuma das condições de corrida que muitas das outras soluções possuem.

Às vezes, as soluções mais simples (e mais feias) são as melhores.

paxdiablo
fonte
5
Isso falhará se "tmp" não existir. nem lhe dá nenhuma confirmação.
Mike Q
15

mkdir foofunciona mesmo se o diretório existir. Para fazê-lo funcionar apenas se o diretório chamado "foo" não existir, tente usar o -psinalizador.

Exemplo: -

mkdir -p foo

Isso criará o diretório chamado "foo" somente se ele não existir. :)

Atul Ranjan
fonte
2
Conforme mencionado por @BrianCampbell, isso também criará outros diretórios no caminho. Isso pode ser perigoso se, por exemplo, um volume for desmontado, pois pode criar diretórios no ponto de montagem.
uliwitness
11
directory_name = "foo"

if [ -d $directory_name ]
then
    echo "Directory already exists"
else
    mkdir $directory_name
fi
Visuwa Bharathi K
fonte
10

Ou se você deseja verificar a existência primeiro:

if [[ ! -e /path/to/newdir ]]; then
            mkdir /path/to/newdir
fi

-e é o teste existente para o shell korn.

Você também pode tentar pesquisar no manual do shell korn.

alkar
fonte
10

O mkdir não suporta mais a opção -p nos sistemas Windows 8+.

Você pode usar isto:

IF NOT EXIST dir_name MKDIR dir_name
Karanvir Kang
fonte
10
OP era sobre o kornshell do AIX ... nada a ver com o Windows, não é?
J.J. Chomel
9

Referindo-se à página de manual man mkdirpara a opção -p

   -p, --parents
          no error if existing, make parent directories as needed

que criará todos os diretórios em um determinado caminho, se existir, não gera erro; caso contrário, cria todos os diretórios da esquerda para a direita no caminho especificado. Experimente o comando abaixo. os diretórios newdire anotherdirnão existe antes de emitir este comando

Modo de usar correto

mkdir -p /tmp/newdir/anotherdir

Depois de executar o comando, você pode ver newdire anotherdircriar em / tmp. Você pode emitir esse comando quantas vezes quiser, o comando sempre o fez exit(0). Devido a esse motivo, a maioria das pessoas usa esse comando em scripts de shell antes de usar esses caminhos reais.

vkrams
fonte
8

Você pode usar o loop if para verificar se o diretório existe ou não, se ele não sair, crie o diretório.

1) dir = / home / dir_name

if [ ! -d $dir ]
then
     mkdir $dir
else
     echo "Directory exists"  
fi

2) Você pode usar o diretório mkdir com a opção -p para criar um diretório. Ele verificará se o diretório não está disponível.

mkdir -p $dir

O mkdir -p também permite criar a estrutura em árvore do diretório. Se você deseja criar os diretórios pai e filho usando o mesmo comando, pode optar por mkdir -p

mkdir -p /home/parent_dir /home/parent_dir/child1 /home/parent_dir/child2
AbhinavVaidya8
fonte
Existe alguma vantagem em usar o loop if !? por que alguém escolheria essa opção sobre -p ?!
Pedram bashiri
1
Compartilhei maneiras de criar as pastas quando uma pasta não existe. Depende da exigência de um. Se você tem um caso de uso em que precisa verificar se a pasta não existe e deseja acompanhá-lo para poder prosseguir com a solução 1. Se isso não importa, você pode optar pela solução 2, ela criará a pasta se não existir.
precisa saber é o seguinte
Eu não vi um loop.
Amit Naidu
3

Esta é uma função simples (bash shell) que permite criar um diretório se ele não existir.

#----------------------------------
# Create a directory if it doesn't exist
#------------------------------------
createDirectory() {
    if [ ! -d $1 ]
        then
        mkdir -p $1
    fi
}

Você pode chamar a função acima como:

createDirectory / tmp / fooDir / BarDir

O exemplo acima cria fooDir e BarDir se eles não existirem. Observe a opção "-p" no comando mkdir, que cria diretórios recursivamente. Espero que isto ajude.

Balaji Boggaram Ramanarayan
fonte
2
mkdir -p sam
  • mkdir = Criar diretório
  • -p = - pais
  • (se não houver erro, crie os diretórios pai conforme necessário)
Paritosh Yadav
fonte
2
if [ !-d $dirName ];then
     if ! mkdir $dirName; then  # Shorter version. Shell will complain if you put braces here though
     echo "Can't make dir: $dirName"
     fi
fi
Alex Zubkov
fonte