分類
软件

觀鳥輔助工具 whoBIRD

whoBIRD可以在手機離線的情況下,根據當前地理位置和所處時間通過 BirdNET 訓練的模型識別鳥叫。有時候用眼睛找鳥是很困難的,但是有 whoBIRD 的幫助,會更容易分辨是自己已知的鳥類還是一個叫聲很相似,但是是不同的鳥類。對於新到一個地方有很多未知鳥類時也很有幫助。如果當時手機有網絡,還能直接顯示出鳥的照片。當然也可以等手機有網絡後從歷史記錄里慢慢查看之前聽到了什麼鳥叫。

分類
Linux 软件

使用 nginx 代理 NextDNS 的 DoH 服務

免費版的 NextDNS 每個月有 300,000 次請求,個人一般是夠用的。通過 nginx 代理其 DoH 服務可以用自己的域名來使用 NextDNS 的服務。Nginx 配置文件 /etc/nginx/conf.d/MY.DOMAIN.conf 如下:

# Cache the dns query
proxy_cache_path /var/cache/nginx/dns levels=1:2 keys_zone=dns_cache:10m max_size=1g inactive=1d use_temp_path=off;

server {
    server_name my.domain;

    root /usr/share/nginx/html;

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/my.domain/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/my.domain/privkey.pem; # managed <p>by</p> Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    http2 on;
    resolver 45.90.28.136;

    location /YOUR_DNS_QUERY_PATH {
        proxy_pass https://dns.nextdns.io/YOUR_ID/YOUR_TAG;
        proxy_set_header Host dns.nextdns.io;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache dns_cache;
        proxy_cache_valid 1d;
        proxy_cache_use_stale error timeout updating;
    }
    
    location / {
    }
}
server {
    if ($host = my.domain) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen [::]:80;
    server_name my.domain;
    return 404; # managed by Certbot


}

Nginx 搭配 Cerbot 獲取免費證書請參考:網站用上了letsencrypt的免費ssl證書

搭建完成後可以通過 curl 來檢查服務是否正常:curl -H 'accept: application/dns-json' 'https://my.domain/YOUR_DNS_QUERY_PATH?name=ft.shaman.eu.org&type=A'

使用 personalDNSfilter 以在安卓手機上使用 DoH

使用 personalDNSfilter (去 F-droid 下載)實現的本地 VPN 來修改系統的DNS查詢,它同時還能攔截廣告。配置非常簡單,只需要在 DNS 配置欄選中禁用 DNS 服務器查找,選中文本編輯模式,並在輸入框中加入下面一行並啟用即可。

[MY.SERVER.IP]::443::DOH::https://my.domain/YOUR_DNS_QUERY_PATH

也可是使用重一點的 Rethink 來管理 DNS。加入自己的 DoH 也很簡單。選擇 Other DNS,DoH,新增。名稱隨便,Resolver URL 填:https://my.domain/YOUR_DNS_QUERY_PATH 即可。

在 Xfce 口味的 Fedora 上使用 DoH

似乎是沒辦法直接在圖形界面上進行設置。我最終是用熟悉的 dnscrypt-proxy 2 來代理。不熟悉的朋友請參考:Fedora 使用 DNSCrypt。只需要修改三處文件即可:

#file:dnscrypt-proxy.toml

#設置 server_names,默認是注釋掉的
server_names = ['mydns']

#如果在中國,可以把 bootstrap_resolvers 設置成 114
bootstrap_resolvers  = ['114.114.114.114:53', '8.8.8.8:53']

#拉到文件底部,添加這兩行
  [static.mydns]
  stamp = 'sdns://AgAAAAAAAAAABzEuMS4xLjEACW15LmRvbWFpbhQvWU9VUl9ETlNfUVVFUllfUEFUSA'

stamp 的生成請打開這個網頁:Online DNS Stamp calculator Protocol 選擇 DoH,IP 寫 IP,Host 寫域名,Path 寫/YOUR_DNS_QUERY_PATH ,然後複製生成的 Stamp 就可以了。

