mkdir recursivo

305

Existe um comando linux que estou ignorando que torna possível fazer algo ao longo das linhas de: (pseudo)

$ mkdir -R foo/bar/zoo/andsoforth

Ou não há alternativa senão criar os diretórios um de cada vez?

Braiam
fonte
1
engraçado, eu estava olhando para essa página, mas esqueci totalmente de "pai" porque pensava neles como crianças (da esquerda para a direita).
18
Protip: Em algumas conchas você pode até fazer mkdir -p foo/{bar,baz}/zoo/andsoforth. Muito útil!
Aaron Copley
1
Pessoalmente, eu também ignorei "pai" na página de manual porque, bem, sinto que o sinalizador deve ser "-r" para "recursivo" - ou, pelo menos, deve haver um alias para isso, pois mkdirpossui apenas 6 sinalizadores documentados no total. Inferno, eu sinto que o comando deve criar diretórios recursivamente por padrão, e se você não quiser isso, deverá especificar isso explicitamente.
21136 jbowman
1
stackoverflow.com/questions/1731767/…
Ciro Santilli escreveu

Respostas:

511
$ mkdir -p foo/bar/zoo/andsoforth
EEAA
fonte
92
FYI o -p significa "pais"
carl crott
14
Eles poderiam ter feito -r em vez disso, como qualquer outro comando, isso é impossível lembrar de parâmetros específicos para cada comando linux
Vedmant
2
Mas mkdir -pnão é multiplataforma, não funciona em todos os shell
#
9
@ РоманКоптев, mkdir -pé especificado no POSIX , que é o mais próximo de ser totalmente portátil. Qual o melhor que você espera em um script de shell?
Curinga
5
@StephanBijzitter Sim, este é o unix.se, não o unixandwindows.se. :)
EEAA
16

O usomkdir -p é uma maneira simples para a maioria dos sistemas operacionais modernos:

mkdir -p foo/bar/zoo/andsoforth

No entanto, mkdir -pnão é recomendado em muitos manuais. Leia a documentação do GNU makee autoconfsobre problemas com o uso mkdir -p:

Os sistemas de instalação e configuração de plataforma cruzada têm suas próprias alternativasmkdir -p seguras .

CMake para usar na linha de comando do shell:

 cmake -E make_directory foo/bar/zoo/andsoforth

Autoconf para usar em script com pré-processamento:

AS_MKDIR_P(foo/bar/zoo/andsoforth)

ou:

AC_PROG_MKDIR_P(foo/bar/zoo/andsoforth)

Mas essas soluções exigem cmakeou autoconf( M4) ferramentas para serem instaladas (e possível pré-processamento)

Você também pode usar o install-shscript com a -dopção:

install-sh -d foo/bar/zoo/andsoforth

Este script é usado por autoconfe automakeprojeto. Eu acho que deve ser a solução mais segura.

Na época, eu estava procurando por uma solução de plataforma cruzada para padrão /bin/shsem dependências, mas não encontrei nenhuma. Portanto, escrevi o próximo script que pode não ser o ideal, mas acho que é compatível com a maioria dos requisitos de plataforma cruzada :

#! /bin/sh

cdirname() # cross platform alternative for 'dirname'
{
  # $1 - path
  test $# -eq 1 || { echo "Procedure 'cdirname' must have only one parameter. Scripting error."; exit 1; }
  echo "$1" | sed -n -e '1p' | sed  -e 's#//*#/#g' -e 's#\(.\)/$#\1#' -e 's#^[^/]*$#.#' -e 's#\(.\)/[^/]*$#\1#' -
}

mkd() # cross platform alternative for 'mkdir -p'
{
  # $1 - directory to create
  test $# -eq 1 || { echo "Function 'mkd' can create only one directory (with it's parent directories)."; exit 1; }
  test -d "$1"  && return 0
  test -d "$(cdirname "$1")" || { mkd "$(cdirname "$1")" || return 1; }
  test -d "$1" || { mkdir "$1" || return 1; }
  return 0
}

Este script pode ser usado para sistemas antigos, nos quais a opção -pfor mkdirestá ausente.

sedversão multi-plataforma baseada em dirnamefoi adicionada ao código. Ele funciona de maneira semelhante a dirname(correto com caminho /, caminhos apenas com nome de base, caminhos com final /, caminhos com e sem final \n). Esta função não pode funcionar corretamente se o caminho tiver novas linhas ou caracteres inválidos para a localidade atual. Ele também substitui qualquer combinação de /( //, ///) por uma única/

Alterou a linha mkdir "$1" || return 1para test -d "$1" || { mkdir "$1" || return 1; }porque mkdirtermina com erro se o caminho existe e esta verificação é necessária para caminhos que contenham construções como aaa\.(Se aaanão existe, a versão anterior cria aaae tenta criá-la novamente).

Esta versão do mkd não gera um erro se o caminho já existir (mas ainda tem a possibilidade de gerar esse erro na execução paralela) e não pode obter vários diretórios na linha de comando.

Роман Коптев
fonte
4
"mkdir -p" é definido pelo posix. Quais variantes unix ou do tipo unix não são compatíveis? (e não deve ser um shell embutido, embora eu ache que não haja motivo para isso.) pubs.opengroup.org/onlinepubs/9699919799/utilities/mkdir.html
Tim B
5
Algumas das informações nessa página têm apenas 15 anos. Alguns são mais velhos.
Thomas Dickey
7
Os sistemas que não suportariam mkdir -pseriam muito antigos (e estamos falando há pelo menos duas décadas) para ter um printfutilitário ou suporte --para marcar o fim das opções.
Stéphane Chazelas
2
Você cdirnamedaria a resposta errada foo/bar//ou nomes de diretório que contenham caracteres de nova linha ou caracteres inválidos no código de idioma atual.
Stéphane Chazelas
2
printfé seguro em sistemas POSIX. Suporte de sistemas POSIX mkdir -p. mkdir -pfoi especificado pelo POSIX por décadas. --começou a se espalhar nos sistemas da AT&T a partir do SysIII no início dos anos 80. printfapareceu pela primeira vez como um kshbuiltin eu acredito e foi especificado pelo POSIX posteriormente mkdir -p. Alguns shells POSIX (como o pdksh ou o yash) ainda não foram printfincorporados.
Stéphane Chazelas
0

Opção -pno comando mkdirfaz p diretórios Arent conforme necessário (sem erro se existente):

mkdir -p foo/bar/zoo/andsoforth

Outra maneira é, por exemplo, usar &&(erro se a pasta especificada existir):

mkdir foo && mkdir foo/bar && mkdir foo/bar/zoo && mkdir foo/bar/zoo/andsoforth

O operador de encadeamento &&é usado para encadear comandos juntos, de modo que o próximo comando seja executado se e somente se o comando anterior tiver saído sem erros.

Claro, o primeiro caminho é melhor.

simhumileco
fonte
-3
mkdir foo foo/bar foo/bar/zoo/ foo/bar/zoo/andsofort.

Isso deve servir.

Kanchan Kumar
fonte