Verifique el parámetro de entrada y ejecútelo en consecuencia

Verifique el parámetro de entrada y ejecútelo en consecuencia

El script que tengo requiere dos entradas, una filepathy la otra filenameque se usa para verificar la existencia de un archivo usando el comando buscar.

#!/bin/bash

Filepath=$1
Filename=$2

if [ -z "$Filepath" ] && [ -z "$Filename" ]
then
        echo "Requires Input"
elif [ ! -z "$Filepath" ] && [ ! -z "$Filename" ]
then
        Found=`find "$Filepath" -iname "$Filename"`
                if [ -z "$Found" ]
                then
                        echo "Not Found"
                else
                        echo $Found
                fi
fi

Esto funciona completamente bien como se esperaba. Más tarde tuve que agregar un par de condiciones más a este script, es decir, si obtenemos solo el filenameparámetro de entrada, buscaremos ese archivo en todo el sistema de archivos como se indica a continuación.

find / -iname "$Filename"

Y en caso de que solo filepathse pase el parámetro de entrada a este script, entonces debe repetirse que el parámetro de nombre de archivo también es necesario o simplemente debe aparecer.

Respuesta1

Lo haría:

#! /bin/sh -
pattern=${1?Please provide a file name}
shift

[ "$#" -gt 0 ] || set /

find "$@" -iname "$pattern" | grep '^' && exit

echo >&2 "Not found"
exit 1

Es decir, pasar elnombre(tenga en cuenta que findlo trata como un patrón (que no distingue entre mayúsculas y minúsculas debido a -iname) para comparar nombres de archivos, no como un nombre de archivo exacto para buscar) como primer argumento. Cualquier otro argumento son directorios o archivos para buscar y, si no se proporciona ninguno, buscar en /.

En lugar de almacenar la salida en una variable y mostrarla al final, utilícela grepcomo transferencia y eso informa que es verdadero si se ha encontrado un archivo.

Además, estoy mostrando el mensaje "No encontrado" en stderr en lugar de stdout, e informo que no se pudo encontrar el archivo en el estado de salida.

Como señaló @ThomasN, existe el problema habitual de que no se pueden pasar nombres de archivos/directorios de manera confiable a find. Si desea buscar en un directorio llamado -delete, llamar, that-script name -deletepor ejemplo, tendría efectos desastrosos. Con BSD find, esto se puede solucionar haciendo (antes de llamar find):

for i do
  set -- "$@" -f "$i"
  shift
done

De forma portátil (aunque tenga en cuenta que -inameno es portátil), deberá anteponer ./rutas relativas que pueden ser problemáticas, como con:

for i do
  case $i in
    (. | ./* | /*) ;; # /foo, ./foo are not a problem
    (*) i=./$i
  esac
  set -- "$@" "$i"
  shift
done
find "$@"...

Sin embargo, eso sí afecta la salida (como verá ./delete/nameen lugar de -delete/name).

información relacionada