Hallo, On Sun, 17 Nov 2002, Joachim Kieferle wrote:
Jürgen Vollmer wrote: [..] nachdem ich heute mittag "meine" Version des User-Anlegen Skriptes an die Liste gepostet habe möchte ich Euch eine bessere Variante von Jürgen Vollmer nicht vorenthalten - Jürgen, vielen Dank. [..]
------------------------------------------------------------------------ #!/bin/bash # Liest die Datei $USERS # und erzeugt die entsprechenden User- und Mail Accounts. # Author: Dr. Jürgen Vollmer
# set -x CMD=`basename $0` USERS=/root/verwaltung/user/userdaten.csv
# Basisverzeichnis aller User USER_HOME_BASE=/export/home/1
# Benutzer-Shell USER_LOGIN_SHELL=/bin/false
# setquota: QUOTA_BLOCK_SOFT=100000 QUOTA_BLOCK_HARD=100000 QUOTA_INODE_SOFT=0 QUOTA_INODE_HARD=0
############################################################################# usage() { cat <
Format der Datei: Vorname:Name:Login:Passwort:MatrNr:Expires:Angelegt:Gruppe1:Gruppe2:Gruppe3 Alle Felder mit Ausname von Name, Login, Passwort können leer sein.
Optionen: -h : help
Author: Dr. Jürgen Vollmer
EOF } ############################################################################# # Einige Funktionen: #############################################################################
# Gib Fehlermeldung aus, und Abbruch error() { echo "$CMD: Fehler: $*" echo "$CMD: Fehler: $*" | mail -s "$CMD: Fehler" root exit 1; }
############################################################################# # Führe Kommando $1 mit den angegeben Argumenten aus und prüfe den # Exit-code der Kommands. # Im Fehlerfalle: gib Fehlermeldung aus (error) do_cmd() { cmd=$1 shift
$CMD "@*" || error "$cmd " "@*" }
Hier soll doch sicher: $cmd "$@" || error "$cmd $@" stehen. Aber das geht auch einfacher ;) function do_cmd() { "$@" || error "$@" } (ich schreib seit ner Weile das function gerne explizit hin, dank Syntax Highlighting macht das die Sache uebersichtlicher ;)
############################################################################# # Analysiere Argumente while getopts hv opt $*
Sollte man nicht "$@" statt $* verwenden?
do case $opt in h) usage; exit;; *) exit 1;; esac done
shift `expr $OPTIND - 1`
# Keine weiteren Argumente angegeben? [ $OPTIND -eq 1 ] || { usage; exit 1;}
Hm. Kommt mir fuer den Anwendungsfall ein wenig "aufgeblasen" for... while test $# -gt 0; do case "$1" in -h | --help) usage; exit 0;; -*) usage; exit 1;; *) ARGS="$ARGS \"$1\""; shift;; esac; done; eval set -- $ARGS; test $# -gt 0 && { usage; exit 1; } Uebrigens halte ich nix davon so wie oben [ .. ] statt 'test' zu verwenden, genausowenig wie '.' statt 'source'... ;)
#############################################################################
# IFS The Internal Field Separator that is used for word # splitting after expansion and to split lines into # words with the read builtin command. The default # value is ``<space><tab><newline>''. OLD_IFS=$IFS
Bitte OLD_IFS="$IFS" verwenden...
sort -t: -k2 $USERS | # sortiere nach Nachnamen (2. Feld) while read line do # entferne alle Leerzeichen aus der Zeile line=`echo $line | sed -e's/ //g'`
Und was ist mit z.B. nem zweiten Vornamen z.B.? IIRC ersetzt du (Joachim) bisher ja mit sed die ',' in der csv-Datei durch ':', oder? Ausserdem kann man sich das ersetzen der , durch : sparen, denn das PW koennte ja z.B. ein , enthalten, das wuerde auch durch ein : ersetzt, da aber beim CSV Export (mindestens) Strings, die den Feld-Trenner enthalten gequotet werden muessen...
# spalte Zeile auf am ":" IFS=":" echo "$line"
Wozu hier das echo? Vom debuggen uebriggelassen? ;)
set -- $line U_VORNAME=$1 U_NAME=$2 U_LOGIN=$3 U_PASSWORT=$4 U_MATRNR=$5 U_EXPIRES=$6 U_ANGELEGT=$7 U_GRUPPE1=$8 U_GRUPPE2=$9 U_GRUPPE3=${10} # bash specific!
IFS=$OLDIFS
Das letzte muesste IFS="$OLD_IFS" sein (s.o.). Ok, um also die csv-Zeile (ob jetzt , oder : der Feldtrenner ist, ist egal, richtig behandeln muss man's sowieso ;) Also (wir sind schon im while): Erstmal die Quotezeichen so "escapen", dass wir Anfang und Ende unterscheiden koennen, dann die Feldtrenner innerhalb davon ebenfalls ersetzen und dann die Quotezeichen wiederherstellen: line="`echo \"$line\" | sed 's/\"\([^\"]*\)\"/§\1¶/g'`" line="`echo \"$line\" | sed 's/\(§[^¶]*\),\([^¶]*¶\)/\1¡\2/g'`" line="`echo \"$line\" | sed 's/[§¶]/\"/g'`" IFS="," set -- $line IFS="$OLD_IFS" Ausserdem sollte man dann die Felder die leer sein duerfen ggfs. mit defaults fuellen, z.B.: U_EXPIRES="${6:-$DEF_EXPIRES}" U_ANGELEGT="${7:-$DATE}" [davor, vor der Schleife:] DATE="`date '+%d.%m.%Y'`" DEF_EXPIRES="`date -d 'year' '+%d.%m.%Y'`" Jetzt noch ein klein wenig "Magie" um die obige Ersetzung rueckgaengig zu machen ;) for var in U_VORNAME U_NAME U_LOGIN U_PASSWORT U_MATRNR U_EXPIRES \ U_ANGELEGT U_GRUPPE1 U_GRUPPE2 U_GRUPPE3 do eval wert="\$$var" wert="`echo \"$wert\" | sed 's/¡/,/g'`" eval "$var=\"$wert\"" done
# Prüfe ob Pflichtfelder angegeben wurden: [ -z "$U_NAME" ] && error "NAME nicht angegeben: $line" [ -z "$U_LOGIN" ] && error "LOGIN nicht angegeben: $line" [ -z "$U_PASSWORT" ] && error "PASSWORT nicht angegeben: $line"
Wieder wuerde ich test verwenden, und ausserdem noch die Logik umdrehen: test -n "$U_NAME" || error "..."
# Führe Kommandos aus do_cmd useradd -c "$U_VORNAME $U_NAMEs" -d $USER_HOME_BASE/$U_LOGIN \ -e $E_EXPIRES -G$U_GRUPPE1 -m -s $USER_LOGIN_SHELL ^?? Oben war's ein U!!
$U_LOGIN do_cmd smbpasswd -a $U_LOGIN $U_PASSWORT do_cmd setquota $U_LOGIN \ $QUOTA_BLOCK_SOFT $QUOTA_BLOCK_HARD \ $QUOTA_INODE_SOFT $QUOTA_INODE_HARD \ -a
Bitte alle Variablen quoten...
Hmm... Ich glaube fast, ich sollte alle meine Aenderungsvorschlaege
nochmal zusammenfassen ;)
Achtung: ich gehe davon aus, dass die Felder in der csv-Datei durch
',' getrennt sind!!!
===================================================================
==== Achtung: nur minimal getestet ====
===================================================================
#! /bin/bash
# Liest eine CSV-Datei
# und erzeugt die entsprechenden User- und Mail Accounts.
# Author: Dr. Jürgen Vollmer