Проверьте входной параметр и выполните соответствующие действия.

Проверьте входной параметр и выполните соответствующие действия.

Скрипт, который у меня есть, требует двух входных данных: один — , filepathа другой — , filenameкоторый используется для проверки существования файла с помощью команды 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

Это работает совершенно нормально, как и ожидалось. Позже мне пришлось добавить еще пару условий в этот скрипт, то есть если мы получаем только в filenameкачестве входного параметра, то мы должны искать этот файл во всей файловой системе, как показано ниже

find / -iname "$Filename"

А в случае, если filepathв этот скрипт передается только входной параметр, то он должен вывести, что параметр имени файла также обязателен или просто должен быть выведен.

решение1

Я бы сделал:

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

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

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

echo >&2 "Not found"
exit 1

То есть, пройтиимя(обратите внимание, что findобрабатывает его как (нечувствительный к регистру из-за -iname) шаблон для сопоставления с именами файлов, а не как точное имя файла для поиска) в качестве первого аргумента. Любые другие аргументы — это каталоги или файлы для поиска, и если ни один из них не указан, поиск в /.

Вместо того, чтобы сохранять вывод в переменной и отображать его в конце, используйте его grepв качестве сквозного метода, который возвращает значение true, если файл найден.

Кроме того, я вывожу сообщение «Не найдено» на stderr вместо stdout и сообщаю о невозможности найти файл в статусе выхода.

Как отметил @ThomasN, есть обычная проблема, что вы не можете надежно передавать имена файлов/каталогов в find. Если вы хотите выполнить поиск в каталоге с именем -delete, вызов, that-script name -deleteнапример, будет иметь катастрофические последствия. В BSD findэто можно обойти, выполнив (перед вызовом find):

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

Для переносимости (хотя имейте в виду, что это -inameнепереносимо) вам придется добавлять ./относительные пути, что может быть проблематично, например:

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

Однако это влияет на вывод (как вы увидите ./delete/nameвместо -delete/name).

Связанный контент