用 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
。
環境變數
- money: P 幣數量,必須大於零。
- after_tax: P 幣計算稅後,預設是稅錢,只要不是空字串就代表計算稅後。
- username_list: 要發的 id 列表,可以用空格或換行或 tab 分割。 優先順序是環境變數、參數、stdin。
- user_interval: 發一位使用者後會停多久, 預設是 2,預設單位是秒,也可以傳 1m 就變成停一分鐘。
- ptt_pane: ptt 發錢畫面的 tmux window,預設是 0。
- script_pane: 腳本執行的 tmux window,預設是 1, 只是跳回去後讓你可以 ctrl-c 中斷用的。
如果要批次作業,就要先開好 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, 雖然不複雜,但實在很沒必要。