Hallo, ich bin leider nicht der Shell-Programmierer vorm Herrn, wollte aber dennoch ein kleines selbst gebasteltest Script zum Anlegen von Benutzern einsetzen: ----------------------------------------------------------------- #!/bin/bash while read user do /usr/sbin/useradd $zeile -d /home/$user -g users -s /bin/false; echo -e "$user"; (echo "passwort"; sleep 3; echo "passwort";) | /usr/bin/passwd $user; echo -e "Passwort gesetzt\n" done < /root/benutzer.txt ----------------------------------------------------------------- In der Datei benutzer.txt steht jeweils pro Zeile ein Benutzername. Auf einem Debian (Kanotix) läuft das Script problemlos durch, auf einem frisch installierten SuSE 10.0 (Minimalinstallation ohne X) gibts es eine seltsame Fehlermeldung: ------------------------------------------------------------------ mailserver1:~ # ./script.sh '.eradd: Invalid account name `abw abw '.sswd: Unknown user `abw Passwort gesetzt ------------------------------------------------------------------ abw" ist der Wert in der 1.Zeile der Datei benutzer.txt. Kann mir da vielleicht jemand auf die Sprünge helfen, was hier schief läuft? Gruß Jürgen
Hallo, 2006-02-14, 14:42 +0100, Juergen Pabst:
Hallo,
ich bin leider nicht der Shell-Programmierer vorm Herrn, wollte aber dennoch ein kleines selbst gebasteltest Script zum Anlegen von Benutzern einsetzen: ----------------------------------------------------------------- #!/bin/bash while read user do /usr/sbin/useradd $zeile -d /home/$user -g users -s /bin/false; echo -e "$user"; (echo "passwort"; sleep 3; echo "passwort";) | /usr/bin/passwd $user; echo -e "Passwort gesetzt\n" done < /root/benutzer.txt ----------------------------------------------------------------- In der Datei benutzer.txt steht jeweils pro Zeile ein Benutzername.
Vielleicht so: ------------- cut here ----------------------- #!/bin/bash while read zeile do /usr/sbin/useradd "$zeile" -d /home/"$zeile" -g users -s /bin/false; echo -e "$zeile"; ( echo "passwort"; sleep 3; echo "passwort"; ) | /usr/bin/passwd "$zeile"; echo -e "Passwort gesetzt\n" done < benutzer.txt ------------- cut here ----------------------- "user" als Variablenname ist eine schlechte Wahl. Außerdem hast du die Variable "zeile" benutzt, obwohl deren Wert nie gesetzt wird.
Gruß Jürgen
Gruß Kimmo
Hallo Kimmo!
Vielleicht so: ------------- cut here ----------------------- #!/bin/bash while read zeile do /usr/sbin/useradd "$zeile" -d /home/"$zeile" -g users -s /bin/false; echo -e "$zeile"; ( echo "passwort"; sleep 3; echo "passwort"; ) | /usr/bin/passwd "$zeile"; echo -e "Passwort gesetzt\n" done < benutzer.txt ------------- cut here -----------------------
"user" als Variablenname ist eine schlechte Wahl. Außerdem hast du die Variable "zeile" benutzt, obwohl deren Wert nie gesetzt wird.
Sorry, mein Fehler, im Script habe ich beide Versionen ($zeile und $user) ausprobiert, also an der Variablen sollte es nicht liegen. Es muss noch irgendwas anderes sein... Meine Vermutung geht in Richtung Software, denn ich habe wie gesagt eine Minimalinstallation gemacht. Könnte vielleicht irgendein Paket fehlen? Gruß Jürgen
Juergen Pabst wrote:
Hallo Kimmo!
Vielleicht so: ------------- cut here ----------------------- #!/bin/bash while read zeile do /usr/sbin/useradd "$zeile" -d /home/"$zeile" -g users -s /bin/false; echo -e "$zeile"; ( echo "passwort"; sleep 3; echo "passwort"; ) | /usr/bin/passwd "$zeile"; echo -e "Passwort gesetzt\n" done < benutzer.txt ------------- cut here -----------------------
"user" als Variablenname ist eine schlechte Wahl. Außerdem hast du die Variable "zeile" benutzt, obwohl deren Wert nie gesetzt wird.
Sorry, mein Fehler, im Script habe ich beide Versionen ($zeile und $user) ausprobiert, also an der Variablen sollte es nicht liegen.
Also so (siehe unten) funktioniert es bei mir :) (ist auch etwas schneller als mit einem slepp 3 für jeden neuen user) #!/bin/sh if test $1 then FILE=$1 else FILE="benutzer.txt" fi for newuser in `cat $FILE` do /usr/sbin/useradd $newuser -d /home/$newuser -g users -s /bin/false; echo -e $newuser; echo "password" | /usr/bin/passwd --stdin $newuser; echo -e "Passwort gesetzt\n"; done; Tipp: siehe # man passwd Ciao, Daniel
Hallo, Am Tue, 14 Feb 2006, Jens Daniel Schmidt schrieb:
Also so (siehe unten) funktioniert es bei mir :) (ist auch etwas schneller als mit einem slepp 3 für jeden neuen user)
#!/bin/sh
if test $1 then FILE=$1 else FILE="benutzer.txt" fi
FILE="${1:-benutzer.txt}"
for newuser in `cat $FILE`
Schlecht. while read -r newuser; do ... done < "$FILE" -dnh -- Our lives are about development, mutation and the possibility of change; that is almost a definition of what life is: change. -- "Look to Windward", Iain M. Banks
while read -r newuser; do ... done < "$FILE"
So geht es auch, aber warum ist das besser?
"Besser" würde ich es für diesen Fall nicht nennen, da ein Username ja keine Leerzeichen enthalten darf. Das "Problem" bei cat ist, dass es bei einer Datei mit folgendem Inhalt: --- asd qwe dfg --- 3 Werte behandelt (asd, qwe und dfg), während read zeilenweise liest und das Skript somit nur 2 Werte verarbeiten würde (asd qwe und dfg). Deshalb wird read normalerweise zur zeilenweise Bearbeitung von Dateien benutzt. Alternativ kann man aber, wenn man sich bewusst ist, wie cat reagiert, vor dem eigentlich Skript ein export ISF="\n" machen. Damit arbeitet dann auch cat "zeilenweise". Grüße Dominik
Hallo, Am Wed, 15 Feb 2006, Achim Schaefer schrieb:
On Tuesday 14 February 2006 18:13, David Haller wrote:
for newuser in `cat $FILE`
Schlecht.
Warum?
Weil das Ergebnis oft nicht das ist was man erwartet...
while read -r newuser; do ... done < "$FILE"
So geht es auch, aber warum ist das besser?
$ wc ~/.procmail/procmail.log 8724 47138 427911 /home/dh/.procmail/procmail.log $ time { i=0; for x in `cat ~/.procmail/procmail.log`; do i=$[i+1]; done; echo "$i tokens"; } 47978 tokens real 0m9.745s $ time { i=0; while read x; do i=$[i+1]; done < ~/.procmail/procmail.log; echo "$i tokens"; } 8724 tokens real 0m1.736s Das read liest Zeilenweise, ggfs. auch mehrere Variablen auf einmal: OIFS="$IFS"; IFS=":";\ while read user pw uid gid comment home shell; do\ echo "user=$user, home=$home, shell=$shell";\ done < /etc/passwd;\ IFS="$OIFS" wobei ein "Rest" in der zuletzt angegebenen Variablen landet: OIFS="$IFS"; IFS=":";\ while read user rest; do\ echo "user=$user, Rest=$rest";\ done < /etc/passwd;\ IFS="$OIFS" Aber man sollte sowieso 'getent passwd | ' verwenden und nicht /etc/passwd auslesen. HTH, -dnh -- No, no, no - you are out of sync. This week the topic is "Germany is antisemitic", "Germany is controlled by a Jewish conspiracy" is *next* week. Please stick to the official schedule, otherwise you'll get us all confused. Thank you. -- Stefan Doll in dpg/scg
Hallo nochmals, 2006-02-14 16:35 +0100, Jens Daniel Schmidt:
Juergen Pabst wrote:
Hallo Kimmo!
Vielleicht so: ------------- cut here ----------------------- #!/bin/bash while read zeile do /usr/sbin/useradd "$zeile" -d /home/"$zeile" -g users -s /bin/false; echo -e "$zeile"; ( echo "passwort"; sleep 3; echo "passwort"; ) | /usr/bin/passwd "$zeile"; echo -e "Passwort gesetzt\n" done < benutzer.txt ------------- cut here -----------------------
"user" als Variablenname ist eine schlechte Wahl. Außerdem hast du die Variable "zeile" benutzt, obwohl deren Wert nie gesetzt wird.
Sorry, mein Fehler, im Script habe ich beide Versionen ($zeile und $user) ausprobiert, also an der Variablen sollte es nicht liegen.
Also so (siehe unten) funktioniert es bei mir :) (ist auch etwas schneller als mit einem slepp 3 für jeden neuen user)
#!/bin/sh
if test $1 then FILE=$1 else FILE="benutzer.txt" fi
for newuser in `cat $FILE` do /usr/sbin/useradd $newuser -d /home/$newuser -g users -s /bin/false; echo -e $newuser; echo "password" | /usr/bin/passwd --stdin $newuser; echo -e "Passwort gesetzt\n"; done;
Ich habe mein Skript auch mit einer Test-Datei (mit 2 Einträgen) probiert und konnte damit problemlos zwei neue users anlegen...:) Übrigens, die "-Zeichen in meinem Skript sind eigentlich unnötig, die Benutzernamen dürfen ja keine Leerzeichen haben. Gruß Kimmo
/usr/sbin/useradd $zeile -d /home/$user -g users -s /bin/false;
Aus "man useradd": --snip useradd [-D binddn] [-P path] [-c comment] [-d homedir] [-e expire] [-f inactive] [-G group,...] [-g gid] [-m [-k skeldir]] [-o] [-p password] [-u uid] [-r] [-s shell] [--service service] [--help] [--usage] [-v] account --snip Du gibt useradd zuerst den account, dann die Optionen. Könnte es das sein?
was sagt denn "file /root/benutzer.txt" Ist es evtl ein DOS-File mit unschönen Zeilenumbrüchen? dos2unix könnte dann helfen
mailserver1:~ # file benutzer.txt benutzer.txt: ASCII text, with CRLF line terminators
Ist das gut oder eher nicht?
Das klingt nach nem Dos-File. Hast du die Datei evtl. auf nem Windows erzeugt? Mach mal folgendes: cp benutzer.txt benutzer.txt.bak dos2unix benutzer.txt Und dann schau mal, was dein Skript tut. Wenns dann immernoch den Dienst verweigert, bin ich mit meinem Latein am Ende :)
Hallo Dominik!
mailserver1:~ # file benutzer.txt benutzer.txt: ASCII text, with CRLF line terminators
Ist das gut oder eher nicht?
Das klingt nach nem Dos-File. Hast du die Datei evtl. auf nem Windows erzeugt?
Ja, hab ich.
Mach mal folgendes: cp benutzer.txt benutzer.txt.bak dos2unix benutzer.txt
Großes Dankeschön, das war es! Wundert mich nur, dass Kanotix (Debian) da keine Probleme mit der (Windows-)Textdatei hatte. Gruß Jürgen
Großes Dankeschön, das war es!
Bitte schön :) Sowas kommt immer mal wieder vor, man kommt auf so einfache Sachen aber oftmals erst zum Schluss. Windows setzt ans Zeilenende andere (für dich unsichtbare) Steuerzeichen, um die Zeile zu beenden, als Linux.
Wundert mich nur, dass Kanotix (Debian) da keine Probleme mit der (Windows-)Textdatei hatte.
Kanotix kenne ich nicht - in sofern kann ich dir den Grund dafür auch nicht nennen.
Hallo, Am Tue, 14 Feb 2006, Juergen Pabst schrieb:
(echo "passwort"; sleep 3; echo "passwort";) | /usr/bin/passwd $user;
Die extra Subshell ist unnoetig. Willst du nur Ausgaben zusammenfassen reicht das dafuer vorgesehene Konstrukt mit {} statt (): { echo "passwort"; sleep 1; echo "passwort"; } | ... ==== man bash ==== Compound Commands (list) list is executed in a subshell. { list; } list is simply executed in the current shell envi ronment. list must be terminated with a newline or semicolon. This is known as a group command. The return status is the exit status of list. ==== HTH, -dnh -- Why do you focus so much on _new_ technology? -- New is better. Is nothink old that is better than new. -- Yes there is. -- Da? Namink one then. -- The Original Pentium versus counting on your fingers. -- Da. Da. "Don't divide. Intel inside" [Sid & Pitr in userfriendly]
Hallo David!
Am Tue, 14 Feb 2006, Juergen Pabst schrieb:
(echo "passwort"; sleep 3; echo "passwort";) | /usr/bin/passwd $user;
Die extra Subshell ist unnoetig. Willst du nur Ausgaben zusammenfassen reicht das dafuer vorgesehene Konstrukt mit {} statt ():
{ echo "passwort"; sleep 1; echo "passwort"; } | ...
==== man bash ==== Compound Commands
(list) list is executed in a subshell.
{ list; } list is simply executed in the current shell envi ronment. list must be terminated with a newline or semicolon. This is known as a group command. The return status is the exit status of list.
Vielen Dank für den Hinweis, wieder was gelernt. Aber mein Script ist nun schon gelaufen und die Benutzer angelegt. Gruß Jürgen
(echo "passwort"; sleep 3; echo "passwort";) | /usr/bin/passwd $user;
(list) list is executed in a subshell. { list; } list is simply executed in the current shell envi ronment. list must be terminated with a newline or semicolon. This is known as a group command. The return status is the exit status of list.
man chpasswd
gruss christof
participants (7)
-
Achim Schaefer
-
Christof E. Spies
-
David Haller
-
Dominik Klein
-
Jens Daniel Schmidt
-
Juergen Pabst
-
K. Elo