批次建帳號─awk的應用


資料來源: 北市文山區力行國小顏國雄
http://mail.lsps.tp.edu.tw/~gsyan/freebsd2001/passwd-awk.html
批次建帳號─awk的應用
2004/07/03 修改 
怎麼能夠大量新增帳號是每個系統管理者頭痛的問題,Unix Like 的系統,大部份的工具都是命令列的方式,只要做輸出/入的重導其實應該可很容易做到批次處理,至於是用 shell script , perl , awk , php , 甚至是用 C 來寫都可以。這裡介紹利用 awk 批次新增帳號的方法。
awk 用來處理有固定格式的資料滿不錯的,我們可以指定要用什麼分隔符號將一行一行的資料分解成各個欄位,然後再這個資訊餵給管理帳號的程式即可達到我們批次管理的需求。
開始當然要知道自己有什麼資料,格式如何?



例如:以下為北市校務行政系統匯出 stu89.txt 資料的樣子
T0002R1 台北市xx區xx國民小學 頁次: 1 - 1
                      列印日期:89/09/06
                      列印時間:15:05:58
學號     姓名     班級      座號
890197    高xx    一年一班    01
890021    高oo    一年一班    02
890164    陳xx    一年一班    03
檔案的前三行為表頭,第四行則為欄位名稱,資料的部份採用的是固定欄寬,每個欄位未使用的部份通通補滿空白字元,這麼有規律,給 awk 來處理,變得很容易。
例如:
把 stu89.txt 上載到 server 的 /tmp 中以後,可以執行:
awk '{print $1 "," $2 "," $3 "," $4 "\n"}' < /tmp/stu89.txt
這樣會輸出:
......略
890197,高xx,一年一班,01
890021,高oo,一年一班,02
890164,陳xx,一年一班,03
awk 預設會以空白字元 (含 Tab) 當作欄位的分隔符號,以前面分解出來的欄位就夠我們在新增帳號的資訊,包括:
  • 帳號名稱 → 學號 (因為帳號不可為全數字的,可前面再加個小寫英文字母)。
  • 群組名稱 → 學號的前二碼 (100學年度以前)。
  • FullName → 班級、座號、姓名。
註:如果我們想以 MS Excel 手動製作類似校務匯出的格式,只要將資料打好後另存新檔,檔案類型選擇『文字檔 (Tab 字元分隔)』,可以得到一樣的輸出結果。

帳號管理的命令及參數

在 FreeBSD 中用來新增帳號的程式有兩個:adduser 和 pw,後者不光是用來新增帳號而已,它是一個完整的帳號管理工具,一行指令即可完成帳號或群組的新增、刪除、修改,也是 ports 中用來新增/刪除服務帳號的預設工具,這裡,我們也選擇它來和 awk 搭配。

新增群組及帳號

FreeBSD 的 /usr/sbin/pw 執行時,後面可接的參數非常多,下面只列出我們應用時會使用的加以說明。
pw groupadd [group]
  • groupadd:這個一看就知道了,代表要讓 pw 執行的是新增群組的程序。
  • group:群組的名稱,命名時一般是以英文小寫字母開頭,其餘用小寫字母或數字,盡量不要使用特殊字元,至於 gid 不指定由 pw 自己計算後再分配。
pw useradd [name] [-m] [-g group] [-c comment] [-b dir] [-w method] [-h fd] [-s shell]
  • useradd:加了這個參數表示要執行新增帳號的程序。
  • name:帳號名稱,以英文字母開頭,後面再接字母或數字,不要用純數字的帳號,以免某些程式會不正常。
  • -m:讓 pw 自動為新帳號建立使用者的個人目錄 (HOMEDIR),並複製預設的檔案 (如果沒有設定 -k ,內定會依 /usr/share/skel 的結構建立)。
  • -g group:group 為使用者所屬的主要群組名稱。
  • -c comment:密碼檔中 comment 這個欄位可存放使用者的相關資訊,最多四項資訊,每項間以逗號隔開,第一項資訊就是我們平時輸入的 FullName。
  • -b dir:dir 為使用者個人目錄的上一層目錄名稱,一般預設為 /home ,我們可以讓同一個群組的帳號放在同一層,例如:s87001 , s87002 都隸屬於群組 stu87 ,我們就指定 -b /home/stu87 讓 s87001 和 s87002 兩個目錄都放在 /home/stu87 中,方便管理。
  • -w method:這個參數是設定密碼產生的方式,method 可以為 no , yes , none , random
    • no:帳號禁止登入。
    • yes:將密碼設為和帳號名稱一樣 (危險,勿用!)。
    • none:將密碼設為空的 (危險,勿用!)。
    • random:以亂數自動產生密碼,產生的密碼會輸出到 stdout。
  • -h fd:這個參數應用在批次新增帳號時很好用,我們利用 -h 0 讓 pw 可以由標準輸入 (stdin) 取得我們要設定的密碼,安全又便利。
  • -s shell:shell 是我們要給帳號登入時使用的 shell 完整路徑,在 FreeBSD 中使用 /bin/csh 就可以,如果沒有指定這個參數,預設的 shell 會是 /bin/sh。