今天是 2024 年 4 月 1 日,看看自己域名的 DoH 可以存活多久。安卓網絡設置里雖然可以直接指定 DoT,NextDNS 的 DoT 也可以用 Nginx 代理,但是感覺陣亡幾率更大(專用端口),所以我選擇了更穩妥一點的 DoH。

2024-04-05: 移動網絡偶爾出現 SSL handshake timed out IO Error occured! Check network or DNS config! 和 Read timed out IO Error occured! Check network or DNS config! 但是還是能用。

2024-04-06: 晚上移動網絡開始出現 SSL handshake aborted: ssl=0x7b2db05fc8: I/O error during system call, Connection reset by peer IO Error occured! Check network or DNS config! 基本用不了了。之間訪問網站也顯示 The connection was reset 。所以清明節沒過完域名就掛了,存活時間約 5 天。如果想要繼續使用被屏蔽的域名,或者直接使用 NextDNS,無論是 DNSCrypt 還是 personalDNSfilter 都支持代理。一息尚存的 DNSCrypt 內置不少 DNS,還可以在不用代理的情況下使用。

2024-04-15:偶爾外出就餐時連接餐廳的 WiFi,發現電信的寬帶仍然可以使用。但是移動網絡和移動寬帶已經完全無法連上。


另請參閱:使用 Python 或/和 Cloudflare Worker 代理 NextDNS 的 DoH 服務

本文更新於 2024/04/24。

分類
Linux

Fedora 39 Xfce tricks

前段時間用了一些 KDE 團隊開發的應用,又聽說 Linux 界的安卓模擬器新星 Waydroid 很厲害,於是裝個 KDE Plasma 體驗。結果離開了 X 才只知道 X 的好!KDE Plasma 在默認配置下,瀏覽器播放視頻會有輕微卡頓,如果快進快退則卡頓感更加明顯。而且原來可以輕鬆設定的全局熱建,搜索一通居然發現無法實現!在英文系統里裝中文輸入法,也是個痛。所以用了一天時間就跟這酷炫的桌面拜拜了——裝回了順手的 Xfce。

多媒體工作站

	
sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm

sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo sh -c 'echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/vscode.repo'

dnf check-update
sudo dnf install code vlc ffmpeg libreoffice calibre

安裝拼音輸入法

Applications > Settings > Input Method Selector,選擇 Use IBus。然後點擊旁邊的 Preferences 打開 IBus 的設置。

在 General 標籤頁可以將候選詞設置為橫排(默認為豎排)。在 Input Method 標籤頁點擊 Add 按鈕添加輸入法(選擇 Chinese > Intelligent Pinyin)。添加後選中拼音輸入法,在點擊右邊的 Preferences 可以設定拼音輸入法,比如候選詞數量、候選詞翻頁按鍵、字典詞庫以及中英文切換鍵等。設置過程中如果有問題,可能是需要登出一下才會生效。

調大字體

歲月不饒人,雖然屏幕是 1920*1080 全高清,但是字體顯示真的有點小,看久了會累。在 Applications > Settings > Apperance 中的 Fonts 標籤頁可以設置 DPI,改為 119,字體大小就舒服多了。Style 標籤也有很多主題,但是丑的居多,個人覺得默認的 Adwaita 確實已經是最好看的了。在 Applications > Settings > Window Manager 中也可以設定窗口樣式,推薦大家試試 Mint-Y-Aqua。

睡眠模式掉電快

在我的電腦上,默認的睡眠模式是 s2idle,如果想要在睡眠時省電,需要改成 deep 模式。

#查看當前模式
cat /sys/power/mem_sleep
#可能會輸出 [s2idle] 或[s2idle] deep
#通過下面命令設定成 deep 模式
echo deep | sudo tee /sys/power/mem_sleep
#再次查看 /sys/power/mem_sleep
#應該變成 s2idle [deep]
#此時可以嘗試睡眠觀察一下電量消耗
#如果沒有問題,還需要通過下面命令將這個模式保存下來

#打開 /etc/default/grub 文件
sudo nano /etc/default/grub
#找到 GRUB_CMDLINE_LINUX= 開頭的一行
#有的系統是 GRUB_CMDLINE_LINUX_DEFAULT= 但是沒關係
#這行中一般都還有一個關鍵字 quiet
#在這行的末尾,引號前加入
 mem_sleep_default=deep
