Sobrescrever um diretório existente?

11

Eu tenho um nome de diretório foolocalizado em ~/Desktop. Suponha que eu queira criar um diretório a partir de um terminal com o mesmo nome e no mesmo local. Quando tentei mkdir, deu um erro:

mkdir: cannot create directory `/home/nux/Desktop/foo': File exists

Isso faz sentido, mas eu quero substituir foose existir. Eu olhei através, man mkdirmas não há nenhuma opção que faça isso.

Então, como substituir o foodiretório?

Por que não mkdirtem uma opção para fazer isso?

nux
fonte
Substituir foocomo em excluir todo o conteúdo dele? mkdirpossui uma -popção que ignora se o diretório existe.
Muru
4
Então, você quer um comando que exclua todos os arquivos em um diretório quando criar acidentalmente um novo diretório com o mesmo nome? E você se pergunta por que não há nenhuma opção? Isso é uma piada?
Marty Fried
downvoters apenas esclarecer por que, estou perguntando sobre um comando que excluir um diretório existente
nux
1
@ nux para mim a pergunta não faz sentido ... explique por que você deseja excluir e recriar um diretório. Temos comandos para qualquer coisa que você precise fazer no diretório. O mkdir não precisa de uma opção para remover / recriar.
Rinzwind
1
é um crime aqui se estou fazendo uma pergunta lógica !!
nux

Respostas:

21

Se seu objetivo é executar um comando de uma linha que:

  • Remove e recria o diretório, ~/Desktop/foose ele já existir.
  • Apenas cria o diretório ~/Desktop/foose ele ainda não existir.

Então você pode usar:

rm -r ~/Desktop/foo; mkdir ~/Desktop/foo

; é equivalente a uma nova linha, mas permite executar vários comandos em uma única linha (ou seja, como um "comando único").

  • Se o diretório que você está removendo pode conter arquivos somente leitura, você precisará do -fsinalizador para removê-los sem avisar o usuário interativamente. Tudo bem, mas eu recomendo ser especialmente cuidadoso rm -rf .... Veja man rmpara detalhes.
  • Você precisa que o rmcomando termine antes da mkdirexecução do comando; esta é a razão para usar em ;vez de &. (Um comando anterior &é executado de forma assíncrona em segundo plano.)
  • Você precisa que o mkdircomando seja executado quando o rmcomando for bem-sucedido; esta é a razão para usar em ;vez de ||.
  • Você precisa que o mkdircomando seja executado quando o rmcomando falhar (geralmente falha significa que o diretório ainda não existia); esta é a razão para usar em ;vez de &&.
  • O rmcomando pode falhar mesmo quando o diretório já existe; nesse caso, o mkdircomando também falhará, mas as mensagens de erro farão sentido e provavelmente não há necessidade de adicionar uma etapa intermediária para verificar fooa existência antes de tentar criá-lo.

Veja 3.2.3 listas de comandos no manual Bash Reference para mais informações e explicações sobre os ;, &, ||, e &&operadores.

Como o muru sugeriu (e Rinzwind elaborou ), eu recomendo que vocêrsync verifique se ele atenderá às suas necessidades de backup. Existem alguns guias úteis adicionais na página de documentação do rsync , bem como neste guia do rsync do Ubuntu .

por que o mkdir não tem essa opção?

mkdircria diretórios (o "mk" significa "make" ). Também excluir diretórios recursivamente e todos os arquivos neles seriam ruins, porque violariam o princípio de menos espanto de uma maneira que provavelmente levaria à perda de dados.

rmdirnem remove os diretórios que possuem arquivos (que não sejam de diretório). rmpossui uma -ropção, que faz sentido, pois rmé esperado remover arquivos (esse é o seu objetivo, portanto, o perigo inerente é intuitivo e os usuários geralmente sabem que devem ter cuidado ao executar rmcomandos).

Eliah Kagan
fonte
+1 excelente. Essa resposta vai além da explicação da sintaxe, algo que eu gostaria que fosse mais profundo nos sites de stackexchange. Há muitas pepitas de ouro nesta resposta.
Govind Rai
7

Não, não existe um único comando para fazer o que você está pedindo.

Por quê?

Esta é a filosofia do Unix: escreva programas que fazem uma coisa e fazem bem. Escreva programas para trabalhar juntos. 1 1

Nesse caso, os comandos mkdire rmfazem o que você precisa e funcionam bem juntos, pois rm -rtambém excluirão o diretório e, portanto, um subsequente mkdircriará o diretório.

1 The Art of Unix Programming , Eric S. Raymond, citando Doug McIlroy.

muru
fonte
por enquanto, essa é uma boa resposta, vou procurar por isso
nux
3

O comando para remover um diretório é rm. Então você precisa de 2 comandos.

rm -r ~/Desktop/foo/
mkdir ~/Desktop/foo/

Conforme mostrado nos comentários, você pode encadear-los com ;(= faça ambos, mesmo que o primeiro falhe) ou &&(= apenas mkdir quando o rm não falhar).

O -ré para remover diretórios. O 1º comando também remove TODO o conteúdo do diretório. Se essa não é a sua intenção, rm e mkdir não são o que você está procurando: as permissões são chmode chown.

por que o mkdir não tem essa opção?

Ambiguidade. mkdirsignifica criar diretório. Não remova e crie o diretório. E como o rmcomando é para excluir coisas, não há necessidade de rmdirremover um diretório.

Rinzwind
fonte
Eu sei disso, mas eu quero dizer um comando, você pode ver a minha edição eu mudá-lo
nux
Primeiro, explique por que você precisa recriar o diretório. Isso não faz sentido para mim.
Rinzwind
é a minha necessidade faz sentido, eu só quero saber como? faz sentido para mim :)
nux
@ Nux não, não. E o mantenedor do mkdir também não entende o porquê;) O que você deseja é inútil e não tem mérito.
Rinzwind
ok se você quer saber estou fazendo um script para fazer backup make em um novo diretório com o mesmo nome de foo e permite substituí-lo se existem para reduzir o espaço
nux
1

Para fazer isso da maneira mais limpa, eu uso isso:

create_clean_directory(){
    dir_name=$1
    if [ -d "$dir_name" ]; then
        echo "Removing $dir_name"
        rm -rf "$dir_name"
    elif [ -f "$dir_name" ]; then
        echo "File with this name already exists, not a directory."
        exit
    fi
    if mkdir "$dir_name"; then
        echo "Clean directory created: $dir_name"
        return 0
    else
        echo "Creating directory failed: $dir_name"
        return 1
    fi 
}

E para usá-lo:

create_clean_directory <dir_name>

Isso garante que o que você está tentando remover seja um diretório e não um arquivo:

  1. -dVerifique se um diretório com esse nome já existe. Nesse caso, exclua-o.

  2. -fVerifique se não existe nenhum arquivo com esse nome. Nesse caso, imprima a mensagem de erro e saia.

  3. Crie o novo diretório e execute o eco com êxito ou, se falhar, o eco falhará.

Rea Haas
fonte