Quiero que mi bash imprima 'encontrado' solo si se encuentra algo, usando el comando find. Pero usar && no ayuda: incluso si no encuentro nada, me imprimen 'encontrado'. Ejemplo:
$ pwd
/data/data/com.termux/files/home/test/test1/test4
$ ls
xaa xab
$ find . -name xac && echo 'found'
found
$ find . -name xaa && echo 'found'
./xaa
found
command-line
find
Josef Klimuk
fuente
fuente
/some/path
le dice a encontrar dónde comenzar a buscar, pero nada le dice qué buscar. Lo mismo en tu respuesta vinculada. Lo que funciona para mí esfind /some/path -name xac -print0 -quit | grep -qz . && echo found
. ¿Me he perdido algo?-print0 -quit
. Lo que pones antes de eso depende de lo que quieras encontrar. Elegí omitir eso aquí.La respuesta de muru es apropiada y adecuada para casos en los que queremos imprimir algo si se encuentra el archivo. Para el caso general cuando queremos ejecutar comandos externos, como
echo
, podríamos usar-exec
flag.La
{}
parte pasa el nombre de archivo al comando entre-exec
y\;
como argumentos. Tenga en cuenta lo\
anterior;
: evita que el shell lo malinterprete ; en el punto y coma que cierra el punto y coma significa el final del comando, pero cuando se escapa con una barra oblicua, el shell lo tratará como un texto literal que se pasará alfind
comando y para encontrar el comando sirve como-exec
argumento de cierre .Para construir condicionales del
if found do this; else do that
tipo, podríamos hacer uso de la substición de comando$()
y eltest
comando (aka[
)Abordar el comentario de Dan
Dan en los comentarios preguntó:
Vamos a entender el problema primero. Por lo general, en los shells hay un concepto de división de palabras, lo que significa que las variables no citadas y los parámetros posicionales se expandirán y tratarán como elementos separados. Por ejemplo, si usted tiene la variable
var
y contienehello world
texto, cuando lo hacetouch $var
el shell dividirlo en dos artículos separadoshello
yworld
ytouch
va a entender que, como si estuviera tratando de crear 2 archivos separados; Si lo hacetouch "$var"
, Shell lo trataráhello world
como una unidad ytouch
creará un solo archivo. Esto es importante para entender que esto sucede solo debido a cómo funcionan las conchas.Por el contrario,
find
no sufre ese comportamiento, ya que los comandos se procesan porfind
sí mismos y se ejecutan mediante unaexecvp()
llamada al sistema, por lo que no hay shell involucrado. Si bien las llaves tienen un significado especial en los shells, porque aparecen en el medio delfind
comando, y no al principio, no tienen un significado especial para shell en este caso. Aquí hay un ejemplo. Creemos algunos nombres de archivo difíciles e intentemos pasarlos como argumento parastat
ordenar.Como puede ver,
stat
recibe nombres de archivo difíciles perfectamente bienfind
, que es una de las razones principales por las que se recomienda su uso en scripts portátiles, y especialmente útil cuando atraviesa el árbol de directorios y desea hacer algo con nombres de archivo que podrían tener personajes especiales en ellos. Por lo tanto, no es necesario citar llaves para los comandos ejecutados enfind
.Es una historia diferente cuando Shell se involucra. A veces necesitas usar un shell para procesar el nombre del archivo. En ese caso, las citas realmente importan, pero es importante darse cuenta de que no es el problema del hallazgo: es el shell el que divide las palabras.
Entonces, cuando citamos dentro de Shell , funcionará. Pero de nuevo, eso es importante para Shell, no
find
.fuente
echo "I found {}"
sería mejor queecho "I found " {}
? Tal vez para echo está bien, pero si alguien copia el comando y reemplaza echo con otro comando, pueden tener un problema.