Ich habe Zweifel, denn ich verstehe Folgendes:
exec 0</etc/passwd
IFS=:
while read in USUARIO
do
echo $USUARIO
done
Die Ausgabe sollte eine Liste mit allen Systembenutzern sein. Stattdessen erhalte ich die zweite Zeile, die mit x gefüllt ist, obwohl ich die erste möchte. Warum?
In diesem Skript übergeben Sie außerdem eine Zahl als Argument und sehen die Liste der Benutzer, die gleich viele oder mehr Dateien haben als der eingegebene Wert:
#!/bin/bash
if [[ ( $# -eq 1) && ( $1==[0-9][0-9]* )]]
then
echo "User with $1 files or more "
cut -d':' -f1 /etc/passwd | while IFS= read -r USUARIO
do
if [[ $( find / -user $USUARIO -print | wc -l ) -ge $1 ]]
then
echo $USUARIO
fi
done
exit 0
else
printf "Error: $0 int"
exit 1
fi
und es funktioniert ok, aber warum funktioniert es nicht:
#!/bin/bash
if [[ ( $# -eq 1) && ( $1==[0-9][0-9]* )]]
then
LIST="Users with more or $1 files: "
cut -d':' -f1 /etc/passwd | while IFS= read -r USUARIO
do
if [[ $( find / -user $USUARIO -print | wc -l ) -ge $1 ]]
then
LIST="$LIST $USUARIO"
fi
done
echo $LIST
exit 0
else
printf "Error $0 int"
exit 1
fi
Die Ausgabe erfolgt in der Rohzeichenfolge ohne Anhängen der Benutzernamen. Warum?
Antwort1
for
Sie scheinen die Syntax von und verwechselt zu haben while
. for
führt eine Befehlsfolge für jedes Element in einer Liste aus. Die Syntax lautet : Das Schlüsselwort trennt den Variablennamen von der Werteliste. führt eine Befehlsfolge aus, während eine andere Befehlsfolge wahr ist. Die Syntax lautet :for VARIABLE in VALUES; do COMMANDS; done
in
while
while COMMANDS; do COMMANDS; done
Der Befehl read
liest eine Zeile und teilt sie in Felder auf. Die Argumente von read
sind die Variablen, auf die die Feldwerte gesetzt werden. read in USUARIO
Setzt also in
auf das erste Feld und USUARIO
auf das zweite Feld, oder, wenn mehr als zwei Felder vorhanden sind (was in Ihrem Szenario der Fall ist), USUARIO
auf alle verbleibenden Felder (einschließlich innerer Trennzeichen). Jeder Aufruf von read
liest eine einzelne Zeile, und jede Schleifeniteration verarbeitet somit eine Zeile der Eingabe.
Um nur die Benutzernamen auszudrucken, müssen Sie also schreiben
while IFS=: read USUARIO rest
do
echo "$USUARIO"
done
Bezüglich der zweiten Frage (aber bitte stellen Sie das nächste Mal keine unzusammenhängenden Fragen zusammen): Das Problem besteht darin, dass jeder Befehl in einer Pipeline in einer Subshell ausgeführt wird, sodass in einer dieser Subshells festgelegte Variablen außerhalb der Pipeline nicht sichtbar sind. SieheWarum befindet sich meine Variable lokal in einer „while read“-Schleife, aber nicht in einer anderen, scheinbar ähnlichen Schleife?