¿Por qué falla este script?

Imagen de slap
0 puntos

Hola, estoy realizando un script sencillo que busca una cadena dentro de los ficheros especificados.

El script es este:

#!/bin/bash
#
# Script para buscar un <patrón> en los ficheros regulares
# que coincidan con la <máscara> y se encuentren a partir de <path_inicial>
#
mask=""
if [[ $# -lt 2 || $# -gt 3 ]]
then
        echo "uso: $0 <path_inicial> [<máscara>] <patrón>"
        exit
elif [ $# -eq 3 ]
then
        mask="-name '$2'"
        patt=$3
else
        patt=$2
fi
echo "find $1 $mask -type f -print0 | xargs -0 grep -n" "$patt"
find $1 $mask -type f -print0 | xargs -0 grep -n "$patt"

El parámetro <máscara> es opcional.

Suponiendo que en el directorio . hay dos ficheros que acaban en .txt y contienen cadenaabuscar,

el problema es que cuando lo invoco así:

./busca . '*.txt' cadenaabuscar

la orden find no saca nada.

Sin embargo la línea que saca el echo "find... está bien formada:

find . -name '*.txt' -type f -print0 | xargs -0 grep -n cadenaabuscar

de hecho, si la copio tal cual y la ejecuto, funciona!

¿Donde falla?

Gracias y saludos.
slap

Imagen de joseluis
+1
0
-1

La verdad es que no se me ocurre bien por qué funciona el echo pero la ejecución de la línea no.
Lo que he visto es que si sustituyes

find $1 $mask -type f -print0 | xargs -0 grep -n "$patt"

por

echo "find $1 $mask -type f -print0 | xargs -0 grep -n" "$patt" | bash

parece que funciona.

Debe ser que la sustitución de las variables por su valor se hace de distinta manera en el echo que al invocar el comando.


  • La guia Ubuntu - solución a muchos problemas
  • Google y el buscador de ubuntu-es son tus amigos

Fdo. El forense asesino.

+1
0
-1

Fdo. Forense asesino, Censor fundamentalista, Fustigador de novatos y Patético maleducado

Imagen de sansatan
+1
0
-1

Creo que el problema es el reemplazamiento de la variable mask, que está entre dobles comillas, lo que hace que no interprete -name como un flag. A mi entender no es la mejor solución, pero observa que esto funciona:

#!/bin/bash
#
# Script para buscar un <patrón> en los ficheros regulares
# que coincidan con la <máscara> y se encuentren a partir de <path_inicial>
#
mask=""
if [[ $# -lt 2 || $# -gt 3 ]]
then
echo "uso: $0 <path_inicial> [<máscara>] <patrón>"
exit
elif [ $# -eq 3 ]
then
mask=$2
patt=$3
else
mask="*"
patt=$2
fi
find $1 -name "$mask" -type f -print0 | xargs -0 grep -n "$patt"

--------------------------------------

"Los esfuerzos, cuando se suman, se multiplican" Anónimo

+1
0
-1

--------------------------------------

Un error muy frecuente: Confundir valor y precio.

Imagen de slap
+1
0
-1

Gracias a los dos por las aportaciones ;)

He puesto una consulta en http://savannah.gnu.org/bugs/?group=findutils a ver qué dicen.

Ya os contaré.

Saludos.
slap

+1
0
-1

Saludos.

0000 start out (+FD),A
           ld  BC, +7FFF
           jp 03CB, RAM-CHECK

http://www.injiniero.es

Imagen de slap
+1
0
-1

Me han contestado superrápido:

The problem you have experienced is not a bug in find but is due to
insufficient evaluation of quoted arguments.  This can be seen by using 'sh
-x' to invoke your test script.

 mask="-name '$2'"
 find $1 $mask -type f -print

 $ sh -x ./script '*txt'
 + mask='-name '\''*txt'\'''
 + find . -name ''\''*txt'\''' -type f -print

The find program is receiving the quote characters.  In your example the find
command needs a shell 'eval' in order to remove one layer of shell quoting.

 mask="-name '$2'"
 eval find $1 $mask -type f -print

Aunque he ejecutado el script con sh -x y a mi no me aparecen las comillas escapadas \' el caso es que poniendo el eval delante del find funciona.

Saludos.
slap

+1
0
-1

Saludos.

0000 start out (+FD),A
           ld  BC, +7FFF
           jp 03CB, RAM-CHECK

http://www.injiniero.es

Imagen de sansatan
+1
0
-1

Ya hemos aprendido algo más

;-) 

--------------------------------------

"Los esfuerzos, cuando se suman, se multiplican" Anónimo

+1
0
-1

--------------------------------------

Un error muy frecuente: Confundir valor y precio.