Substituir um diretório existente?

Substituir um diretório existente?

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 mkdirdeu um erro:

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

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

Então, como substituir fooo diretório?

Por que não mkdirtem opção de fazer isso?

Responder1

Se o 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 contiver arquivos somente leitura, você precisará do -fsinalizador para removê-los sem avisar o usuário de forma interativa. Tudo bem, mas recomendo ter um cuidado especial com rm -rf .... Verman rmpara detalhes.
  • Você precisa do rmcomando paraterminarantes 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 uma falha significará 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á existia; 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 a fooexistência de antes de tentar criá-lo.

Ver3.2.3 Listas de ComandosnoManual de referência do Bashpara obter mais informações e explicações sobre os operadores ;, &, ||e &&.

ComoMuru sugeriu(eRinzwind elaborou),Eu recomendo que você dê uma olhadarsyncpara ver se ele atenderá às suas necessidades de backup. Existem alguns guias úteis adicionais sobre opágina de documentação do rsync, assim comoeste guia rsync do Ubuntu.

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

mkdircria diretórios (o "mk"significa "fazer"). Pois também excluir recursivamente diretórios e todos os arquivos neles contidos seria ruim, porque violaria oprincípio do menor espantode uma forma que provavelmente levaria à perda de dados.

rmdirnem mesmo remove diretórios que contenham arquivos (não-diretórios).rmtem uma -ropção, o que faz sentido, já que rmse espera remover arquivos (esse é o seu propósito, portanto, o perigo inerente é intuitivo e os usuários normalmente sabem que devem ter cuidado ao executar rmcomandos).

Responder2

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

Por que?

Esta é a filosofia do Unix: Escreva programas que façam uma coisa e façam bem. Escreva programas para trabalharem juntos. 1

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

1A arte da programação Unix, Eric S. Raymond, citando Doug McIlroy.

Responder3

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 encadeá-los com ;(= faça as duas coisas mesmo se o primeiro falhar) ou &&(= apenas mkdir quando o rm não falhar).

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

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

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

Responder4

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

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 é um diretório e não um arquivo:

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

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

  3. Crie o novo diretório e faça eco com sucesso ou, se falhar, faça eco com falha.

informação relacionada