Usar cp para copiar arquivos de um diretório que contém um diretório vazio também resulta em um valor de retorno de erro, que falha em meu script.
Existe uma maneira de simplesmente pular os diretórios sem ter um valor de retorno de erro? Gostaria que o valor do erro refletisse quaisquer erros, mas ter um diretório vazio deve ser simplesmente ignorado, sem ser relatado como um erro.
Eu poderia simplesmente adicionar um sinalizador recursivo, -r
mas e se eu simplesmente não quiser que o diretório seja copiado, mas eufazerdeseja que algum erro seja relatado?
Responder1
Sugiro que você use rsync em vez de cp, se puder tem a opção -m que excluirá pastas vazias, exemplo:
rsync -am <origin> <destination>
Explicação do comando emexplicashell.com
Estou usando a opção -a porque ela executa muitas ações padrão interessantes, mas se você quiser, também pode usar a opção -r, que definirá apenas o modo recursivo.
[Adicionar comentário]
Não conheço uma maneira de fazer isso com cp, pelo menos a página de manual não mostra nenhuma opção que faça isso para você. Você provavelmente pode fazer uma solução mais complexa usando o comando find
para encontrar a lista de arquivos/diretórios para copiar e depois passá-la para o cp, mas isso seria muito mais complicado que o rsync. rsync é praticamente padrão em muitos Linux
Responder2
cp
na verdade não tem a opção de obter apenas arquivos, mas comofuriosodisse, você pode usar find
junto com cp
. Na verdade, isso é muito simples:
# Copy only files
find /path/to/file -type f -execdir cp "{}" /dest/path ";"
Ou:
# Copy everything except directories
find /path/to/file -not -type d -execdir cp "{}" /dest/path ";"
Explicação
find
é a ferramenta que irá procurar os arquivos que você deseja. Na primeira opção, configuramos -type f
para retornar apenas arquivos normais. Na segunda opção, configuramos -not -type d
para obter tudo, exceto diretórios. find
executa os argumentos passados para -execdir
substituição {}
por uma entrada de resultado por vez e interrompe o comando quando ;
é encontrado ( ;
deve ser escapado \;
ou ";"
, ou o shell pode expandi-lo).
-execdir
irá executar o comando tendo a pasta do arquivo como seu "diretório de trabalho" e é preferível em vez de -exec
, verifique abaixo.
A -type
documentação da opção:
-tipo c
O arquivo é do tipo c:
b: bloco (bufferizado) especial
c: caractere (sem buffer) especial
d: diretório
p: tubo nomeado (FIFO)
f: arquivo normal
l: link simbólico; isso nunca é verdade se a opção -L ou a opção -follow estiver em vigor, a menos que o link simbólico seja quebrado. Se você quiser procurar links simbólicos quando -L estiver em vigor, use -xtype.
S: soquete
D: porta (Solaris)
A -not
documentação da opção:
!expressão
Verdadeiro se expr for falso. Esse caractere também normalmente precisará de proteção contra interpretação pelo shell.
-nãoexpressão
Igual a ! expr, mas não é compatível com POSIX.
A -execdir
documentação da opção:
-execcomando;
Executarcomando;verdadeiro se o status 0 for retornado. Todos os argumentos a seguir para encontrar são considerados argumentos para o comando até que um argumento consista em ';' é encontrado. A string '{}' é substituída pelo nome do arquivo atual que está sendo processado em todos os lugares em que ocorre nos argumentos do comando [...]. Ambas as construções podem precisar ser escapadas (com um '\') ou entre aspas para protegê-las da expansão pelo shell. O comando especificado é executado uma vez para cada arquivo correspondente. O comando é executado no diretório inicial.Existem problemas de segurança inevitáveis envolvendo o uso da ação -exec; você deve usar a opção -execdir.
-execdircomando;
Como -exec, mas o especificadoo comando é executado a partir do subdiretório que contém o arquivo correspondente, que normalmente não é o diretório no qual você iniciou o find. Este é um método muito mais seguro para invocar comandos, pois evita condições de corrida durante a resolução dos caminhos para os arquivos correspondentes. [...] Se você usar esta opção, você deve garantir que sua variável de ambiente $PATH não faça referência a '.'; caso contrário, um invasor poderá executar qualquer comando que desejar, deixando um arquivo com nome apropriado em um diretório no qual você executará -execdir. O mesmo se aplica a entradas em $PATH vazias ou que não sejam nomes de diretório absolutos.