2012-01-31 13 views
7
if (-e "$ENV{MYHOME}/link") { 
    system("rm $ENV{MYHOME}/link"); 
} 

Este es el código que se utiliza para verificar si existe un enlace simbólico y eliminarlo si lo hace.Cómo verificar y eliminar un enlace simbólico, si existe, usando Perl?

Estoy siguiendo un error donde este código no funciona. No he podido averiguarlo a partir de ahora, pero lo que está sucediendo es que este código no puede eliminar el enlace simbólico, lo que da como resultado un error 'Archivo existe' en la línea.

¿Quería comprobar si hay alguna falla fundamental con esta técnica? También leí acerca de http://perldoc.perl.org/functions/unlink.html, pero me gustaría saber si el enfoque actual no se recomienda debido a alguna razón.

Respuesta

19

sólo tiene que utilizar:

if (-l "$ENV{MYHOME}/link") { 
    unlink "$ENV{MYHOME}/link" 
     or die "Failed to remove file $ENV{MYHOME}/link: $!\n"; 
} 

Si la falla de desenlace, que va di porqué. El -l pregunta si el objetivo es un enlace. El -e pregunta si el archivo existe. Si su enlace es a un archivo inexistente, devolverá falso y su código no eliminará el enlace.

+0

¿'-l' verifica si el archivo es enlace simbólico o enlace físico? ¿o ambos? – mask8

+0

@ mask8 - '-l' devuelve verdadero si la ruta es un enlace simbólico. Los archivos vinculados duros aparecen como archivos regulares, donde la única diferencia es su recuento de enlaces (el 'st_nlink' de la estadística) es mayor que uno. Los directorios no se pueden enlazar en Linux/Unix. – unpythonic

0

Su código solo tendrá los permisos del usuario bajo el que se ejecuta. ¿Es posible que el enlace simbólico sea propiedad de otro usuario y no se pueda escribir?

Además, siempre existe la posibilidad de que $ ENV {} MYHOME no contiene lo que usted cree ...

+0

Sí, esa es una posibilidad que estoy buscando, esto es posible pero no debería suceder. – Lazer

+0

BTW, unlink es mucho más eficiente ya que no está bifurcando otro proceso. Además, no sé qué tan cargado está tu sistema o con qué frecuencia ocurre esto, pero al forzar una llamada al sistema como esa, se abre la posibilidad de que algo como tu tabla pid esté llena y no se pueda bifurcar. –

0

respectivos sistemas operativos tienen su propio errno.h. Yo usaría Errno.pm para manejar cada error.

use Errno; 
use File::Spec; 

my $dir = File::Spec->catfile($ENV{MYHOME}, 'link'); 

if (!unlink $dir) { 
    if ($! == Errno::ENOENT) { 
     die "Failed to remove '$dir'. File doesn't exist:$!"; 
    } 
} 
+0

¿Hacia atrás? Por qué ignorar los errores "reales" y solo imprimir el que no importa. – ikegami

+2

PS - 'use Errno; if ($! == Errno :: ENOENT) 'también se puede escribir' if ($! {ENOENT}) '. – ikegami

+0

Gracias por su respuesta, ikegami. Los errores reales son sensibles a la configuración regional y no son para el manejo. De todos modos, no sabía el idioma '%!'. +1 – ernix

Cuestiones relacionadas