Alguns comandos do Linux e Unix acabaram por tornar-se tão onipresentes e aparentemente óbvios que não nos damos conta de como podem ser ricos. Um destes comandos é o prosaico cp. Isso, um mero comando para cópia de arquivos pode reservar muitas surpresas.
O comando cp tem como função copiar arquivos e diretórios. Entretanto, por precaução, ele irá copiar somente arquivos, a não ser quando explicitamente informado que deve copiar diretórios.
A sintaxe padrão é
cp [opções] origem destino
como em
cp velhoarq novoarq
que criará uma cópia de velhoarq no próprio diretório corrente, com o nome de novoarq.
Podem ser informadas origens múltiplas como neste caso
cp /var/log/arq1 /bin/arq2 ~/arq3 /tmp
No comando acima teríamos a cópia de três arquivos, cada um deles encontrado em um diretório distinto, todos para o diretório /tmp.
Contudo, as opções e metacaracteres tornarão o uso do cp muito mais flexível e produtivo.
Tomando cuidado
Geralmente, comandos Unix são cegamente obedientes. Ao mandar copiar diversos arquivos para determinado destino, essa cópia será realizada prontamente. E isto ocorrerá mesmo que exista arquivo no destino com o mesmo nome de algum dos arquivos a ser copiado. Uma forma de se prevenir disto é com a opção -i (ou –interactive) que faz com que o cp pergunte o que fazer antes de sobrescrever um arquivo.
Teste-o da seguinte forma:
cd /tmp && touch arq1 arq2 && cp arq1 arq2 && rm -f arq?
Nenhuma pergunta, certo? Agora tente assim:
cd /tmp && touch arq1 arq2 && cp -i arq1 arq2 && rm -f arq?
Outra forma de prevenir possível perdas é utilizar a opção -b (ou –backup), para gerar um arquivo de backup. Veja assim:
cd /tmp
echo "1" > arq1
echo "2" > arq2
cp -b arq1 arq2
ls -l arq*
cat arq2
cat arq2~
rm -f arq*
Você reparou que o arquivo de backup é aquele com um til (~) como sufixo. Se desejar alterar isto pode repetir os comandos fazendo a cópia da seguinte forma
cp -b --suffix='.copia' arq1 arq2
Convém acrescentar que, ao sobrescrever um arquivo, o cp irá alterar o conteúdo do mesmo, sem alterar metadados como direitos ou dados de propriedade do arquivo. Vamos ao teste:
cd /tmp && echo "Conteudo 1" > arq1 && ls -l arq1
chmod 467 arq1 && sudo chown nobody.nogroup arq1 && ls -l arq1
cat arq1
echo "Novo conteudo" > arq2 && ls -l arq?
cp arq2 arq1 && ls -l arq?
cat arq1
sudo rm -f arq?
Mas, e se seu objetivo for manter as permissões, propriedades e hora de acesso e modificação do arquivo de origem no de destino utilize a opção -p. Teste os comandos acima utilizando esta opção no comando cp (será necessário utilizar o cp com sudo, para não sofrer restrições causadas por questões de propriedade do arquivo). Você pode controlar qual parâmetro quer que seja preservado utilizando –preserve no lugar do -p e indicando o que deve ser preservado. Aliás, a opção -p é equivalente à –preserve=mode,ownership,timestamps
Sem perguntas!
A opção -i faz com que o cp verifique se deve sobrescrever um arquivo. Todavia, pode ser que você esteja ciente da presença de arquivos com o mesmo nome e queira sobrescrever sem ser molestado por perguntas. Então utilize a opção -f (ou –force) e veja o comando ser executado sem questioná-lo.
Copiando diretórios
Para copiar diretórios devemos informar que queremos cópias recursivas, incluindo os arquivos de subdiretórios. Para tal podemos utilizar as opções -r e -R (ou –recursive). A segunda forma é preferida por copiar também certos arquivos especiais que não seriam copiados com a opção -r.
O que está acontecendo?
Você solicitou a cópia de dezenas de arquivos e está inseguro sobre o progresso desta cópia. A opção -v (ou –verbose) fará com que sejam listados na tela os nomes dos arquivos que estão sendo copiados.
Copiando incrementalmente
Este artigo foi motivado pelas minhas pesquisas para resolver um determinado problema. Eu havia feito diversas cópias de um mesmo diretório. Em cada uma destas cópias eu alterei alguns arquivos, mas nem sempre os mesmos. Posteriormente eu queria ter uma cópia com as versões mais novas dos arquivos. A solução foi copiar cada um destes diretórios para um diretório único com a opção -u (ou –update). Ela irá fazer com que somente sejam sobrescritos arquivos mais velhos do que os da origem. Veja em
cd /tmp
mkdir dir1 && cd dir1
echo "velho" > arq1
echo "velho" > arq2
cd ..
cp -R dir1 dir2
cat dir2/arq1
cat dir2/arq2
echo "novo" > dir1/arq1
cp -u dir1/* dir2
cat dir2/arq1
cat dir2/arq2
rm -fr dir?
Backup
Aliás, a opção -u leva-nos a uma boa forma de utilizar o cp para realizar backups. Se você tem interesse em fazer backup incremental de certo diretório, você poderia utilizar um comando como
cp -uvfa ~/ /media/pendrive
Este comando copiaria os arquivos de seu diretório padrão para um pendrive. As opções utilizadas foram u (update), v (verbose), f (force) e a (archive). A opção -a (ou –archive) é equivalente a outras três: R (recursive), p (preserve) e d (do qual falarei em outro artigo sobre cp e links). Desta forma copiaríamos todos os arquivos e diretórios do meu diretório padrão, inclusive alguns especiais, sem perguntas, listando-os, preservando permissões e outros metadados, de modo incremental.
Economizando digitação
Imagine-se digitando um comando como
cp ~/musicas/mp3/madonna_vogue.mp3 ~/musicas/mp3/madonna_vogue.backup
Há uma forma mais prática que seria
cp ~/musicas/mp3/madonna_vogue{.mp3,.backup}
As chaves irão gerar duas cópias da expressão original, uma terminando com .mp3 e outra com .backup. Você pode utilizar uma destas duas expressões vazias como em
cp ~/musicas/mp3/madonna_vogue.mp3{,.backup}
Cópia com compressão
Existe uma opção de realizar cópias com o tar, de forma a utilizar compressão de dados. Ao invés de
cp -R ~ /tmp
você poderia utilizar um
cd /tmp && $( cd ~ ; tar -cf - . ) | tar -xvf -
Há quem diga que a segunda forma seria mais rápida por fazer tráfego de dados comprimidos. Da forma como eu apresentei, a primeira opção levou 14 centésimos de segundo para realizar a cópia de pouco mais de 40 MBytes. A opção seguinte levou quase 24 segundos! Talvez exista alguma vantagem se a origem ou o destino estejam em outros computadores, com tráfego pela rede.
Conclusão
O comando cp é rico em opções. Bem exploradas, elas podem descortinar modos de uso valiosos em determinadas ocasiões