#然後保存文件
#最後執行下更新啟動項
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

Virtual Box

使用sudo dnf install VirtualBox virtualbox-guest-additions即可安裝 VirtualBox,現在最新版是 7.0 。安裝後進入虛擬機發現共享文件以及顯示縮放都不能用。原來是自動下載失敗了,需要手動下載虛擬機增強插件 ISO。從 https://download.virtualbox.org/virtualbox/7.0.14/VBoxGuestAdditions_7.0.14.iso 下載後,掛載上就可以在虛擬機里安裝增強插件了。


其他小撇步另請參考:Fedora Workstation Tricks

本文更新於 2024/03/16。

分類
Linux 软件

Turmux X11 以及 VSCode

本篇文件介紹如何在安卓手機上運行 VSCode 來實現在旅途中繼續編碼。我使用的手機是 2018 年的 Xperia XZ2,內存只有 4GB,CPU 型號是 Qualcomm SDM845,屏幕是 5.7 in (140 mm) 1080p (2160 × 1080) IPS LCD, ~424 pixel density。最終效果如下:

VSCode On Debian With Termux

藉助 Termux 我們得以在安卓上運行多種 Linux,之所以選擇 Debian 是因爲它相對輕量且不含 systemd (安卓不支持)。本文得以形成主要是參考了 Termux X11:手機的X伺服器使用教學Android手機安裝Linux發行版:Termux proot-distro使用教學 以及 VSCode installation tutorial with Termux-x11,在此一併感謝!

如果你的手機性能良好,推薦按照 Ivon 的文章安裝 Xfce4 桌面環境,這樣東西就一應俱全了(除了不能運行 Docker,安卓內核不支持)。

安裝 Termux

雖然可以直接去 Github 下載安裝包,但是還是建議去 F-Droid 安裝Termux。當前的最新版本是 0.118.0。安裝完成後執行下列命令:

pkg update
pkg upgrade
pkg install nano proot-distro x11-repo termux-x11-nightly
termux-setup-storage

安裝 X11

這裏需要到 Github 下載 X11 的安裝包。如果沒有 Github 賬戶,可以從這裏下載我安裝的這個版本。

安裝 Debian

手機性能好的話,可以嘗試其他口味的 Linux 以及桌面環境。我的手機連 Xfce4 也運行不起來(X11 裏可以,但是 Debian 裏就會自動退出),所以我使用輕量的 openbox。

proot-distro install debian
#進入 Debian
proot-distro login debian
apt update
apt upgrade
apt install nano sudo wget git
#添加普通用戶
passwd
groupadd storage
groupadd wheel
groupadd video
#替換 [USER] 爲你想要的名字
useradd -m -g users -G wheel,audio,video,storage -s /bin/bash [USER]
passwd [USER]
visudo
#在 root ALL=(ALL:ALL) ALL 這行的後面添加
[USER] root ALL=(ALL:ALL) ALL
#保存後使用 exit 退出 Debian

創建兩個腳本來啓動和關閉 X11:

##以下是startDebian.sh
#!/bin/bash
export DISPLAY=:0
killall -9 termux-x11 termux-wake-lock
# 啟動Termux X11
am start --user 0 -n com.termux.x11/com.termux.x11.MainActivity
XDG_RUNTIME_DIR=${TMPDIR}
termux-x11 :0 &
sleep 3

proot-distro login debian --user [USER] --shared-tmp
##以下是stopDebian.sh
#!/bin/bash
killall -9 termux-x11

然後給予可執行權限:

chmod +x startDebian.sh
chmod +x stopDebian.sh
#然後執行 startDebian.sh 就能就如 Debian 了
./startDebian.sh
#若出現報錯 ERROR: openbox-xdg-autostart requires PyXDG to be installed 可以按回車鍵忽略
#安裝窗口管理器
sudo apt install xorg openbox
sudo apt install firefox-esr fonts-noto-cjk proxychains4 curl tint2 xclip pcmanfm
#火狐:你需要一個瀏覽器
#fonts-noto-cjk:字體
#proxychains4:沒有代理不科學
#curl:安裝 curl 可以修復使用 proxychains4 時 library "libdl.so.2" not found 的錯誤
#tint2:任務欄讓桌面更美好
#pcmanfm:桌面環境怎能少得了文件管理器
#xclip:把剪切版的內容從安卓傳遞到 Debian

