Verifique o parâmetro de entrada e execute de acordo

Verifique o parâmetro de entrada e execute de acordo

O script que tenho requer duas entradas, uma é a filepathe a outra filenameé usada para verificar a existência de um arquivo usando o comando find.

#!/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

Isso funciona perfeitamente bem, conforme esperado. Mais tarde, tive que adicionar mais algumas condições a este script, ou seja, se obtivermos apenas o filenameparâmetro de entrada, pesquisaremos esse arquivo em todo o sistema de arquivos, conforme fornecido abaixo

find / -iname "$Filename"

E caso apenas o filepathparâmetro de entrada seja passado para este script, ele deverá repetir esse parâmetro de nome de arquivo também é necessário ou apenas deverá ser lançado.

Responder1

Eu faria:

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

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

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

echo >&2 "Not found"
exit 1

Ou seja, passe onome(observe que findo trata como um padrão (sem distinção entre maiúsculas e minúsculas por causa de -iname) para corresponder aos nomes dos arquivos, não como um nome de arquivo exato a ser encontrado) como o primeiro argumento. Qualquer outro argumento são diretórios ou arquivos para pesquisar e, se nenhum for fornecido, pesquise em /.

Em vez de armazenar a saída em uma variável e exibi-la no final, use grepcomo passagem e isso informa verdadeiro se um arquivo for encontrado.

Além disso, estou exibindo a mensagem "Não encontrado" em stderr em vez de stdout e relatando a falha ao encontrar o arquivo no status de saída.

Conforme observado por @ThomasN, há o problema usual de você não poder passar nomes de arquivos/diretórios de maneira confiável para find. Se você quiser pesquisar em um diretório chamado -delete, chamar, that-script name -deletepor exemplo, teria efeitos desastrosos. Com BSDs find, isso pode ser contornado fazendo (antes de chamar find):

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

Portavelmente (embora observe que -inamenão é portátil), você precisaria acrescentar ./caminhos relativos que podem ser problemáticos, como:

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

Isso afeta a saída (como você verá ./delete/nameem vez de -delete/name).

informação relacionada