2012-03-01 11 views
6

Supongamos que crea algunos enlaces simbólicos de Windows, como en:eliminar enlaces simbólicos de Windows en una secuencia de comandos perl?

rd /s /q source withlink linkdir 
mkdir source 
mkdir withlink 
echo blah > source/myfile 
cd withlink 
touch blah 
mklink mylink ..\source\myfile 
@REM mklink /d linkdir ..\source 
cd .. 

que puede eliminar el directorio que contiene los enlaces simbólicos en la cáscara con

rd /s /q withlink 

tengo la misma tarea que hacer en un script de perl donde actualmente usamos cygwin 'rm -rf'. Desafortunadamente estamos usando cygwin 1.5 y rm y rm -rf no funcionan correctamente en esa versión en los enlaces simbólicos que me gustaría usar (they delete symbolic link contents instead of the symlinks).

si trato:

use File::Path qw(rmtree) ; 
rmtree(['withlink']) ; 

Esto funciona muy bien, siempre y cuando no tengo ningún directorio de enlaces simbólicos (como el que se REM'ed a cabo en la secuencia de crear-la-links arriba) y luego de Perl rmtree termina comportándose como cygwin, y termino con el contenido del directorio de mi directorio original eliminado.

¿Alguien tiene una sugerencia de un método alternativo de eliminación de directorio perl recursivo que podría utilizar. Pensé en sólo una llamada shell:

system("rd /s /q withlink") ; 

pero esto requiere que probar la plataforma y tienen diferentes códigos de Perl para Windows y Unix.

EDIT: Tenga en cuenta que, a diferencia de Unix, desvincular() no funciona para eliminar un enlace simbólico al directorio, al menos con v5.6.0 Perl, que es lo que nuestro sistema de construcción está utilizando actualmente. Sin embargo, rmdir() funciona para eliminar un enlace simbólico de directorio de Windows.

+0

Si intenta ... ¿qué? –

+0

lo siento, edité mi título ligeramente mientras aún estaba haciendo mi pregunta, y envié la pregunta de forma prematura y accidental en un estado incompleto. –

+0

¡Gracias por la actualización! –

Respuesta

0

Debería usar unlink("FILE_FOO"); llamada en script perl. Es portátil.

+0

No, ni desvincular ni rmdir funcionan correctamente con un directorio de enlaces simbólicos. Debería haberlo mencionado en mi descripción del problema. –

+0

corrección. unlink no funciona con los enlaces simbólicos de directorio en Windows (a diferencia de unlink en Unix). rmdir() parece ser necesario para un enlace simbólico de directorio de Windows. –

2

Debe usar rmdir para eliminar los enlaces simbólicos de directorios y los puntos de unión en Windows y debe simplemente usar unlink para eliminar los enlaces simbólicos a los archivos. La razón es que un enlace simbólico de directorio y punto de unión es realmente un directorio vacío con metadatos adicionales del sistema de archivos (llamado datos de punto de reanálisis). De manera similar, los enlaces simbólicos a archivos son archivos vacíos con datos de punto de reanálisis. Tal directorio o archivo se llama punto de reanálisis cuando lee la documentación de Microsoft NTFS. El tipo de punto de análisis se determina por el llamado punto de reanálisis TAG. Hay etiquetas de dos puntos de análisis visible para los usuarios como 'enlaces':

  1. IO_REPARSE_TAG_SYMLINK - Si se establece en un directorio - es un enlace simbólico a un directorio, si se establece en el archivo - es un enlace simbólico un archivo
  2. IO_REPARSE_TAG_MOUNT_POINT - solo se puede configurar en un directorio, se denomina "punto de unión". Podría ser un "enlace" a otro directorio, pero podría ser un "punto de montaje" para todo el dispositivo (volumen).

Para resumir:

  1. Se quita los enlaces simbólicos a los directorios y los puntos de unión como si fueran vacías directorios (de hecho si revisas atributos de una cosa tal, tiene dos: FILE_ATTRIBUTE_DIRECTORY y FILE_ATTRIBUTE_REPARSE_POINT) .
  2. Elimina los enlaces simbólicos a los archivos como si fueran archivos.
  3. En ambos casos mencionados anteriormente, solo se elimina el enlace/unión (no el destino).
  4. Para averiguar si el archivo/carpeta es un enlace (de todo tipo): si se llama GetFileAttributes o GetFileInformationByHandle o FindNextFile continuación attributtes contienen FILE_ATTRIBUTE_REPARSE_POINT bandera (ej .: WIN32_FIND_DATA::dwFileAttributes). Si se trata de un enlace a un directorio, también contiene el indicador FILE_ATTRIBUTE_DIRECTORY (ver 1.).

Espero que ayude.

+0

Eso es consistente con lo que encontré, pero gracias por la información. ¿Conoce una forma de consultar estas etiquetas del sistema de archivos dentro de Perl, o tendría que escribir el código C que llama a FindFirstFile (y sus amigos)? –

+0

Sí, tengo código C++ que puede consultar/establecer/eliminar estas etiquetas de reanálisis que funcionan desde Windows XP y superiores. El código es demasiado largo y complicado para publicarlo aquí, requeriría escribir un artículo completo al respecto. Se basa principalmente en mis experimentos y leer MSDN. A partir de Vista, puede usar la función 'CreateSymbolicLink' para crear enlaces simbólicos o' CreateHardLink' (XP y superior) para crear enlaces duros. Actualicé mi respuesta - cómo detectar enlaces/uniones - vea arriba. – sirgeorge

Cuestiones relacionadas