# .bashrc 中添加下面文本

alias pp='termux-clipboard-get | xclip -sel clipboard'
alias p='proxychains4'

export DISPLAY=:0
if ! pgrep -x "openbox" > /dev/null; then
    openbox-session &
    tint2 &
fi

安裝 VSCode

前往 VSCode 下載頁,下載 Arm64 版本的 .deb 安裝包。可以通過瀏覽器下載,然後下載頁會有下載的直鏈,複製後用 wget 下載就好。

#安裝 VSCode
sudo dpkg -i /sdcard/Downloads/code-[VERSION].deb
#如果出現報錯嘗試
sudo apt --fix-broken install
#然後再試試上面的 dpkg 安裝指令

最在啓動欄創建兩個常用的快捷啓動方式:先修改下桌面快捷方式

#把 /usr/share/applications/code.desktop 中的
Exec=/usr/share/code/code --unity-launch %F
#改爲
Exec=/usr/share/code/code --no-sandbox %F

#把 /usr/share/applications/firefox-esr.desktop 中的
Exec=/usr/lib/firefox-esr/firefox-esr %u
#改爲
Exec=/usr/lib/firefox-esr/firefox-esr --no-sandbox %u

兩個手機點一下桌面(黑屏)呼出右鍵菜單,選擇 Applications > Settings > Tint2 Settings 。點擊左上角編輯,Panel 推薦設置在左邊,length 150%,size 60 pixels。Panel items 留下 Launcher 和 Taskbar 即可。Lanucher 裏選擇 VS Code 和 Firefox ESR 保存即可。

既然提到了命令行啓動火狐,順便記錄下火狐的多用戶。在命令行加上 -P 可以啓動 Profile 管理器。在管理器裏可以新增、重命名以及設置默認的用戶。想以用戶 42 啓動,則把上面快捷方式裏的運行項改爲 /usr/lib/firefox-esr/firefox-esr --no-sandbox -P 42 %u 即可。

Firefox 在 A Profile 升級後,从 B Profile 啟動可能會出現問題:"You've launched an older version of firefox" "Using an old version of Firefox..."。此時可以在啟動命令後加上 -allow-downgrade 就可以啟動了。然後關閉火狐就可以正常啟動了。

使用場景

開始使用

  1. 啓動 Termux
  2. ./startDebian.sh

退出

  1. 切換到 Termux,執行 exit
  2. ./stopDebian.sh

其他小撇步

字體非常小:在 Debian 家目錄新增文件 nano ~/.Xdefaults 內容爲 Xft.dpi: 192 即指定 dpi 分辨率爲 192。如果個別應用字體還是很小,可以嘗試通過應用自己的配置來調整顯示大小。顏色深度也可以在這裏配置,例如:Xft.depth: 16

剪切版:從 Debian 到安卓默認是沒問題的,除非你在 X11 的配置項裏禁用了。但是從安卓到 Debian 卻不輕鬆。目前一個可行的方案就是上面使用 xclip 的方式:首先切換到 Termux,運行 alias pp,然後就可以在 Debian 裏粘貼了。

中文輸入:本篇沒有安裝中文輸入法,以節省更多資源予 VSCode。

掛載外部 SD Card 到 Debian:啓動時加入 --bind /data/data/com.termux/files/home/storage/external-1:/sdcard1 就會將外部儲存卡的可用目錄掛載到 proot 系統裏的 /sdcard1。手機裏的內部儲存默認是掛載在 /sdcard 的。

時間來到 2024 年底,Copilot 不使用代理已經無法登錄和使用了。雖然 VSCode 的配置項中可以設置代理,但是如果想讓 Copilot 走代理則需要使用 http 類型代理且在設置中將 Proxy Support 從默認的 override 切換為 on。這樣就不會再出現Extension activation failed: "tunneling socket could not be established, cause=socket hang up這個錯誤了。

本文更新於 2024/11/21。

分類
Linux

