Mi pregunta es ¿por qué es necesario usar el -r
indicador (recursivo) al hacer una copia de un directorio? Es decir, por qué hacer esto:
$ cp -r dir1 copyDir1
¿Cuándo no querría este comportamiento al copiar un directorio?
¿No es una copia recursiva de un directorio realmente el comportamiento "predeterminado"; El comportamiento que queremos casi todo el tiempo?
Parece que esta es una bandera superflua.
rm
Respuestas:
En la forma en que funcionan los sistemas de archivos, un directorio no es en realidad una carpeta que contiene archivos, sino que un directorio es un archivo que contiene punteros de inodo a archivos "secundarios" conectados a él. Es decir, desde la perspectiva del sistema de archivos, un archivo es un archivo, pero un directorio es solo un archivo que contiene una lista de archivos conectados.
Entonces, desde la perspectiva de la línea de comando, haciendo esto:
Básicamente significaría copiar el archivo llamado
dir1
a un nuevo archivo llamadocopyDir1
. Y en lo que respecta al sistema dedir1
archivos, de todos modos es solo un archivo; el hecho de que sea un "directorio" solo será evidente cuando el sistema de archivos realmente verifiquedir1
qué es realmente ese montón de bits.La
-r
bandera le dice al sistema de archivos que despliegue recursivamente el árbol de archivos / directorios y copie cualquier contenido que pueda ser un "hijo" de ese archivo a un nuevo lugar.Ahora, por qué eso puede parecer superfluo o redundante, esto realmente se reduce a métodos históricos para tratar con sistemas de archivos. Además de crear un sistema que esté a salvo de todo tipo de errores relacionados con el usuario; accidental así como intencional.
Es decir, supongamos que tiene un
~/bin
archivo en su directorio de inicio que desea copiar pero que accidentalmente dejó de lado,~
porque es un ser humano y comete errores, así que es/bin
así:Con la "red de seguridad" de
/bin
ser un directorio combinado con la necesidad del-r
indicador, evitará copiar accidentalmente toda la raíz binaria del sistema en el que se encuentra en su directorio de inicio. Si esa red de seguridad no existiera, ocurriría un desastre menor, o posiblemente mayor.La lógica aquí es que en los días previos a las GUI (interfaces gráficas de usuario) las convenciones lógicas / de comportamiento deben establecerse para evitar que el usuario cree contratiempos que potencialmente pueden matar un sistema. Y usar la
-r
bandera ahora es uno de ellos.Si eso parece superfluo, entonces no necesita buscar más allá del sistema GUI moderno que uno puede colocar por encima de los sistemas de archivos Linux. Una GUI aborda problemas básicos del usuario como este al permitir arrastrar y soltar archivos y directorios con facilidad.
Pero en el caso de las interfaces basadas en texto, gran parte de la "experiencia del usuario" dentro de ese mundo es básicamente un bache de camino lógico y basado en huerística que ayuda a mantener al usuario bajo control para evitar posibles desastres.
De manera similar, esta es la razón por la cual los sistemas de archivos Linux / Unix no tienen
777
permisos ysudo
derechos establecidos de manera predeterminada y cómo los administradores de sistemas reales hacen una mueca cuando un usuario establece777
permisos o otorgasudo
derechos a todos . Estas son las cosas básicas que uno hace para garantizar que el sistema sea estable y lo más "a prueba del usuario" posible; cualquiera que se apresure a cortocircuitar esas convenciones probablemente causará daños a su sistema sin siquiera saberlo.INFORMACIÓN ADICIONAL: Otra respuesta aquí en el sitio Unix Stack Exchange da una buena explicación de por qué una copia no recursiva de un directorio es problemática; El énfasis es mío.
Entonces, si un directorio es realmente un archivo con elementos de inodo dentro de él, hacer una copia directa de ese archivo sería el equivalente de cómo funcionaría un enlace duro. Que no es lo que nadie quiere.
fuente
cp -r /bin
tan fácilmente comocp-r ~/bin
. La bandera en sí misma no evita errores ni necesariamente hace que nadie sea más cuidadoso. Si desea evitar errores, el comando cp podría mirar fácilmente el nodo en cuestión y proporcionar un mensaje, algo así como "Este es un directorio, ¿desea copiar todo el contenido en la ubicación especificada (y /norte)?" Eso sería una red de seguridad . Requerir -r para directorios mantiene la hinchazón de código más baja que cualquier otra cosa.Es muy cierto que este es el comportamiento que queremos casi todo el tiempo. Sin embargo, esto no significa necesariamente que copiar de forma recursiva sea el comportamiento predeterminado.
Creo que las razones
cp
actúan como si tuviera raíces en la filosofía de Unix . Unix favorece los programas que hacen una cosa y lo hacen bien , así como los programas que son simples tanto en la interfaz como en la implementación (a veces llamado peor es mejor ).La pieza clave del rompecabezas aquí es darse cuenta de que
cp
no copia directorios:cp
copia archivos (y solo archivos). Si desea copiar un directorio, secp
llama a sí mismo de forma recursiva , para copiar los archivos en cada directorio.Por supuesto, la diferencia entre "copiar directorios" y "copiar archivos recursivamente" no es absolutamente nada, desde la perspectiva del usuario, pero tener esta interfaz ayuda a que la implementación siga siendo simple .
Si
cp
pudo copiar directorios, pronto estaría tentado de agregar más funciones que solo tengan sentido para los directorios; por ejemplo, es posible que desee copiar solo los nombres de archivo que terminaron en.sh
. Inevitablemente, esto conduce a la distorsión de la hinchazón y las características a las que estamos acostumbrados en otros sistemas operativos, lo que hace que el software sea lento, complejo y propenso a errores.Otra ventaja es que tener
-r
también ayuda al usuario a comprender lo que realmente está sucediendo debajo de la interfaz. Un buen efecto secundario de esto es que aprender el concepto de operación recursiva le ahorrará algo de trabajo cuando aprenda sobre otras herramientas que lo soportan (comogrep
, por ejemplo)Algunas personas seguramente le dirán que exponer los detalles de implementación al usuario es malo , y que tener más funciones es bueno . Mi intención aquí es simplemente explicar la lógica de este comportamiento, por lo que no intentaré discutir de ninguna manera.
fuente
Las interacciones con los directorios aseguran que sepa que está interactuando con un directorio y NO con un solo archivo.
Por ejemplo:
Entonces, si desea copiar con éxito una carpeta, ya que implica tanto la carpeta como los objetos relacionados con la referencia de la carpeta, debe tratarla como si fuera una colección de archivos:
fuente
La consecuencia de cambiar el valor predeterminado sería que miles de scripts de shell se romperían. Esto lleva a los requisitos POSIX y SUS para el comportamiento predeterminado bien conocido.
La razón es el desarrollo histórico de los comandos cp, ln y mv (todos los mismos binarios en la mayoría de los sistemas UNIX antiguos) en varias ramas UNIX. Cuando
-r
apareció (tempranocp
no tenía una opción para copiar directorios; aquí hay una página de manual de cp temprana sin-r
o-R
), hubo varias diferencias en el manejo de archivos especiales, enlaces simbólicos y otros caprichos del sistema de archivos.De The Open Group Base Especificaciones Número 7 :
De hecho, todavía verá que algunas personas usan regularmente:
Porque no confían en que la
cp -r
implementación sea lo que están acostumbrados en una máquina arbitraria; O porque quieren eltar
comportamiento.fuente
Puede ser una interfaz de usuario subóptima hoy en día, pero fue una decisión tomada en algún momento alrededor de 1970 durante el diseño de UNIX cuando el disco era considerablemente más caro. Millones de scripts de shell dependen de que funcione de esa manera, y es demasiado tarde para cambiarlo.
Vea este artículo para la información de diseño original.
fuente
Una clara ventaja del
-r
indicador es que puedecp * /target/dir
copiar solo todos los archivos del directorio de origen en el directorio de destino, omitiendo (aunque con una advertencia) todos los directorios contenidos en él.cp -r * /target/dir
copiaría todo en su lugar, incluidos los subdirectorios.fuente
Necesita este indicador solo cuando
cp
es un comando para copiar archivos y directorios y no solo directorios.Si hubiera un comando especial para la copia de directorios, el comportamiento "predeterminado" seguramente sería una copia recursiva.
fuente
mkdir
?Como otros han mencionado, un directorio es básicamente otro tipo de archivo (a diferencia de un archivo normal), que generalmente "contiene" (apunta a) otros archivos. Podría contener subdirectorios, para lo cual se aplica lo mismo ...
Entonces, si está copiando un directorio (perspectiva del usuario), realmente está copiando un montón de archivos (perspectiva del sistema de archivos) (archivos normales, archivos de directorio, enlaces simbólicos, ...) y para cada archivo de directorio, está repitiendo eso recursivamente proceso. Como copiar un directorio es, por definición, un proceso recursivo, se llama el argumento de cp
--recursive
.Por supuesto, es muy fácil crear un acceso directo de comando en su entorno de usuario (póngalo en su archivo .profile / .bashrc para que esté disponible permanentemente):
O tal vez mejor:
De esa manera, puede copiar un directorio utilizando
cpa dir1 copyDir1
y no solo imprimirá lo que se está copiando, sino que también aplicará permisos de archivo.Y dado que alguien mencionó que cp podría detectar teóricamente que el archivo fuente es un directorio y preguntar si debería copiarlo recursivamente, aquí hay una sugerencia rápida:
Esto es solo un envoltorio de cp barato. Siempre conserva todos los metadatos (es decir, copia el tiempo de modificación del archivo, copia correctamente los enlaces simbólicos, etc.) y si está intentando copiar un directorio, le pregunta si debe copiarlo (recursivamente).
fuente