Seltsames Problem beim Übergeben von Variablen aus einer Textdatei

Seltsames Problem beim Übergeben von Variablen aus einer Textdatei

Ich habe ein Skript, das für jede Zeile in einer Datei ein anderes Skript ausführt.

Wenn ich echo„jedes“ drücke, $linekann ich wie erwartet den vollständigen Inhalt der Zeile sehen.

Doch connect.shnur im Inneren $1ist es so eingestellt user\ name.

Wenn ich versuche, zu verwenden "$line", wird $1am connect.shEnde angezeigt user\ name user\ password.

Wie kann ich den Programmfluss so einrichten, dass reboot.shjede Zeile als 2 Parameter übergeben /tmp/historywird connect.sh?

Mit dem Endergebnis, das $1lautet user\ nameund $2ist user\ password?

Neustart.sh:

if [ -e "/tmp/history" ]; then
  while read -r line; do
    echo $line
    connect.sh $line \
      && break
  done </tmp/history
fi

verbinden.sh:

echo $1
echo $2

/tmp/Geschichte:

user\ name user\ password

Antwort1

Ich gehe davon aus, dass die Backslashes dazu da sind, die beiden Leerzeichen zu maskieren, sodass sie die Werte nicht trennen.

Mit read -r lineerhalten Sie die ganze Zeile in der Variable line, die also , mit den Backspaces lineenthält user\ name user\ password. Es ist nicht einfach, das ohne Tricks mit aufzuteilen eval. Ein nicht in Anführungszeichen gesetztes Wort $linewird an Leerzeichen aufgeteilt, egal ob es Backslashs gibt oder nicht. In Anführungszeichen gesetzt, wird es zu einem Wort erweitert, wie Sie gesehen haben.

Glücklicherweise readkann Backslashes verarbeiten und seine Eingabe in zwei (oder mehr) Variablen aufteilen. Die Variablen würden dann user nameund enthalten user password(ohne Backslashes):

while read user pass ; do 
    echo "user: $user"
    echo "pass: $pass"
    ./connect.sh "$user" "$pass"
done < file

Wenn Sie jedoch Leerzeichen im Benutzernamen und im Passwort zulassen möchten, ist es möglicherweise besser, ein anderes Trennzeichen als Leerzeichen zu verwenden. Ein Doppelpunkt ist üblich, sodass Sie eine Eingabe wie diese erhalten:

user name:user pass word

Und dann lesen Sie es mit

while IFS=: read -r user pass ; do 
    echo "user: $user"
    echo "pass: $pass"
done < file          

(Das sollte funktionieren, solange das Passwort nicht mit einem Doppelpunkt endet)

Antwort2

Wenn Sie ein Argument mit Leerzeichen haben, müssen Sie die Zeichenfolge unbedingt in doppelte Anführungszeichen setzen, um zu verhindern, connect.shdass sie als mehrere Argumente interpretiert wird. Möglicherweise möchten Sie die Zeichenfolge in mehrere Argumente aufteilen. Ich bin mir nicht sicher, welches Format die Zeile hat, aber Sie können möglicherweise so etwas tun:

line="user name user password"
# Split the line into space-separated tokens and store 1 and 2
UNAME=$(echo "$line" | cut -d ' ' -f 1,2)
# Split the line into space-separated tokens and store 3 and 4
UPASSWD=$(echo "$line" | cut -d ' ' -f 3,4)
echo "$UNAME"
echo "$UPASSWD"

Dies sollte gedruckt werden:

user name
user password

Sie müssen wahrscheinlich einige Anpassungen basierend auf dem tatsächlichen Format der Eingabezeile vornehmen. Wenn Ihre $line beispielsweise den Benutzernamen und das Benutzerkennwort durch ein Komma getrennt hat, können Sie Folgendes ausführen:

line="user name,user password"
# Split the line into comma-separated tokens and store 1
UNAME=$(echo "$line" | cut -d ',' -f 1)
# Split the line into comma-separated tokens and store 2
UPASSWD=$(echo "$line" | cut -d ',' -f 2)
echo "$UNAME"
echo "$UPASSWD"

Denken Sie daran: Wenn Sie einem Programm ein Argument übergeben und dieses Argument Leerzeichen enthält, müssen Sie doppelte Anführungszeichen verwenden, damit das Programm es als ein Argument erkennt.

verwandte Informationen