Problema con el comando de instalación para copiar un directorio completo

16

Así que tengo un repositorio con algunos de mis archivos de configuración y estoy tratando de crear uno makefilepara instalarlos en el homedir. El problema que tengo es que cuando ejecuto el siguiente comando directamente en bash

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

aparentemente no pasa nada mientras

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

Funciona según lo previsto.

¿Por qué no funciona la primera solución (más fácil y limpia)?

nathdwek
fuente
Acabo de usar cp con -r. Realmente no entiendo por qué instalar no tiene la opción -r como tiene cp.
ibrahim

Respuestas:

7

De un vistazo a la página del manual , parece que installno hará lo que quiere.

De hecho, la sección Sinopsis indica un uso del formulario:

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

y luego, la página del manual dice:

-d, --directory
trata todos los argumentos como nombres de directorio; crear todos los componentes de los directorios especificados

Entonces, me parece que el objetivo de esta opción es poder instalar una estructura de directorio complicada (pero vacía) a la mkdir -p ....

Puedes lograr lo que quieres con un bucle:

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

O, si hay muchos niveles por debajo /path/to/DotFiles/dir, puede usar find:

find /path/to/DotFiles/dir/ -type f -exec 'install -m 755 "{}" ~/' +
Joseph R.
fuente
Crear todos los componentes de los directorios especificados = ¿Crear subdirecciones pero no los archivos?
nathdwek
@nathdwek Derecha. De esta forma, puede crear una estructura de directorio compleja (esqueleto) debajo de, digamos, su directorio de inicio usandoinstall -m 755 -d ~/foo/bar/baz
Joseph R.
1
-exec 'install -m 755 "{}" ~/' +no va a funcionar, al menos no en ciertas versiones (¿todas? ¿La mayoría?) de Linux. Puede funcionar en OSX o algo así. Usar algo como esto es bastante sencillo si desea un elemento de línea: 1. cree directorios recursivos: for d in $(find . -type d); do install -d --mode 755 "$d" "../install-test/$d"; done2. cree archivos recursivos:for f in $(find . -type f); do install -D --mode 644 "$f" ../install-test/; done
Josh M.
6

A partir de la respuesta de @Joseph R., esta es mi solución para que funcione con find, ya que no pude hacer que su comando funcione. (No creo que lo haga, debido a las reglas que se aplican a \+: no puede haber nada después del{} elemento). (No pude comentar. Todo este párrafo se puede eliminar realmente).

Para copiar todos los archivos en el mismo directorio exacto (aquí target/directory):

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

-D no es obligatorio aquí, solo creará los directorios no existentes para el destino.

Para copiar una jerarquía de directorios completa y sus archivos (esto omitirá los directorios vacíos) comenzando desde donde se encuentra actualmente:

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

Como se dijo, esto recreará el árbol a partir de $PWD. Además, si necesita copiar el directorio vacío, en podría encontrar una manera usando el -type dde findyinstall -d .

Entonces, para copiar el árbol, comenzando desde un directorio que no es $PWD:

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

Observe cómo parent/directoryno se copia.

Extra

Para aquellos que usan shell/fish, aquí está la línea que hace lo mismo:

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