Rafał Radecki wrote:
Witam wszystkich. Jako początkujący twórca skryptów natrafiłem na problem.
Tworzę skrypt tworzący konta na podstawie pliku /etc/passwd z innego hosta.
Teoretycznie chciałem umieścić wszystkie odpowiednie ($5 ~ /WZÓR$/)linijki
wspomnianego /etc/passwd w zmiennej SUSERS:
SUSERS=`awk -F: '$5 ~ /WZÓR$/{print}' ./passwd`
Następnie za pomocą pętli for chciałem dla każdej linijki (wpisu ze starego
/etc/passwd) otrzymywać odpowiednie wartości pól i dodawać nowego
użytkownika:
for $i in $SUSERS
do
USRNAME=`awk -F: '{print $1}' $i`
UID=`awk -F: '{print $3}' $i`
HOMEDIR=`awk -F: '{print $6}' $i`
LSHELL=`awk -F: '{print $7}' $i`
COMMENT=`awk -F: '{print $5}' $i`
PASSWORD=`egrep "^$USRNAME" .shadow | cut -d: -f2`
useradd -u $UID -m -d $HOMEDIR -s $SHELL -c \'$COMMENT\' -p
$PASSWORD $USRNAME
done
Niestety zmienna SUSERS zawiera jedną linijkę składającą się ze wszystkich
linii starego /etc/passwd oddzielonych spacjami i moja metoda nie działa.
Czy moglibyście doradzić jakieś inne podejście do problemu? Może zmienna
SUSERS powinna być tablicą => jak wówczas zmodyfikować zmienną i pętlę for?
Może awk ma taką funkcjonalność by dla każdej linijki, która w 5. polu ma
WZÓR wykonywać komendę (w tym przypadku) useradd z parametrami
odpowiadającymi poszczególnym polom z aktualnie przetwarzanej linii
($1,$2...)? Pytanie dla niektórych pewnie proste, zaczynam jednak dopiero
przygodę ze skryptami w bash-u, wszelka pomoc więc będzie bardzo miło
widziana.
Pozdrawiam,
R.
czesc,umieszczanie czegos w jednej zmiennej i potem for'owanie pon to kiepski pomysl - jak trafisz gdzies spacje (np: w opisie uzyszkodnika) to skrypt Ci sie rozjedzie.
druga sprawa: zmienna UID jest rd-only. :) dodalem przedrostki "C_" do wszystkich zmiennych, zeby nic sie nie pokrywalo ze zmiennymi shell'a.
pamietaj tez na przyszlosc, zeby przypisania do zmiennych i ich uzycie zawsze brac w cudzyslowia - unikniesz dzieki temu sporej ilosc "spacjowych problemow". :)
jesli potrzebujesz przetwarzania linia po linii proponuje cos takigo "while read", np:
#!/bin/bash
cat /etc/passwd | \
while read line
do
C_USRNAME="`awk -F: '{print $1}' <<< "$line"`"
C_UID="` awk -F: '{print $3}' <<< "$line"`"
C_HOMEDIR="`awk -F: '{print $6}' <<< "$line"`"
C_LSHELL="` awk -F: '{print $7}' <<< "$line"`"
C_COMMENT="`awk -F: '{print $5}' <<< "$line"`"
#C_PASSWORD=`egrep "^$C_USRNAME" /etc/shadow | cut -d: -f2`
echo useradd -u "$C_UID" -m -d "$C_HOMEDIR" -s "$C_SHELL" -c
"$C_COMMENT" -p "$C_PASSWORD" $C_USRNAME
done exit 0w/w skrypt jest dosc toporny, ale dziala (grepowanie shadow'a wykomentowalem, bo nie testowalem tego - zostawilem jak bylo u Ciebie). przed wykonaniem useradd dalem echo zebys widzial co sie dzieje (latwiej bedzie Ci zmieniac/debugowac). jak skonczysz to wywalasz echo i voila. :)
btw: petla "while read" bedzie miala tu jeszcze jedna zalete - zapewne bedizesz potrzebowal odfiltrowac UID'y systemowe lub uzyszkodniqw juz obecnych w docelowym systemie (i.e.: root, cron, etc...) - teraz wystarczy dodac jednego if'a przed wykonaniem useradd'a.
-- pozdrawiam serdecznie / best regards, bartek szurgot http://baszerr.org