用 tmux 在 ptt 發錢

最近因為好玩,想試試發錢要鄉民去噓別人的文, 於是之後兌現承諾發錢時,試了 mumi 發錢程式 有問題, 所以 自己用 tmux 和 ssh 當介面 寫了個簡單的 shell script 來發錢 。 這個 script 大概是我認同的 shell script 風格吧, 用了很多我流的奇淫技巧。

使用方法

要先有 tmux,在 window 0 連上 ptt, 進入發 p 幣的選單, 然後可以在 window 1 執行這個腳本。 這個腳本有互動介面,所以什麼選項都不給還是能正常運行, 腳本缺的變數就會要求你輸入。

執行就是 sh tmux-give-p.sh 10 iXXXXGAY5566 seabox freeunixer RS5566 , 第一個參數是稅前 P 幣,後面是要送的 id, ptt 不分大小寫,所以可以一律小寫。 或是 id 也可以從 stdin 送進去,一行一個 id。

sh tmux-give-p.sh 10 <<USER_LIST
iXXXXGAY5566
seabox
freeunixer
RS5566

USER_LIST

然後會要求你輸入 ptt 密碼, 密碼不能放在參數傳,因為會被 top ps pgrep 看到。 所以我是用 tmux 的 buffer 存。 又基於腳本要可以批次操作, 你也可以事先存在 tmux 的 ptt_password buffer。 就不會要求輸入,可以直接開始發錢。

每發一個人會切回 window 1, 所以如果出錯可以按 ctrl-c 中斷。 但我沒有做很完整的判斷, 如果出什麼意外可能會在 ptt 亂輸入一堆東西。

另外這腳本可以很大程度由環境變數改變行為, 像如果要算稅後,可以 after_tax=1 sh tmux-give-p.sh 10 錢、使用者名單也都可以從環境數傳 money=10 username_list='seabox rs5566' sh tmux-give-p.sh

環境變數

如果要批次作業,就要先開好 tmux, 在 window 0 連上 ptt 進到發錢介面, 然後把密碼存到 tmux buffer, 像是 pass show ptt | tmux load-buffer -b ptt_password - , 再執行這個腳本,id 建議用 stdin 傳,比較不會被限制長度。 cat userlist | sh tmux-give-p.sh 10

如果什麼參數都不給,就會要求你輸入要發的 P 幣, ptt 密碼,之後要求你一行行輸入 id。 另外把 tmux 開起來後,也可以在另外的終端機執行這個腳本, tmux 好像會自己找到自己。

腳本技巧

最近我寫程式最大的關注是 如何讓使用者在無需改寫原始碼的情況下, 改變程式行為;也就程式的重用。 例如 emacs 的 emacs lisp 就在這點下了很大心力, 你可以用 hook advice 來在不更動原始碼的情況下, 改變某些函數的行為。

我大量使用了 set_if_empty 這個函數, 也就是在 script 裡不直接指派值給變數, 而是先檢查外部有沒有給值,沒有再指定。 因為 shell 裡在讀取變數時, 變數和環境變數是沒有差異的。

之前學 common lisp, 有個 defparameter 就是類似的意思, 定義一個參數,但可以被其它 defparameter 改變。 在 Makefile 或 C 的巨集裡,好像也有類似的語法。

現在寫腳本,如果是可以改變的參數, 我都會用 set_if_empty 來定義, 執行時如果想改可以直接傳環境變數覆寫。

使用環境變數

雖然 unix 風格是以 - 開頭的參數當作選項, 來改變程式的行為。 但用選項來傳遞參數實在是很麻煩, 要考慮短選項長選項,有時 - 又會被當作 stdin stdout, 不然就是用 getopt 來解析參數。 總之,用連字號傳參數寫起來一點都不直覺, 所以我決定以後都直接用環境變數來傳參數。

環境變數也不像參數會有順序問題,也不像選項要解析, 什麼變數要是什麼值,直接傳就好了。 像 javascript 中某些行為很麻煩的函數, 就直接傳一個參數物件進去, 用環境變數也是差不多的意思, 像傳一個 key value 集合。 又 shell 取用環境變數也很簡單,以 shell 的風格, 直接走最簡單直接暴力的作法就對了。

緣起

最近幾個月 ptt 在流行 搶第 777777 篇文章 , 搶到的人都會被推爆,還會被要求發錢。 對這行為有點反感,所以之後想試試在 777777 前後發一篇文, 發錢請鄉民在 777777 文章下面噓文, 看能不能把推爆變噓爆。

但後來剛好看到一篇沒什麼意義的發錢文, 就在他之後發了文章後要求鄉民去噓他, 可惜沒有成功,因為發錢文大部份都會推超過 100, 我後來統計有 173 噓,但扣掉後還是有二十幾推, 還是不到噓爆。

但不知道為什麼一堆人噓我,噓我又沒錢, 可能看不爽我要鄉民去噓別人吧, 或是單純看到噓就被當成 討噓文 。 後來那篇文章作者也來我的文章噓, 說他不能噓自己,能不能多少給他一點; 把他的爆文噓掉也不太好意思,發一點錢給他也剛好而已。

ptt 應該內建群組發錢功能

雖然可以用 tmux 解決, 但最簡單的作法還是 ptt 開個批次發錢的功能。 站內信都可以群組寄信了, 做個批次發錢的功能應該也不難吧。 不然大家都自己 hack, 雖然不複雜,但實在很沒必要。