使用 xinput 映射鼠標按鍵

鼠標左鍵故障無法使用了,可以使用 xinput 將其他不常用的按鍵映射爲左鍵。Fedora 的 Xfce 桌面環境沒有默認安裝 xinput,需要手動安裝一下。

sudo dnf install xinput
#查看設備列表
xinput list
#比如我的鼠標會找到
Bluetooth Mouse M336/M337/M535 Mouse    	id=20	[slave  pointer  (2)]
#後續操作使用 20 和 Bluetooth Mouse M336/M337/M535 Mouse 都可以
#查看此鼠標當前的按鍵映射配置
xinput --get-button-map 'Bluetooth Mouse M336/M337/M535 Mouse'
1 2 3 4 5 6 7 8 9 10 11 12
#查看當前鼠標按鍵
xinput test 'Bluetooth Mouse M336/M337/M535 Mouse'
#當你操作鼠標時機會顯示哪個按鍵有動作
#通過映射拯救左鍵
xinput set-button-map 'Bluetooth Mouse M336/M337/M535 Mouse' 1 1 3 4 5 1 1 1 1 1 1 1
#我把不常用的鍵都指定成左鍵了
#測試沒有問題後可以將映射的指令添加到開機啓動裏
#Applications > Settings > Session and Startup > Application Autostart
/usr/bin/xinput set-button-map 'Bluetooth Mouse M336/M337/M535 Mouse' 1 1 3 4 5 1 1 1 1 1 1 1

用了一小段時間後發現,似乎鼠標滾輪也不是很好,所以最終在屋裏找到另一隻鼠標後,放棄了這隻。建議大家旅行時攜帶鼠標最好有個盒子,免得擠壓導致鼠標死亡。

分類
软件

nginx 默認配置下載文件 403

裝了個 nginx 臨時分享一下文件,但是文件複製到 /usr/share/nginx/html 中後訪問卻提示 403。排除防火牆、文件權限和所有者的問題後,發現是 SElinux 的原因。

#查看 SELinux 上下文
ls -lZ
#大概是這樣的
-rw-r--r--. 1 root root system_u:object_r:httpd_sys_content_t:s0     3086 Jan 28 13:39 index.html
-rwxr-xr-x. root root unconfined_u:object_r:user_home_t:s0 ToBeShared.zip
#只要 user_home_t 改成 httpd_sys_content_t 就可以了
sudo chcon -t httpd_sys_content_t ToBeShared.zip

更多參考:Nginx 403 error for single file while others workSELinux documentation from RedHat

分類
讀書

我成了故鄉的臥底

田園將蕪

——後鄉村時代記事

作者:江子

ISBN:978-7-224-10540-7-

江西人民出版社


從外表看,我已經與一名城裡人無異。

我也算得上是衣冠楚楚。我的皮膚也還白皙。我的普通話還算流利。我保持著城市的許多生活習慣:出門頭髮梳得整齊,喜歡喝點好茶和咖啡。我走起路來和城裡人一樣快慢有致。我還喜歡看碟,聽音樂,對足球也說得上愛好,床頭上堆著一些與精神有關的書。必要的時候,我還能說上幾句這座城市的方言,短時間內一般不會露出漏洞,對我不熟悉的人,完全可能把我當作土生土長的本市人。

可我是農民的後裔,是一個生活在城裡的鄉下人。在許多表格關於籍貫的一欄裡,我寫的是與我所在的城市不一樣的一個地址﹁吉水﹂——距離我居住的城市二百公裡之遙的南方小縣。而若干年前,我在吉水工作時,寫的是﹁楓江鎮下隴洲村﹂。

那是吉水贛江之濱的一個村子。除了求學,我的童年和少年都在那裡度過。那裡至今住著我的父輩和兄弟。從這個村莊出發,我的親友遍布故鄉的山山水水。得益於國家早年沒有來得及實施計劃生育政策,祖輩強大的生殖力衍生了故鄉龐大的親系。

