Minha pergunta é por que é necessário usar o -r
sinalizador (recursivo) ao fazer uma cópia de um diretório? Ou seja, por que fazer isso:
$ cp -r dir1 copyDir1
Quando eu não gostaria desse comportamento ao copiar um diretório?
Uma cópia recursiva de um diretório não é realmente o comportamento "padrão"; o comportamento que queremos quase o tempo todo?
Parece que esta é uma bandeira supérflua.
rm
Respostas:
Da maneira como os sistemas de arquivos funcionam, um diretório não é realmente uma pasta que contém arquivos, mas um diretório é um arquivo que contém ponteiros de inode para arquivos “filhos” conectados a ele. Ou seja, da perspectiva do sistema de arquivos, um arquivo é um arquivo, mas um diretório é apenas um arquivo que contém a lista de arquivos conectados.
Portanto, da perspectiva da linha de comando, faça o seguinte:
Basicamente, significa copiar o arquivo nomeado,
dir1
para um novo arquivo nomeadocopyDir1
. E, no que diz respeito ao sistema de arquivos,dir1
é apenas um arquivo; o fato de ser um "diretório" só será aparente quando o sistema de arquivos realmente verificardir1
para ver o que realmente é essa pilha de bits.O
-r
sinalizador diz ao sistema de arquivos para rolar recursivamente a árvore de arquivos / diretórios e copiar todo e qualquer conteúdo que possa ser um "filho" desse arquivo para um novo local.Agora, por que isso pode parecer supérfluo ou redundante, isso realmente se resume a métodos históricos de lidar com sistemas de arquivos. Além de criar um sistema seguro contra todos os tipos de erros relacionados ao usuário; acidental e intencional.
Ou seja, digamos que você tenha um
~/bin
arquivo em seu diretório pessoal que deseja copiar, mas que acidentalmente tenha deixado de lado,~
porque você é humano e comete erros, então é assim/bin
:Com a “rede de segurança” de
/bin
ser um diretório combinado com a necessidade do-r
sinalizador, você evitará copiar acidentalmente toda a raiz binária do sistema em que está no diretório inicial. Se essa rede de segurança não existisse, um desastre menor - ou possivelmente maior - aconteceria.A lógica aqui é que nos dias anteriores às convenções lógicas / comportamentais pré-GUI (interfaces gráficas com o usuário) precisam ser definidas para evitar que o usuário crie contratempos que possam potencialmente matar um sistema. E usar a
-r
bandeira agora é um deles.Se isso parecer supérfluo, não será necessário procurar o sistema GUI moderno acima dos sistemas de arquivos Linux. Uma GUI soluciona problemas básicos do usuário como esse, permitindo arrastar e soltar arquivos e diretórios com facilidade.
Porém, no caso das interfaces baseadas em texto, grande parte da “experiência do usuário” nesse mundo é basicamente apenas obstáculos econômicos e lógicos que ajudam a manter o usuário sob controle para evitar possíveis desastres.
Da mesma forma, é por isso que os sistemas de arquivos Linux / Unix não têm
777
permissões esudo
direitos definidos por padrão e como administradores de sistema reais estremecem quando um usuário define777
permissões ou concedesudo
direitos a todos . Essas são as coisas básicas que se faz para garantir que o sistema seja estável e o mais "à prova do usuário" possível; qualquer um que se apresse em dar um curto-circuito nessas convenções provavelmente causará danos ao sistema sem nem mesmo saber.INFORMAÇÕES ADICIONAIS: Outra resposta aqui no site do Unix Stack Exchange fornece uma boa explicação de por que uma cópia não recursiva de um diretório é problemática; ênfase é minha.
Portanto, se um diretório é realmente um arquivo com itens de inode, fazer uma cópia direta desse arquivo seria apenas o equivalente a como um link físico funcionaria. O que não é o que alguém quer.
fonte
cp -r /bin
tão facilmente quantocp-r ~/bin
. A bandeira em si não evita erros ou necessariamente torna alguém melhor em tomar cuidado. Se você deseja evitar erros, o comando cp pode facilmente olhar para o nó em questão e fornecer um prompt, algo como "Este é um diretório, deseja copiar todo o conteúdo para o local especificado (y / n)? " Isso seria rede de segurança . Exigir -r para diretórios mantém o código inchado mais do que qualquer coisa.É bem verdade que esse é o comportamento que queremos quase o tempo todo. Porém, isso não significa necessariamente que copiar recursivamente deve ser o comportamento padrão.
Eu acho que as razões
cp
agem, pois têm raízes na filosofia Unix . Unix favorece programas que fazer uma coisa e fazê-lo bem , assim como os programas que são simples, em ambos interface e implementação (às vezes chamado de pior, melhor ).A peça principal do quebra-cabeça aqui é perceber que
cp
não copia diretórios -cp
copia arquivos (e somente arquivos). Se você deseja copiar um diretório,cp
chama-se recursivamente , para copiar os arquivos em cada diretório.Obviamente, a diferença entre "copiar diretórios" e "copiar arquivos recursivamente" não é absolutamente nada, na perspectiva do usuário, mas ter essa interface ajuda a implementação a permanecer simples .
Se você
cp
conseguiu copiar diretórios, em breve ficaria tentado a adicionar mais recursos que só fazem sentido para diretórios - por exemplo, convém copiar apenas os nomes de arquivos que terminaram em.sh
. Inevitavelmente, isso leva ao inchaço e à fluência de recursos com os quais estamos acostumados em outros sistemas operacionais - tornando o software lento, complexo e propenso a erros.Outra vantagem é que ter
-r
também ajuda o usuário a entender o que realmente está acontecendo sob a interface. Um bom efeito colateral disso é que aprender o conceito de operação recursiva poupará algum trabalho quando você aprender sobre outras ferramentas que o suportam (comogrep
, por exemplo)Algumas pessoas certamente dirão que a exposição dos detalhes da implementação ao usuário é ruim e que ter mais recursos é bom . Minha intenção aqui é apenas explicar a lógica desse comportamento, então não tentarei argumentar de qualquer maneira.
fonte
As interações com diretórios garantem que você esteja interagindo com um diretório e NÃO apenas com um único arquivo.
Por exemplo:
Portanto, se você deseja copiar com êxito uma pasta, uma vez que ela implica a pasta e os objetos relacionados à referência à pasta, você deve tratá-la como se fosse uma coleção de arquivos:
fonte
A consequência da alteração do padrão seria que milhares de scripts de shell quebrariam. Isso leva aos requisitos POSIX e SUS para o conhecido comportamento padrão.
O motivo é o desenvolvimento histórico dos comandos cp, ln e mv (todos os mesmos binários na maioria dos sistemas UNIX antigos) em várias ramificações do UNIX. Quando
-r
apareceu (o iníciocp
não tinha a opção de copiar diretórios; aqui está uma página inicial do cp sem-r
ou-R
), havia várias diferenças no manuseio de arquivos especiais, links simbólicos e outros caprichos do sistema de arquivos.Do Open Group Base Specifications Edição 7 :
Na verdade, você ainda verá algumas pessoas usando regularmente:
Porque eles não confiam que a
cp -r
implementação seja o que estão acostumados em uma máquina arbitrária; Ou porque eles querem otar
comportamento.fonte
Pode ser uma interface de usuário subótima hoje, mas foi uma decisão tomada em torno de 1970 durante o design do UNIX, quando o disco era consideravelmente mais caro. Milhões de scripts de shell dependem do funcionamento dessa maneira e é tarde demais para alterá-lo.
Consulte este artigo para obter as informações de design originais.
fonte
Uma clara vantagem do
-r
sinalizador é que você podecp * /target/dir
copiar apenas todos os arquivos no diretório de origem no diretório de destino, omitindo (embora com um aviso) todos os diretórios nele contidos.cp -r * /target/dir
copiaria tudo, incluindo subdiretórios.fonte
Você precisa desse sinalizador apenas quando
cp
for um comando para copiar arquivos e diretórios e não apenas diretórios.Se houvesse um comando especial para cópia de diretórios, o comportamento "padrão" certamente seria uma cópia recursiva.
fonte
mkdir
?Como outros já mencionaram, um diretório é basicamente apenas outro tipo de arquivo (em oposição a um arquivo normal), que geralmente "contém" (aponta para) outros arquivos. Pode conter subdiretórios, aos quais o mesmo se aplica ...
Portanto, se você estiver copiando um diretório (perspectiva do usuário), realmente está copiando vários arquivos (perspectiva do sistema de arquivos) (arquivos regulares, arquivos de diretório, links simbólicos, ...) e para cada arquivo de diretório, você está repetindo repetidamente processo. Como copiar um diretório é, por definição, um processo recursivo, o argumento do cp é chamado
--recursive
.Obviamente, é muito fácil criar um atalho de comando no ambiente do usuário (coloque isso no seu arquivo .profile / .bashrc para torná-lo permanentemente disponível):
Ou talvez melhor:
Dessa forma, você pode copiar um diretório usando
cpa dir1 copyDir1
e ele não apenas imprimirá o que está sendo copiado, mas também aplicará permissões de arquivo.E como alguém mencionou que o cp poderia teoricamente detectar que o arquivo de origem é um diretório e perguntar se deveria copiá-lo recursivamente, aqui está uma sugestão rápida:
Este é apenas um invólucro cp barato. Ele sempre preserva todos os metadados (ou seja, copia a hora da modificação do arquivo, copia corretamente links simbólicos e assim por diante) e se você estiver tentando copiar um diretório, ele pergunta se deve copiá-lo (recursivamente).
fonte