Problema com o comando install para copiar um diretório inteiro

16

Então, eu tenho um repositório com alguns dos meus arquivos de configuração e estou tentando criar um makefilepara instalá-los no homedir. O problema que tenho é que, quando executo o seguinte comando diretamente no bash

install -m 755 -d ~/path/to/dotfilesDir/ ~/

aparentemente nada acontece enquanto

install -m 755 ~/path/to/dotfilesDir/{file1,file2,...} ~/

funciona como pretendido.

Por que a primeira solução (mais fácil e limpa) não funciona?

nathdwek
fonte
Eu apenas usei cp com -r. Eu realmente não entendo por que instalar não tem a opção -r como o cp tem.
Ibrahim

Respostas:

7

De uma olhada na página de manual , parece que installnão fará o que você deseja.

De fato, a seção Sinopse indica um uso do formulário:

install [OPTION]... -d DIRECTORY...

e mais tarde, a página de manual diz:

-d, --directory
trata todos os argumentos como nomes de diretório; crie todos os componentes dos diretórios especificados

Portanto, parece-me que o objetivo desta opção é poder instalar à la uma estrutura de diretórios complicada (mas vazia) mkdir -p ....

Você pode realizar o que deseja com um loop:

for file in /path/to/DotFiles/dir/*;do
    install -m 755 "$file" ~/
done

Ou, se houver muitos níveis abaixo /path/to/DotFiles/dir, você pode usar find:

find /path/to/DotFiles/dir/ -type f -exec 'install -m 755 "{}" ~/' +
Joseph R.
fonte
Criar todos os componentes dos diretórios especificados = Criar os subdiretórios, mas não os arquivos?
Nathdwek 1/11/14
@nathdwek Certo. Desta forma, você pode criar um complexo (esqueleto) estrutura de diretórios em, digamos, seu diretório home usandoinstall -m 755 -d ~/foo/bar/baz
Joseph R.
1
-exec 'install -m 755 "{}" ~/' +não vai funcionar, pelo menos não na versão certa (tudo? mais?) do linux. Pode funcionar no OSX ou algo assim. Usando algo como isto é bastante simples se você quiser um oneliner: 1. criar diretórios recursivo: for d in $(find . -type d); do install -d --mode 755 "$d" "../install-test/$d"; done2. criar arquivos recursiva:for f in $(find . -type f); do install -D --mode 644 "$f" ../install-test/; done
Josh M.
6

A partir da resposta de Joseph R., esta é minha solução para fazê-lo funcionar com o find, pois eu não poderia fazer o comando dele funcionar. (Acho que não, devido às regras aplicáveis \+: não pode haver nada após o{} elemento.) (Não pude comentar. Este parágrafo inteiro pode realmente ser removido.)

Para copiar todos os arquivos no mesmo diretório (aqui target/directory):

find directory/to/copy -type f -exec install -Dm 755 "{}" "target/directory" \;

-D não é obrigatório aqui, apenas criará os diretórios inexistentes para o destino.

Para copiar uma hierarquia de diretórios inteira e seus arquivos (isso omitirá diretórios vazios) a partir de onde você está:

find directory/tree/to/copy -type f -exec install -Dm 755 "{}" "target/directory/{}" \;

Como dito, isso recriará a árvore a partir de $PWD. Além disso, se você precisar copiar o diretório vazio, poderá encontrar uma maneira de usar o -type dde findeinstall -d .

Portanto, para copiar a árvore, iniciando em um diretório que não seja $PWD:

(cd parent/directory && find directory/tree/to/copy -type f -exec install -Dm 755 "{}" "target/directory/{}" \;)

Observe como parent/directorynão é copiado.

Extra

Para quem usa shell/fish, aqui está a linha que faz o mesmo:

fish -c 'cd parent/directory; and find directory/tree/to/copy -type f -exec install -Dm 755 "{}" "target/directory/{}" \\;'
Vrakfall
fonte