Dieses Skript sollte alle Dateien, deren Namen als Argumente in der Befehlszeile angegeben sind, in das Stammverzeichnis des Benutzers kopieren. Wenn keine Dateien angegeben wurden, sollte das Skript read verwenden, um nach Dateinamen zu fragen, und alle in der Antwort angegebenen Dateinamen in das Stammverzeichnis des Benutzers kopieren.
if [ -z $1 ]
then
echo provide filenames
read $FILENAMES
else
FILENAMES="$@"
fi
echo the following filenames have been provided: $FILENAMES
for i in $FILENAMES
do
cp $i $HOME
done
Wenn ich Argumente als Zeichenfolge angebe, funktioniert es. Aber wenn ich „read $FILENAMES“ angebe, funktioniert es nicht.
Der Mentor zeigt in seinen Lektionen dieselbe Lösung, aber nicht, wie sie funktioniert.
UPDATE Nachdem ich die Dateinamen als Argumente eingegeben habe, werden leere Zeichenfolgen ausgegeben und die Dateien werden nicht an den Speicherort $HOME kopiert
[dmytro@oc1726036122 ~]$ cd Desktop/
[dmytro@oc1726036122 Desktop]$ . totmp
provide filenames
one two
the following filenames have been provided:
the following filenames have been provided:
[dmytro@oc1726036122 Desktop]$
Antwort1
Das read
deklariert Variablen, anstatt sie zu lesen. Einfach ausgedrückt: Entfernen Sie das $
von read
und schon kann es losgehen.
if [ -z $1 ]
then
echo provide filenames
read FILENAMES
else
FILENAMES="$@"
fi
echo the following filenames have been provided: $FILENAMES
for i in $FILENAMES
do
cp $i $HOME
done
BEARBEITEN: Ich sehe, dass Sie den Befehl source
( .
) verwenden, um ein Skript auszuführen.
[dmytro@oc1726036122 Desktop]$ . totmp
Für dieses spezielle Skript mag das in Ordnung sein, aber tun Sie das niemals für komplexe Skripte. Andernfalls würden Sie eine Variable oder Funktion aus diesem Skript in Ihre Shell einspeisen. Verwenden Sie einfachbash totmp
Antwort2
Das Problem, das Sie zu blockieren scheint, ist, dass der read
Befehl falsch ist. Das ihm übergebene Argument sollte ein Variablenname sein und daher ohne ein übergeben werden $
(das erweitert den Inhalt der Variablen, der zu diesem Zeitpunkt leer ist, sodass das Ergebnis ein ohne übergebene Variablennamen $
ist .)read
read FILENAMES
Es gibt ein weiteres Problem bei der Prüfung auf das Fehlen des ersten Befehlszeilenarguments. Wenn es nicht vorhanden ist, $1
wird then ins Nichts expandiert (nicht in eine leere Zeichenfolge), was zu Problemen mit dem [
Befehl führen könnte, da [ -z ]
es eigentlich nicht gültig sein sollte, [ -z "" ]
was Sie in diesem Fall überprüfen würden. Kurz gesagt, Sie müssen diese Variable in Anführungszeichen setzen:
if [ -z "$1" ]
Da Sie Bash verwenden, können Sie auch verwenden [[ ... ]]
, was im Allgemeinen besser ist, da es sich um einen internen Befehl handelt (in diesem Fall sollte dieser Befehl ohne Anführungszeichen funktionieren, aber die Anführungszeichen beizubehalten schadet nicht und sieht gut aus.)
(PS: An diesem Skript ist noch so viel mehr falsch, es ist so weit von Best Practices entfernt, dass es mich wirklich entsetzt, wenn ich sehe, wie jemand so etwas lehrt. Leider scheint die Messlatte für das Unterrichten von Bash sehr niedrig zu sein, und die Handbücher sind sehr komplex, bis man es wirklich gut verstanden hat, also weiß ich auch nicht, ob ich eine bessere Empfehlung hätte, wie man es richtig lernt.)☹️
Antwort3
Der read
Befehl übernimmt die Variable, aber Sie beziehen sich bereits auf die Werte der Variablen:
#correct syntax
read variable
#wrong syntax
read $variable
$variable
ist der Wert von variable
und am Anfang des Skripts ist dieser nicht festgelegt/leer.