他們是卑微的、底層的一群,是大地上匍匐的一群。他們多麼渴望在天空中飛翔——城市就是他們常常窺視、仰望的天空。從農村包圍城市,是我的故鄉世世代代不死的心。城市擁有任何時代都是最好的物質和精神資源:高層的行政機關,先進的醫療、教育、物流、文化體系。因為求學、患病、購物或者厄運,他們暫時離開了鄉村,坐火車或汽車,沿著血脈的通道,秘密潛人城市,與我會合。鄉音或者他們口中的我在鄉村粗鄙難聽的乳名,就是接頭的暗語。

他們是我的另一個組織,掌握了我的血脈、出身甚至更多的秘密檔案。我其實是他們安排在這座城市的臥底,是潛伏在城市內部的、為故鄉工作的地下工作者。我的衣冠楚楚人模狗樣從另一個角度上來說,不過是為了便於開展工作的一種化妝術。一名潛入城市的臥底,就是我在故鄉的組織掌握的檔案上的真實身份。


那個人站在那裡,手足無措。那個人無論頭髮臉龐和衣著,都與那座很歐化的拱形的大門外觀和來來往往的高檔車輛極不相稱。那個人頭髮蓬亂,皮膚粗糙黝黑,面色愁苦,鬍子拉碴,皺巴巴的襯衫有一塊明顯的印記——顯然那是不習慣出遠門暈車嘔吐的痕跡。那個人的手裡提著一個髒兮兮的蛇皮袋,背上背著一床被子,被面的花色是嶄新而豔俗的那種。那個人的樣子就像一個難民。他的旁邊,是他的兒子,兩手空空,卻因為和他的難民父親站在一起感到尷尬萬分。

他是我的姨父。站在他身邊的是我的表弟。姨父看見我,臉上露出了沒有被人察覺的笑意。他的神情看起來有些激動,但是他並沒有像在故鄉的路上遇見時那樣大叫大嚷,而是竭力保持著克制。待我走近,他顯得訓練有素地慢慢伸出了手,輕輕地用鄉音喚了我一聲——就像電影裡組織派來的人與地下黨員在敵佔區秘密接頭一個樣。

姨父生了兩個兒子。他靠著種幾畝地和做點小生意供兩個兒子上學。大兒子今年高考落榜,可他還想上學。前些日子,姨父從家鄉打電話給我,問我有沒有什麼辦法,讓表弟在省城上一所民辦大學。我說乾脆讓他出去打工算啦,去民辦大學上學能讀到什麼東西?再說那該要老大一筆錢呢,您現在負擔那麼重。可姨父說兒子想讀,做父母的,就成全他麼。從電話裡聽得出,姨父有一種為了兒子豁出去的悲壯意味。

我知道這是我的組織交給我的任務。我必須充分利用我的城裡人身份來完成它。接到姨父的電話以後,我費勁了心機搞到了這座城市幾乎所有民校的情報,內容從建校歷史、學校規模、師資力量、專業結構、收費就業情況等無所不包。最後,我把目標鎖定了市郊一所據說就業率 98% 以上的大學。其實所有的民辦高校只要給錢就能上,但我不能讓姨父把辛辛苦苦積攢的錢往水裡扔。

在單位隔壁的飯館裡,我叫了兩瓶啤酒,姨父說路上車暈得厲害,什麼也吃不下。他幾乎沒動什麼筷子,只是一根接一根地抽菸。倒是表弟一個人自斟自飲把兩瓶啤酒幹了。我想,即使不暈車,這檔兒他也不會有什麼胃口—這座於他缺乏把握能力的城市危機四伏,對表弟前途命運的擔心顯而易見。再說了,每年上萬塊錢的學費,對他也不會是一個小數目。

我領著父子倆打車來到了那所大學報名處。正是報名的高峰時期,校園人山人海。姨父躲到偏僻處,費力地從縫合在褲子上的口袋裡掏出一疊皺巴巴的錢來。辦完手續,手中的錢變成了幾張輕飄飄的收據。我看見姨父的臉虛弱蒼白,手還有些抖。正是炎熱的九月天氣,他不停地用衣服的下擺擦著汗。很多衣著光鮮的人從他面前走過,露出了鄙夷和警惕的表情,仿佛他是一個被繳了械的俘虜。姨父告訴我,學費中的很大一部分,是借來的,要三分的利息。我說那該還到猴年馬月?他咬咬牙說,什麼時候還得清先不管,兒子讀書要緊。

