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.
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.
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):
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.
mkdir -p foo/{bar,baz}/zoo/andsoforth
. Muito útil!mkdir
possui 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.Respostas:
fonte
mkdir -p
não é multiplataforma, não funciona em todos os shellmkdir -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?O uso
mkdir -p
é uma maneira simples para a maioria dos sistemas operacionais modernos:No entanto,
mkdir -p
não é recomendado em muitos manuais. Leia a documentação do GNUmake
eautoconf
sobre problemas com o usomkdir -p
:Os sistemas de instalação e configuração de plataforma cruzada têm suas próprias alternativas
mkdir -p
seguras .CMake para usar na linha de comando do shell:
Autoconf para usar em script com pré-processamento:
ou:
Mas essas soluções exigem
cmake
ouautoconf
(M4
) ferramentas para serem instaladas (e possível pré-processamento)Você também pode usar o
install-sh
script com a-d
opção:Este script é usado por
autoconf
eautomake
projeto. 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/sh
sem 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 :Este script pode ser usado para sistemas antigos, nos quais a opção
-p
formkdir
está ausente.sed
versão multi-plataforma baseada emdirname
foi adicionada ao código. Ele funciona de maneira semelhante adirname
(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 1
paratest -d "$1" || { mkdir "$1" || return 1; }
porquemkdir
termina com erro se o caminho existe e esta verificação é necessária para caminhos que contenham construções comoaaa\.
(Seaaa
não existe, a versão anterior criaaaa
e 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
mkdir -p
seriam muito antigos (e estamos falando há pelo menos duas décadas) para ter umprintf
utilitário ou suporte--
para marcar o fim das opções.cdirname
daria a resposta erradafoo/bar//
ou nomes de diretório que contenham caracteres de nova linha ou caracteres inválidos no código de idioma atual.printf
é seguro em sistemas POSIX. Suporte de sistemas POSIXmkdir -p
.mkdir -p
foi 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.printf
apareceu pela primeira vez como umksh
builtin eu acredito e foi especificado pelo POSIX posteriormentemkdir -p
. Alguns shells POSIX (como o pdksh ou o yash) ainda não foramprintf
incorporados.Opção
-p
no comandomkdir
faz p diretórios Arent conforme necessário (sem erro se existente):Outra maneira é, por exemplo, usar
&&
(erro se a pasta especificada existir):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.
fonte
Isso deve servir.
fonte