Quando eu uso
cp -R inputFolder outputFolder
o resultado depende do contexto :
- se
outputFolder
não existir, ele será criado e o caminho da pasta clonada seráoutputFolder
. - Se
outputFolder
existir, o clone criado seráoutputFolder/inputFolder
Isso é horrível , porque eu quero criar algum script de instalação e, se o usuário outputFolder
executá- lo duas vezes por engano, ele será criado pela primeira vez e, na segunda execução, todas as coisas serão criadas novamente outputFolder/inputFolder
.
- Eu quero sempre o primeiro comportamento: crie um clone ao lado do original (como um irmão).
- Eu quero usar
cp
para ser portátil (por exemplo, o MINGW não foirsync
enviado) - Eu verifiquei,
cp -R --parents
mas isso recria o caminho até a árvore de diretórios (para que o clone não sejaoutputFolder
massome/path/outputFolder
) --remove-destination
ou--update
no caso 2 não mudar nada, ainda assim as coisas são copiadas paraoutputFolder/inputFolder
Existe uma maneira de fazer isso sem primeiro verificar a existência do outputFolder
(se a pasta não existir, então ...) ou usar rm -rf outputFolder
?
Qual é a maneira portátil e acordada do UNIX de fazer isso?
mv
uma coleção de arquivos seja movida para uma única regular?rsync
?cp
, a canalização entre doistar
comandos é uma boa maneira confiável de copiar árvores.rsync
enviado.tar -C input -cf - . | tar -C output -xf -
funciona.-C
muda o diretório de trabalho, mas não é uma opção padrão; portanto, se não houver suporte, você precisará executar os dois alcances nos diretórios de trabalho certos, por exemplo, no( cd input && tar -cf - . ) | ( cd output && tar -xf - )
entanto, se você estiver lidando com o Windows, usaria a resposta de roaima.Respostas:
Use isto:
Isso funciona exatamente da mesma maneira que, digamos,
cp -R aaa/bbb ccc
funciona: seccc
não existe, é criado como uma cópiabbb
e seu conteúdo; mas seccc
já existir,ccc/bbb
será criado como a cópiabbb
e seu conteúdo.Para quase qualquer instância
bbb
disso, é apresentado o comportamento indesejável que você anotou na sua pergunta. No entanto, nessa situação específica,bbb
é justo.
,aaa/bbb
realmente éaaa/.
, o que, por sua vez, é realmente justo,aaa
mas com outro nome. Portanto, temos esses dois cenários:ccc
não existe:O comando
cp -R aaa/. ccc
significa "criarccc
e copiar o conteúdo deaaa/.
paraccc/.
, ou seja, copiaraaa
paraccc
.ccc
existe:O comando
cp -R aaa/. ccc
significa "copiar o conteúdo deaaa/.
paraccc/.
, ou seja, copiaraaa
paraccc
.fonte
inputFolder/.
vez deinputFolder
e realmente funciona para mim no Windows / Git Bash. (No entanto, não funciona apenas com um final/
, preciso também do ponto após a barra). Eu dei uma vez que é interessante, embora seja provavelmente um pouco demasiado complicado para usá-lo em código público :)Não copie a pasta, apenas copie o conteúdo:
Dessa forma, você garante que o diretório de destino seja criado na primeira vez em que o script é executado e evita o problema ao executá-lo pela segunda vez.
Chris Down indica muito corretamente que, no bash, isso ignorará arquivos cujo nome começa com a
.
. Para evitar isso, você pode executarshopt -s dotglob
antes de executar o comando acima.Tanto
-p
paramkdir
quanto-R
paracp
são definidos pelo POSIX, portanto, isso deve ser perfeitamente portátil.fonte
.
. No bash, você pode usardotglob
para isso.Tente a
-T
opção paracp
. Isso existe no GNU coreutilscp
versão 8.22; pode não ser portátil fora disso.fonte
cp -T
(cp --no-target-directory
). unix.stackexchange.com/questions/94831/… Infelizmente minha versão docp
é muito mais antiga.-u
é uma ótima opção para adicionar para torná-lo preguiçoso.Você também pode usar
rsync
:(observe as barras, especialmente após a primeira)
fonte
Na minha opinião, não há nada mais simples e mais portátil do que
rm -rf outputFolder
. Então, eu sempre fico com isso. Entendo que sua pergunta é diferente, mas acho que essa é a melhor prática.fonte
cp
seja o mesmo, quando o diretório não existe e quando ele existe. Então, do que você está falando?cp
comando dado pelo OP não mantém permissões (ou registros de data e hora).Você pode usar a
-t
opção decp
comando como:Agora, se a pasta de destino não existir, ocorrerá um erro:
O comando note acima será copiado
inputFolder
junto com o conteúdo (e não apenas o conteúdo)se você deseja copiar apenas o conteúdo
inputFolder
, fica um pouco complicado (já que você precisa ter cuidado ao usar o shell globbing ao usar o asterisco *)Agora, se a pasta de destino não existir, ocorrerá um erro:
funciona com
cp (GNU coreutils) 8.23
fonte