報完名,姨父就要回去,農活不能耽誤,好幾丘田等著灌水呢。他反覆囑咐兒子,囉裡囉唆,表弟都有點煩了。——我盯著表弟不耐煩的臉色,心想,如果這傢伙做了一名城裡人,早晚會成為故鄉的叛徒。

姨父當天來當天回。他坐上回家的班車的時候,天已經全黑了。


我不認識眼前的這個人,雖然他有著和我的故鄉契合的表情和裝束,不同之處是他手裡拿著一張 X 光片。這張 X 光片此次變成了我和故鄉在城裡接頭的暗號。他是我舅舅的﹁特派員﹂。這個在牛皮紙信封裡半露半藏的膠片上記錄了舅舅的腰椎。舅舅是個泥瓦匠,在縣城的某個工地上打工。春節去給他拜年時得知他在縣城幹得不錯,比在家種幾畝地時強很多。可就在前幾天,他不小心從腳手架上摔下來,腰椎斷了。眼前的這個人是他工地上的工友。舅舅讓他帶話給我,要我去問省城的醫生能否不做手術,因為做手術會花光他全家僅有的存款,兩個孩子在縣城讀書就會成為問題。

我從紙袋裡取出這張片子,在陽光下觀望。我看不懂這片子的受傷情況,但我知道,那裡藏著我的舅舅—媽媽的弟弟的腰椎骨胳,它記錄了一個底層人的、靠手藝生活的莊稼漢的、很可能使他永遠失去勞動能力的一次事故。它是來自故鄉關乎命運的一張秘密圖案。

我帶著舅舅的工友來到單位附近的一所大醫院。已是下午四點,專家門診空無一人,我只好衝進了住院部,找到一名正在值班的骨科專家。我要讓我在不暴露身份的情況下從他的嘴中撬出有用的情報。我去買了一盒價格不菲的香菸—某種程度上它可以是一張城市通行證,也是一張名片,用來證明我城市人的身份。我客氣地給他點了煙,並開始運用與城裡人交談的一套話語系統,來表明我和他是同類的人。我儘量讓自己顯得鎮靜和有涵養,語言上既顯得謙恭又不失尊嚴。我臉上的表情也十分到位,沒有露出一點破綻。我費盡周折終於取得了他的信任、尊重和診斷。我成功了。

我聽到的結論是肯定要動手術,不然這輩子就廢了。當我不動聲色地提著裝了舅舅腰椎的牛皮紙袋走出醫院的時候,我的腰椎忽然傳出了一陣劇痛。


並不是每一次組織都會派人來跟我接頭,也有用電話、手機的時候。只要有來自故鄉區號的電話響起,我就心領神會這些只有我才能破解的密碼,我知道,那是故鄉正在給我發出新的指令。

有一天,我接到了一個電話。電話裡是個中年婦女的聲音,帶著哭腔。她問我是否記得她,曾經住在離我家隔幾棟房子的地方。她說我小時候叫她姑,她還經常抱我,小時候的我長得可胖呢。可後來她嫁到了我村隔壁的村子裡。她說是從我在老家的爸爸那裡要到我的手機號碼的。

說實話我對她並沒有什麼印象,只覺得聲音有點熟悉。再加上手機信號不太好,她的聲音帶著哭腔有些失真,我完全不知道她是誰。離開故鄉多年,故鄉的人和事,已有許多退出了記憶。但她的鄉音讓我對她的真實身份沒有產生一絲懷疑。

我知道,她是自己人。

電話裡開始絮絮叨叨地說事兒。她說她的兒子開長途汽車跑貨運,前幾天在廣州被別人的車撞了。她的兒子還住在醫院裡,傷得很重,肇事司機被當場抓著了,可不知什麼原因,不久就放了出來。這場車禍從此找不著事主了。兒子的傷得治,可眼看著快沒有錢了。她在電話裡哭起來,說這都是因為咱們是鄉下人啦,咱們在廣州人生地不熟的,石頭擲天也沒用啊。聽說只要有人給廣州打個電話那邊就會認真辦理。你是咱村裡的能人,聽說在省城當大官呢,你就給我打個電話過去吧,那邊也是省城,你這裡也是省城,省城還有不聽省城的?求求你了大侄子救救命呀,事情辦成後我打幾斤麻油專門到省城感謝你呀……

