交集/聯集/差集


comm 這個指令可以用來求交集/聯集/差集, 很多場合下非常好用。

新增帳號

我在 Linux 主機上面為上課同學建立帳號。 在樹德資工, Linux 的使用狀況目前並不熱烈, 所以只有修課的同學才開帳號。 假設目前已有 這樣的 /etc/passwd, 現在新學期新增 AB 兩班, 如何一口氣為這兩班當中, 所有尚未有帳號的同學建立帳號?

        sed 's/:.*//' class_a.txt | sort > a
        sed 's/:.*//' class_b.txt | sort > b
        sed 's/:.*//' passwd | sort > pwd
        comm a b | perl -pe 's/^\s+//' > c
        for u in $(comm -1 -3 pwd c); do useradd -g users $u ; done

封鎖太久沒有用的帳號

閒置不用的帳號, 是 cracker 入侵的最佳跳板之一。 不妨在每個月底查看一下: 有那些人在過去一個月之中, 從來不曾登入過? 把這些帳號全部封鎖起來, 以提高系統的安全性。

        last | perl -ne 'print "$1\n" if /^(s\d+)/' | sort | uniq > ever
        perl -ne 'print "$1\n" if /^(s\d+)/' /etc/passwd | sort > all
        comm -3 all ever > never
        for u in $(cat never) ; do chsh -s /sbin/nologin $u ; passwd -l $u ; done

這裡做了雙重防護措施: passwd -l 封鎖密碼檔, 沒有任何密碼可以進入, 只有 root 可以直接 su 切換進去; chsh -s /sbin/nologin 更徹底, 把 shell 改掉, 連 root 都進不去。

如果覺得一個月的時間太短, 給自己徒增麻煩, 或許可以修改 /etc/logrotate.conf 將 wtmp 與 lastlog 的 "monthly" 欄改成 "size=3M" 之類的。 如果希望將 「封鎖帳號」 的工作自動化, 一樣可以靠修改 logrotate.conf 完成: 只要加一段

        prerotate
        ... (上述指令) ...
        endscript

好吧, 自己招認了, 這裡其實是無病呻吟, 是為賦新詞強說愁。 如果改用 lastlog 指令, 前三句其實可以縮短成一句: lastlog | perl -ne 'print "$1\n" if /^(s\d+)/.*Never logged in' > never

兩系統安裝相同套件

我有好幾部電腦 (浪費資源, 汗顏...), 每次升級 Linux 都要花不少時間安裝作業系統。 雖然現在的安裝還蠻方便的, 但點選自己有興趣的套件還是蠻花時間的工作。 畢竟, 重複, 機械化, 有規律的動作, 就不應該是人做的事! 用滑鼠來做, 而且根據不同的心情及不完整的記憶, 在不同時間地點安裝, 所點選的套件可能有些出入。

不管您的系統配置是否 和我一樣, 總之假設已有一套安裝完備, 正常運作的系統。 在上面下 rpm -qa | sort 得到 列表-A。 現在在第二部機器上選擇最小安裝, 並一樣執行 rpm -qa | sort 得到 列表-B。 前者是花了很多時間增刪套件的辛苦結晶; 後者則是目前安裝的狀況。

rpm -e $(comm -1 -3 rpm-qa-A.txt rpm-qa-B.txt)
urpmi $(comm -2 -3 rpm-qa-A.txt rpm-qa-B.txt)

當然真實狀況可能稍微複雜些, 例如有些套件可能不是安裝光碟上原本就有的, 而是自己找來的。 這時就需要多做幾次集合運算, 同時無法用 urpmi , 而必須下 rpm 指令。 當然 rpm 指令後面要接的是檔名而不是套件名稱, 所以 regular expression 就非常有用了。

妥善維護你自己的 「標準套件列表」 (例如叫做 mdv-06.txt), 以後在其他機器安裝相同版本的 Linux 時, 會很方便。 有時不同的機器, 我們還是希望安裝少許不同的套件 例如我經常帶筆記電腦出去演講, 特別喜歡向小學老師介紹 gcompris; 但其實平常自己並不需要用, 所以辦公室的機器並沒有安裝; 這個套件及其他相依套件, 也就沒有收錄在 mdv-06.txt 裡面。 現在若在一部非標準的機器上, 新增了一些 「適用於所有機器」 的套件, 要如何將這些新套件加入 mdv-06.txt? 例如想在這部筆記電腦上安裝媒體播放程式 xine 及所有相依套件, 同時也提醒自己: 其他電腦也需要裝這些套件。 在這部 「未按照列表安裝套件」 的筆記電腦下 rpm -qa | sort 出來的結果並不適合拿來取代原來的 「標準套件列表」。 此時可以找出所有 "最新安裝的套件", 只把這些套件加入 mdv-06.txt。 安裝新套件之前先下: rpm -qa --qf '%{INSTALLTIME} %{NAME}-%{VERSION}-%{RELEASE}\n' | sort, 特別注意最後兩三個套件名稱, 這些是最後安裝的套件。 下 urpmi xine 安裝 xine 及所有相依套件之後, 再下一次上述的 rpm -qa --qf ..., 將之存檔, 例如叫做 by_time.txt。 手動編輯 by_time.txt 只留下最下面數個新安裝的套件, 最後 sort by_time.txt mdv-06.txt > mdv-06.new.txt 產生新的列表。