carpeta de contenido de copia de diferencia entre /. y / * en linux

8

para copiar contenidos de una carpeta que he leído, el uso es:

cp -rfva ../foldersource/. ./

pero esto también funciona

cp -rfva ../foldersource/* ./

¿hay alguna diferencia?

por ejemplo si quiero eliminar un contenido de una carpeta con. :

rm -rf ../foldersource/.

me sale el error:

rm:  rejet delete folder '.' or '..':

pero con asterisco está bien

rm -rf ../foldersource/*

Entonces, ¿el asterisco es una mejor opción que funciona en cualquier lugar?

stackdave
fuente

Respuestas:

10

Hay una diferencia fundamental entre estas dos formas de argumento. Y es importante entender lo que está sucediendo.

Con ../foldersource/.el argumento se pasa sin cambios al comando, ya sea cpo no rmo algo más. Depende del comando si ese punto final tiene una semántica especial o única diferente de la convención estándar de Unix de simplemente señalar el directorio en el que reside; ambos rmy cpparecen tratarlo como un caso especial.

Con ../foldersource/*el argumento, el shell primero lo expande antes de que el comando se ejecute y pase cualquier argumento. Por lo tanto, rmnunca ve ../foldersource/*; ve la versión ampliada ../foldersource/file1.ext ../foldersource/file2.ext ../foldersource/childfolder1y así sucesivamente. Esto es importante porque los sistemas operativos limitan la cantidad de argumentos que se pueden pasar a un comando, generalmente solo unos pocos cientos.

eestrada
fuente
44
It's up to the command whether that trailing dot makes any senseUm, el punto siempre enlaza con el directorio que lo contiene, por lo ../foldersource/.que no debería ser diferente de indicar ./foldersource/y, de hecho, es solo una forma redundante de decir lo mismo. Ningún comando intenta "dar sentido" a punto o doble punto, ya que estos son estándar en los sistemas de archivos Linux / Unix. rmsimplemente rechaza eliminar el directorio de trabajo actual como se jimmijindica en su respuesta. Además, tenga en cuenta que está utilizando ./en todos sus ejemplos mientras OP tiene ../allí. Algo de una (gran) diferencia.
Sergiy Kolodyazhnyy
"cp -rfva ../foldersource/. ./" es equivalente a "cp -rfva ../foldersource ./", quiero copiar el contenido de la carpeta de origen, pero no la raíz de la carpeta
stackdave
1
@Stackdave no, cp -rfva ../foldersource/. ./ NO es equivalente a cp -rfva ../foldersource ./ . El seguimiento /.es significativo
roaima
2
Si bien lo que dice esta respuesta es correcto, le falta una diferencia muy importante como se menciona en la respuesta de @ roaima: la variante / * no (generalmente) copia archivos o directorios que comienzan con.
Adam
@SergiyKolodyazhnyy Tienes razón; Esta .es una convención estándar en Unix para denotar la corriente directamente. Además, gracias por señalar que había usado ./en mis ejemplos cuando debería haber usado ../; Lo arreglaré Usted es incorrecto acerca de si los comandos "tienen sentido" del punto final; como señala el OP (y he experimentado con cp) ambos rmy se cpcomportan de manera diferente cuando hay un final .presente. Debería haber escrito algo como "depende del comando si el punto final tiene una semántica especial o única". Cambiaré mi respuesta por claridad.
eestrada
10

Cuando copia usando cp -a source/* target/está copiando la mayoría de los archivos y directorios de sourcea target. Específicamente, los elementos que están excluidos probablemente serán archivos que comienzan con un punto ( .) en el nivel superior de source.

Considere estos archivos (o directorios) en source

apple        # will be copied
banana/      # will be copied, as will all its contents
.cherry      # will not be copied

Cuando copia usando cp -a source/. target/está copiando todo el contenido de source, incluidos los elementos que comienzan con un punto ( .) entarget

Considere estos archivos (o directorios) en source

apple        # will be copied
banana/      # will be copied, as will all its contents
.cherry      # will be copied

Si está usando bash, zshpuede usar la dotglobopción para cambiar el significado de *modo que incluya archivos y directorios que comiencen con un punto ( yashtambién tiene una dotglobopción; sin embargo, luego incluye .y ..en expansiones globales que limitan su usabilidad. Ver también FIGNORE='@(.|..)'en ksh93).

Curiosamente, cp -a source/. target/se garantiza que nunca creará el componente target/source. (Por otro lado, cp -a source target/hará una de dos cosas dependiendo de si targetya existe o no . Consulte Cómo copiar una carpeta de forma recursiva de forma idempotente usando cp para obtener más detalles).


Cuando elimina usando rm -rf source/*está eliminando los archivos y directorios sourceque no comienzan con un punto ( .). Sujeto a la dotglobconfiguración que ya he mencionado. No eliminará el directorio en sourcesí.

Cuando intente eliminarlo rm -rf source/., fallará, como ya lo han explicado otros , porque POSIX prohíbe la eliminación de una ruta cuyo último componente es .o ... El equivalente más cercano es rm -rf source, que eliminará el sourcedirectorio y todo su contenido, independientemente de si comienzan o no con un punto ( .).

roaima
fuente
1
Consulte también ¿'rm. *' Alguna vez elimina el directorio principal? sobre rm -rf .su defecto .
Stéphane Chazelas
7

No puede hacerlo rm -rf ../foldersource/.porque rmno permite esto, como se indica explícitamente en el manual:

Cualquier intento de eliminar un archivo cuyo último componente de nombre de archivo es '.' o '..' se rechaza sin ninguna solicitud, como lo ordena POSIX.

y en el manual POSIX man 1p rmvemos:

Si cualquiera de los archivos dot o dot-dot se especifican como la porción de nombre base de un operando (es decir, el componente final del nombre de ruta) o si un operando se resuelve en el directorio raíz, rm escribirá un mensaje de diagnóstico de error estándar y no hará nada más con tales operandos.

jimmij
fuente