我沒有辦法幫這個忙。她想得太天真了。在廣州,除了家鄉的一些打工仔,我並不認識誰,更沒有打個電話就能把事兒給辦了的能力。廣州是我鞭長莫及的城市。我和那邊的城裡人沒有任何交情。我知道她正面臨的困境,可我一點辦法也沒有。我根本不是什麼官兒,我在城裡的身份只是一個靠寫字兒謀生的小文人。而此刻,我成了她落水時想抱著的一根虛弱的稻草。我艱難地回絕了她。她顯得多麼失望!在電話的最後,她嘟嘟囔囔,語氣中充滿了對我見死不救的埋怨。

我知道我讓我的組織失望了。我想我的故鄉肯定會有一段時間對我的忠誠產生懷疑。他們會以為我背叛了他們。﹁哼,人家是城裡人了,哪裡會看得起咱們鄉下人﹂,故鄉的人在議論我時肯定會這麼說。我將因此暫時蒙受冤屈。但作為一名臥底,蒙受冤屈是常有的事。對此,我已逆來順受。

我的親友們紛至沓來。可為了做好一名臥底,我必須承受更多。我必須讓自己越來越像一名城裡人。我必須討好領導,團結同事,善待他人,以取得這座城市更多的信任,從而讓自己在這座城市扎穩腳跟。我甚至對單位的守門人都不敢得罪,親友們給我帶來了紅薯辣椒我都要分給他一些,生怕他把故鄉來的人兇神惡煞地堵在門外。我必須更廣泛地熟悉城市,與更多的城裡人交朋友,以獲得更多的信息,竊取更多故鄉需要的情報。我必須擁有更多的資源:包括人脈資源和信息資源。我必須夜以繼日地工作。我的組織並不發給我所需要的資金,獎勵基本靠口碑,而我必須掙下所有的活動經費︵包括接待故鄉親友的食宿費、交通費和其他開支︶。在這個城市生活,我常常為資金的緊缺一籌莫展。我表面像城裡人一樣樂呵,可我內心的困窘,有誰知曉?一個臥底內心深埋的悲涼,又有誰分擔?我經常孤單地行走在這座城市的街頭,腳步遲疑,一方面對故鄉的命運憂心忡忡,一方面又為是否接聽顯示為故鄉號碼的座機、一直響個不停的手機而猶豫不決。


今夜故鄉又有人入城,說是半夜會來。從電話裡的聲音我知道那是我的一個遠親。他壓低著嗓音說他正在來城裡的夜班車上,可能要十二點左右才能到達。問他到底有什麼事,他欲言又止,顯然他說話不太方便。他的聲音在夜晚的班車上含混不清,呼呼的風聲和車輪在地面行駛的尖銳聲音隱約可聞,很讓我有一些風聲鶴唳的感覺。他乾脆說電話裡說不清。等到見面時一切就知道了。

接電話的前夕,我剛剛送走了一批來城裡的親友。家裡的餐桌上杯盤狼藉,我還來不及把一切清理乾淨。我在城裡用微薄的積蓄和一幢用對我來說是巨額的貸款買下的房子建成了故鄉在城裡的秘密交通站。我坐在親友們沉重的身體坐得凹陷了的沙發上,一動也不想動。故鄉親人們的蜂擁而來已經讓我疲憊不堪。我超負荷地在為我的組織工作。老實說,我受夠了。但我想起我的故鄉依然在苦難中掙扎,我的親友依然嘍蟻般活在蒼茫大地上,而我對他們的熱情款待和為他們的事情奔忙多少可以給他們帶來一星半點的希望和安慰,就一點脾氣也沒有了。是的,就像一名臥底不敢背叛他的組織,我怎麼會忍心改變對故鄉親友的忠誠,成為我貧弱不堪的故鄉千夫所指的叛徒?!

今夜,我依然靜靜地坐在家裡的燈光下,心平氣和地等著入城的親友,將我家的門,篤篤叩響。