刪除群組及帳號

pw groupdel group
  • groupdel:表示要執行刪除群組的程序。
  • group:為要刪除的群組名稱。
pw userdel name -r
  • userdel:表示要執行刪除帳號的程序。
  • name:為要刪除的帳號名稱。
  • -r:順便刪除使用者的個人目錄 (HOMEDIR)及其它用 -m 建立的相關檔案。

範例

下面的三個小範例所需要的使用者資料檔可以利用北市國小校務行政系統匯出成文字檔的格式(固定欄寬,以空白分隔各欄位),也可以自行用 Excel 製作後另存成文字檔。
資料檔中的使用者資料至少依序提供:學號、姓名、班級、座號等四個欄位,這樣密碼會由 pw 以亂數產生,也可以加上第五個欄位當密碼,如果想調整欄位的順序則自行設定第 21 行開始的各欄位的對映表,$1 , $2 , $3 , $4 , $5 分別代表資料依分隔符號分解完的欄位內容。

批次新增帳號

指令稿

使用方法

假設上面的指令稿以 root 的身份存成 adduser.awk,先將它加上可執行的權限
chmod u+x adduser.awk
如果使用者的資料庫檔為 /root/userdb.txt,就執行:
./adduser.awk < /root/userdb.txt > /root/password.txt
執行完後,新帳號的密碼會存放在 /root/password.txt 中。
新增完要用 vipw 檢查一下是否有使用者的 FullName 變成『○○○』的,表示他的姓名中含有特殊字元,這部份只好手動修改囉!

批次刪除帳號

指令稿

使用方法

假設上面的指令稿以 root 的身份存成 rmuser.awk,先將它加上可執行的權限
chmod u+x rmuser.awk
如果要刪除的使用者資料庫檔為 /root/userdb.txt,就執行:
./rmuser.awk < /root/userdb.txt
其實刪除帳號時,我們只需要一個欄位就可以,裡面就放要被刪除的學生學號清單,一筆一行。

批次新增 samba 帳號

指令稿

這個其實是由 adduser.awk 改過來的,因為新增 samba 的本機帳號到 smbpasswd 中只需要帳號和密碼兩個欄位,所以看起來更簡單。使用時別忘了要修改 smbpassword = $1 這行,指定想當密碼的欄位。

使用方法

假設上面的指令稿以 root 的身份存成 smbadduser.awk,先將它加上可執行的權限
chmod u+x smbadduser.awk
如果使用者的資料庫檔為 /root/userdb.txt,就執行:
./smbadduser.awk < /root/userdb.txt

已知問題

  • 因為欄位間的分隔符號預設為空白字元,有的人姓名的部份中間會用空格補字,這可能會造成分解欄位時的錯亂。
  • 當使用 FS = "," 也就是以逗號為分隔符號時,匯入的使用資料庫第一筆總會解析錯誤,目前的解決方法是在資料庫的第一行只放個井字號,讓它自動跳過去。
  • pw 的參數有些會檢查是否含特殊字元,像姓名就不能帶有冒號、驚嘆號及小老鼠,但是中文字裡有一些字就是會有,只好在送給 pw 執行前先檢查,暫時將可能出錯的姓名改用其它符號代替,自己再用 vipw 去修改密碼檔吧。
  • 本來 smbadduser.awk 的功能是整合在 adduser.awk 中,執行完 pw 後,接著 smbpasswd 執行時,/etc/passwd 中居然還沒有更新,以致無法新增 samba 的帳號,所以才分家,問題還沒找到。

參考資料

  • man pw
  • man smbpasswd
  • man awk

留言

這個網誌中的熱門文章

十四、NAS4Free 新增一ZFS磁碟機