disputa - El operador de prueba de archivo de Perl-f devuelve verdadero para enlaces simbólicos
disputa paypal articulo no recibido (3)
Soluciones rápidas
$ ls | perl -lne ''print if stat && -f _'' 1 2 3 4 5 file1 $ ls | perl -lne ''print if lstat && -f _'' file1
Enlaces simbólicos y encontrar
De forma predeterminada, GNU nunca find
desreferencias ni sigue enlaces simbólicos, pero la documentación de find
describe los modificadores que modifican esta política.
Las opciones que controlan el comportamiento de find con respecto a los enlaces son las siguientes:
-P
find
no desreferencia enlaces simbólicos en absoluto. Este es el comportamiento estándar. Esta opción debe especificarse antes de cualquiera de los nombres de archivo en la línea de comando.
-H
find
no desreferencia enlaces simbólicos (excepto en el caso de los nombres de archivo en la línea de comando, que se desreferencia). Si no se puede desreferenciar un enlace simbólico, se utiliza la información para el enlace simbólico en sí. Esta opción debe especificarse antes de cualquiera de los nombres de archivo en la línea de comando.
-L
Busque referencias de enlaces simbólicos donde sea posible, y cuando esto no sea posible, use las propiedades del enlace simbólico en sí. Esta opción debe especificarse antes de cualquiera de los nombres de archivo en la línea de comando. El uso de esta opción también implica el mismo comportamiento que la opción-noleaf
. Si luego usa las opciones-H
o-P
, esto no se desactiva-noleaf
.
-follow
Esta opción forma parte de la "expresión" y debe especificarse después de los nombres de los archivos, pero equivale a-L
. La opción-follow
afecta solo a aquellas pruebas que aparecen después de ella en la línea de comando. Esta opción está en desuso. Donde sea posible, debes usar-L
lugar.
Conversión de comandos de búsqueda a Perl
La distribución estándar viene con una utilidad find2perl
que es compatible con find
de sistemas Unix más antiguos.
$ find2perl . -type f | perl ./file1
En su lugar, podríamos solicitar archivos que sean simples o enlaces a archivos simples.
$ find2perl . -follow -type f | perl ./1 ./2 ./3 ./4 ./5 ./file1
En el código que genera find2perl
, el sub wanted
defecto para find
desde el módulo File :: Find es
sub wanted {
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
-f _
&& print("$name/n");
}
pero con -follow
, obtenemos
sub wanted {
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) = stat($_)) &&
-f _
&& print("$name/n");
}
Tenga en cuenta que la única diferencia es si las llamadas wanted
stat
o lstat
, donde esta última está documentada como
lstat EXPR
lstat
Hace lo mismo que la función
stat
(incluida la configuración del identificador de archivo_
especial), pero representa un vínculo simbólico en lugar del archivo al que apunta el enlace simbólico. Si los enlaces simbólicos no se implementan en su sistema, se realiza unastat
normal. Para obtener información mucho más detallada, consulte la documentación parastat
.Si se omite EXPR , las estadísticas
$_
.
Como muestra el resultado de la muestra de find2perl
, puede expresar su intención con el operador de prueba de archivo pero ser preciso acerca de la semántica de los enlaces simbólicos con su elección de stat
versus lstat
.
Esa divertida _
ficha
El _
al final de las soluciones rápidas anteriores es el lstat
especial que menciona la documentación de lstat
. lstat
una copia del resultado más reciente de stat
o lstat
como una forma de evitar tener que realizar reiteradamente esas costosas llamadas al sistema. Los operadores de Filetest como -f
, -r
, -e
y -l
también llenan este búfer:
Si alguna de las pruebas de archivos (o el operador
stat
olstat
) recibe ellstat
de archivo especial que consiste en un subrayado solitario, entonces se usa la estructura estadística de la prueba de archivo anterior (u operadorstat
), guardando una llamada al sistema. (Esto no funciona con-t
, y debe recordar quelstat
y-l
dejan valores en la estructura de estadísticas para el enlace simbólico, no en el archivo real.) (También, si el buffer de estadísticas fue llenado por una llamadalstat
,-T
y-B
lo restablecerán con los resultados destat _
). Ejemplo:
print "Can do./n" if -r $a || -w _ || -x _; stat($filename); print "Readable/n" if -r _; print "Writable/n" if -w _; print "Executable/n" if -x _;
Solía pensar que -f
probado un archivo para ver si era un archivo normal, y nada más. Pero Perl parece estar comportándose de manera diferente. Busqué la entrada del perldoc y dice:
-f File is a plain file.
Supongamos que tengo un directorio que tiene un archivo llamado file1
, y 5 enlaces simbólicos 1 2 3 4 5
, cada uno de los cuales apunta al file1
, así:
-rw-r--r-- file1
lrwxrwxrwx 1 -> file1
lrwxrwxrwx 2 -> file1
lrwxrwxrwx 3 -> file1
lrwxrwxrwx 4 -> file1
lrwxrwxrwx 5 -> file1
drwxr-xr-x ../
drwxr-xr-x ./
Si ejecuto find en este directorio usando -type f
filter, da salida como se esperaba:
% find . -type f
./file1
Pero cuando ejecuto un script de Perl usando el operador -f, da el siguiente resultado:
% ls | perl -e ''while(<>) { chomp; print "$_/n" if -f $_ }''
1
2
3
4
5
file1
Cuando agregue la prueba de -l
también, funciona como se esperaba:
% ls | perl -e ''while(<>) { chomp; print "$_/n" if -f $_ and not -l $_}''
file1
¿Los enlaces simbólicos también se consideran archivos sin formato? Si es así, ¿por qué? ¿Mi uso de la prueba de archivo es incorrecto?
Por defecto, todos los operadores de prueba de archivos (aparte de -l
) usan stat()
para probar, lo que significa que son transparentes para los enlaces simbólicos. -f
devuelve verdadero en un archivo normal o un enlace simbólico a un archivo normal.
Para usar lstat()
lugar, primero debe lstat
luego usar las pruebas de archivo en el lstat
archivo _
especial, que almacena los resultados de la operación stat
o lstat
más reciente.
perl -e ''while(<>) { chomp; print "$_/n" if lstat $_ && -f _ }''
Cuando prueba un enlace simbólico, la prueba se lleva a cabo en lo que apunta el enlace simbólico a menos que use la prueba -l
enlace simbólico.
Esto es paralelo a las lstat
sistema stat
y lstat
Linux que se comportan de manera similar. Es decir, si stat
un enlace simbólico, obtendrá el resultado para el objetivo del enlace simbólico, mientras que si lstat
el enlace simbólico, obtendrá el resultado del enlace simbólico. Este comportamiento es intencional para que los programas ingenuos no tengan que preocuparse por los enlaces simbólicos, y los enlaces simbólicos funcionarán como se esperaba.
Debería encontrar que si su enlace simbólico hace referencia a un directorio, la prueba -f
es falsa y la prueba -d
es verdadera.