recibido disputa articulo perl shell unix find

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 una stat normal. Para obtener información mucho más detallada, consulte la documentación para stat .

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 o lstat ) recibe el lstat de archivo especial que consiste en un subrayado solitario, entonces se usa la estructura estadística de la prueba de archivo anterior (u operador stat ), guardando una llamada al sistema. (Esto no funciona con -t , y debe recordar que lstat 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 llamada lstat , -T y -B lo restablecerán con los resultados de stat _ ). 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.