Das Skript, das ich habe, erfordert zwei Eingaben, eine ist die filepath
und die andere filename
wird verwendet, um die Existenz einer Datei mit dem Befehl „Find“ zu überprüfen.
#!/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
Dies funktioniert wie erwartet einwandfrei. Später musste ich diesem Skript noch ein paar weitere Bedingungen hinzufügen, d. h. wenn wir nur als filename
Eingabeparameter erhalten, müssen wir diese Datei im gesamten Dateisystem suchen, wie unten angegeben
find / -iname "$Filename"
Und falls nur der filepath
Eingabeparameter an dieses Skript übergeben wird, muss es diesen Dateinamenparameter erneut anzeigen, es ist auch dieser erforderlich oder muss einfach ausgegeben werden.
Antwort1
Ja, würde ich:
#! /bin/sh -
pattern=${1?Please provide a file name}
shift
[ "$#" -gt 0 ] || set /
find "$@" -iname "$pattern" | grep '^' && exit
echo >&2 "Not found"
exit 1
Das heißt, übergeben Sie dieName(Beachten Sie, dass find
es als Muster behandelt wird (Groß-/Kleinschreibung wird aufgrund von nicht beachtet -iname
), das mit Dateinamen abgeglichen werden soll, und nicht als exakter Dateiname, der gesucht werden soll) als erstes Argument. Alle anderen Argumente sind Verzeichnisse oder Dateien, in denen gesucht werden soll. Wenn keines angegeben ist, soll in gesucht werden /
.
Anstatt die Ausgabe in einer Variablen zu speichern und sie am Ende anzuzeigen, verwenden Sie sie grep
als Pass-Through und melden Sie „true“, wenn eine Datei gefunden wurde.
Außerdem gebe ich die Meldung „Nicht gefunden“ auf stderr statt auf stdout aus und melde im Beendigungsstatus, dass die Datei nicht gefunden werden konnte.
Wie von @ThomasN angemerkt, gibt es das übliche Problem, dass Sie Datei-/Verzeichnisnamen nicht zuverlässig an übergeben können find
. Wenn Sie in einem Verzeichnis namens suchen möchten -delete
, that-script name -delete
hätte der Aufruf von beispielsweise katastrophale Auswirkungen. Bei BSDs find
kann dies umgangen werden, indem Sie (vor dem Aufruf von find
) Folgendes tun:
for i do
set -- "$@" -f "$i"
shift
done
Portabel (beachten Sie jedoch, dass dies -iname
nicht portabel ist) müssten Sie ./
relative Pfade voranstellen, was problematisch sein kann, wie beispielsweise:
for i do
case $i in
(. | ./* | /*) ;; # /foo, ./foo are not a problem
(*) i=./$i
esac
set -- "$@" "$i"
shift
done
find "$@"...
Dies wirkt sich jedoch auf die Ausgabe aus (Sie sehen stattdessen ./delete/name
) -delete/name
.