用主板蜂鳴器完全指南:從beep命令到8254定時(shí)器)
人類對(duì)聲音的感知某種程度上是從開機(jī)那一聲“嘀”開始的。在很長(zhǎng)一段時(shí)間里主板蜂鳴器是我判斷一臺(tái) GNU/Linux 服務(wù)器到底有沒有活過來的唯一依據(jù)——沒有顯示器、沒有串口線、網(wǎng)卡都沒配好機(jī)器如果能在自檢通過后發(fā)出一聲干脆的“嘀”我基本就能確定它進(jìn)入了可控狀態(tài)。后來我發(fā)現(xiàn)這枚小小的、被新玩家戲稱為“過時(shí)硬件”的元件在 GNU/Linux 下其實(shí)有一條完整的可用生態(tài)鏈內(nèi)核模塊、用戶態(tài)命令、底層端口操作全都能用而且玩法遠(yuǎn)比想象中多。這篇文章會(huì)從原理到實(shí)操把“GNU/Linux 調(diào)用主板蜂鳴器”這件事徹底講透。你不需要有聲卡不需要音箱只要主板上還有那枚蜂鳴器或者機(jī)箱前面板還插著 SPEAKER 跳線。1. 先搞清你面對(duì)的是哪種蜂鳴器很多新手卡在第一步明明主板上有蜂鳴器Linux 里怎么敲都沒反應(yīng)。這不是命令錯(cuò)了很可能是你面對(duì)的根本不是 Linux 傳統(tǒng)支持的那種蜂鳴器。1.1 主動(dòng)式、被動(dòng)式、電磁式、壓電式“主板蜂鳴器”這四個(gè)字其實(shí)是個(gè)大口袋。按驅(qū)動(dòng)方式分有主動(dòng)式有源和被動(dòng)式無源兩種按物理結(jié)構(gòu)分又有電磁式和壓電式兩種。主動(dòng)蜂鳴器內(nèi)部自帶震蕩電路你給它一個(gè)直流高電平它自己就能發(fā)出固定頻率的聲音常見于現(xiàn)代主板的板載小圓片。被動(dòng)蜂鳴器沒有內(nèi)部震蕩源必須給它輸入一個(gè)方波或 PWM 信號(hào)才會(huì)響頻率由外部信號(hào)決定。傳統(tǒng)意義上的 PC Speaker 屬于被動(dòng)電磁式蜂鳴器它由主板上的 8254/8253 可編程定時(shí)器PIT的通道 2 驅(qū)動(dòng)。8254 的輸入時(shí)鐘是 1.1931816 MHzLinux 內(nèi)核通過設(shè)置分頻值來控制發(fā)聲頻率公式很簡(jiǎn)單頻率 1193182 / 分頻值。理解這個(gè)區(qū)別非常重要。GNU/Linux 內(nèi)核里那套經(jīng)典的pcspkr驅(qū)動(dòng)支持的就是“8254 定時(shí)器驅(qū)動(dòng)被動(dòng)蜂鳴器”這條路線。如果你的主板蜂鳴器是主動(dòng)式、由 Super I/O 芯片的 GPIO 直接控制那pcspkr驅(qū)動(dòng)不認(rèn)識(shí)它也很正常因?yàn)槲锢礞溌犯静煌?。先在心里埋下這個(gè)判斷后面排查起來能少走一半彎路。1.2 一條聲音從內(nèi)核到耳朵的路徑在傳統(tǒng) GNU/Linux 系統(tǒng)上讓主板蜂鳴器響起來一般會(huì)經(jīng)過幾個(gè)環(huán)節(jié)。第一步是內(nèi)核加載pcspkr模塊這個(gè)模塊會(huì)在輸入子系統(tǒng)里注冊(cè)一個(gè)名為 PC Speaker 的事件設(shè)備。之后用戶態(tài)程序可以和這個(gè)事件設(shè)備交互也可以走更老派的/dev/consoleioctl 接口往 8254 定時(shí)器里寫分頻值最終推動(dòng)蜂鳴器發(fā)聲。另外還有幾條支線路線。老內(nèi)核里出現(xiàn)過實(shí)驗(yàn)性的 ALSA 驅(qū)動(dòng)snd-pcsp它把 PC Speaker 偽裝成一張聲卡理論上你可以用aplay播放音頻但這條路對(duì) CPU 占用高音質(zhì)也談不上后來基本沒聲音了。還有一類筆記本、一體機(jī)上常見的 HDA Beep 通道蜂鳴器和聲卡編解碼器連在一起用alsamixer能看到一個(gè) Beep 開關(guān)但獨(dú)立臺(tái)式機(jī)主板上很少走這條路。發(fā)聲方式依賴原理適合場(chǎng)景beep 命令經(jīng)典/dev/console KIOCSOUND通過控制臺(tái) ioctl 設(shè)置 8254 分頻腳本、本地終端beep -eevdevpcspkr 輸入設(shè)備向輸入事件節(jié)點(diǎn)發(fā)送 SND_TONE普通用戶權(quán)限終端響鈴 \apcspkr 模塊內(nèi)核 tty 層觸發(fā)控制臺(tái)鈴聲快速測(cè)試ioperm 裸操作root 無內(nèi)核鎖直接讀寫端口 0x42/0x43/0x61學(xué)習(xí)、老平臺(tái)HDA Beep聲卡驅(qū)動(dòng)HDA 編解碼器內(nèi)部 Beep 發(fā)生器筆記本/一體機(jī)這張表基本就是整個(gè) GNU/Linux 蜂鳴器生態(tài)的骨架。后面幾節(jié)我會(huì)把其中用得最多的幾條路線逐一展開。2. 最省事的路線用 beep 命令把蜂鳴器變成你的值班哨如果你只是想快點(diǎn)聽到聲音別一上來就寫 C 代碼。發(fā)行版?zhèn)}庫里有一個(gè)專門干這事的工具叫beep它把 KIOCSOUND 的細(xì)節(jié)封裝成了命令行參數(shù)用起來像樂器一樣舒服。2.1 安裝與驗(yàn)證5 分鐘跑通第一個(gè)能聽見的 beepDebian/Ubuntu 上執(zhí)行sudo apt install beepFedora 系執(zhí)行sudo dnf install beep。裝完先別急著跑命令檢查一下內(nèi)核模塊sudo modprobe pcspkr lsmod | grep pcspkr如果沒有任何輸出說明模塊加載失敗或者被系統(tǒng)屏蔽了。很多發(fā)行版為了不讓服務(wù)器在按下 Tab、誤敲退格鍵時(shí)發(fā)出煩人的“嘀嘀嘀”默認(rèn)把pcspkr寫進(jìn)了黑名單。你可以先看看/etc/modprobe.d/下面有沒有相關(guān)配置有的話注釋掉或刪掉再重新加載。更穩(wěn)的驗(yàn)證方式是直接找事件設(shè)備ls -l /dev/input/by-path/platform-pcspkr-event有這個(gè)路徑恭喜硬件鏈路基本通了?,F(xiàn)在執(zhí)行beep -f 1000 -l 200建議用 root 執(zhí)行或者保證當(dāng)前用戶有權(quán)限訪問對(duì)應(yīng)的設(shè)備節(jié)點(diǎn)。如果聽到了短促的一聲“嘀”整個(gè)鏈條就打通了。如果沒聲音先確認(rèn)主板有沒有物理蜂鳴器很多新主板上并沒有焊那個(gè)小圓片只留了一個(gè)四針 SPEAKER 跳線接口你得從舊機(jī)箱前面板拆個(gè)蜂鳴器插上去才有戲。2.2 常用參數(shù)不只響一聲可以響出花樣beep命令的參數(shù)設(shè)計(jì)得挺人性化。-f指定頻率單位 Hz-l指定時(shí)長(zhǎng)單位毫秒-r指定重復(fù)次數(shù)-d指定重復(fù)之間的延遲-n表示緊接著播下一個(gè)音。舉個(gè)例子beep -f 600 -l 300 -n -f 900 -l 300 -r 2 -d 100這段會(huì)先響 600Hz 持續(xù) 300 毫秒然后響 900Hz 持續(xù) 300 毫秒整套重復(fù)兩遍中間隔 100 毫秒。聽起來就像一個(gè)“雙音提示鈴”。我經(jīng)常把這種雙音用在腳本結(jié)尾編譯成功一種音調(diào)失敗另一種音調(diào)進(jìn)度一目了然。有個(gè)容易踩的坑beep默認(rèn)是通過/dev/console發(fā)聲不依賴你當(dāng)前 SSH 會(huì)話的終端。也就是說哪怕你遠(yuǎn)程登錄執(zhí)行命令聲音也是從服務(wù)器那臺(tái)機(jī)器的控制臺(tái)喇叭傳出來。這對(duì)服務(wù)器管理員來說反而是優(yōu)點(diǎn)——人在機(jī)房門口不用看屏幕就知道機(jī)器狀態(tài)。2.3 權(quán)限、黑名單和“為什么敲終端會(huì)有響聲”如果不想每次都用 root可以給beep配 udev 規(guī)則。新建一個(gè)規(guī)則文件比如/etc/udev/rules.d/70-pcspkr.rulesKERNELevent*, SUBSYSTEMinput, ATTRS{name}PC Speaker, MODE0660, GROUPaudio然后把你的用戶加入audio組重新插拔設(shè)備節(jié)點(diǎn)或者直接重啟普通用戶就能用beep -e /dev/input/by-path/platform-pcspkr-event發(fā)聲了。注意新版 beep 對(duì) setuid 做了安全限制如果你用-e指明事件設(shè)備會(huì)比走/dev/console更不容易觸發(fā)權(quán)限陷阱。還有一個(gè)體驗(yàn)點(diǎn)pcspkr加載后你在虛擬終端里敲錯(cuò)命令導(dǎo)致終端響鈴也會(huì)觸發(fā)蜂鳴器聲音從機(jī)箱里冒出來。想控制這塊可以用setterm -bfreq 800 -blen 100調(diào)節(jié)響鈴頻率和長(zhǎng)度覺得煩直接卸載pcspkr模塊一了百了。這個(gè)矛盾我后面會(huì)專門講。3. 寫點(diǎn)代碼繞過 beep自己控制那枚蜂鳴器工具雖然方便但想真正理解系統(tǒng)在干什么還是得自己摸到底層接口。這一節(jié)給出兩條代碼路線一條走內(nèi)核官方 ioctl一條直接操作硬件端口。3.1 正統(tǒng)方案KIOCSOUND 控制臺(tái) ioctlGNU/Linux 內(nèi)核早就為控制臺(tái)響鈴提供了標(biāo)準(zhǔn)接口定義在linux/kd.h里KIOCSOUND這個(gè) ioctl 接受一個(gè)分頻值0 表示停止發(fā)聲。示例代碼不長(zhǎng)#include stdio.h #include stdlib.h #include fcntl.h #include unistd.h #include sys/ioctl.h #include linux/kd.h static void tone(int fd, int freq, int ms) { if (freq 0) { ioctl(fd, KIOCSOUND, 0); return; } ioctl(fd, KIOCSOUND, 1193180 / freq); usleep(ms * 1000); ioctl(fd, KIOCSOUND, 0); } int main(int argc, char **argv) { int fd open(/dev/console, O_WRONLY); if (fd 0) { perror(open /dev/console); return 1; } int freq argc 1 ? atoi(argv[1]) : 1000; int ms argc 2 ? atoi(argv[2]) : 200; tone(fd, freq, ms); close(fd); return 0; }編譯運(yùn)行g(shù)cc -O2 -o mybeep mybeep.c sudo ./mybeep 1000 3001193180這個(gè)數(shù)字就是 8254 定時(shí)器的輸入時(shí)鐘頻率把目標(biāo)頻率除一下得到分頻值寫進(jìn) ioctl蜂鳴器就會(huì)按這個(gè)頻率震動(dòng)。調(diào)用 ioctl 后立即 sleep結(jié)束后再寫 0 停止整個(gè)時(shí)序非常清晰。要注意/dev/console通常只有 root 能打開所以這里必須加sudo如果你在 systemd 系統(tǒng)上還碰到 Operation not permitted多半是內(nèi)核開啟了 lockdown 或者設(shè)備的 capabilities 被限制需要進(jìn)一步檢查啟動(dòng)參數(shù)。3.2 神經(jīng)病級(jí)的玩法直接讀寫 8254 端口如果你對(duì)“系統(tǒng)調(diào)用”這種事還不過癮想看看蜂鳴器最底層的驅(qū)動(dòng)原理可以繞過內(nèi)核接口用ioperm直接搬寄存器。老 DOS 時(shí)代程序員就是這么干活的#include stdio.h #include stdlib.h #include unistd.h #include sys/io.h static void pcspk_on(int freq) { if (freq 0) return; outb(0xB6, 0x43); /* 通道2方式3方波 */ int divisor 1193182 / freq; outb(divisor 0xFF, 0x42); /* 先寫低字節(jié) */ outb((divisor 8) 0xFF, 0x42); /* 再寫高字節(jié) */ unsigned char t inb(0x61); outb(t | 0x03, 0x61); /* 打開 gate 和 speaker 數(shù)據(jù)位 */ } static void pcspk_off(void) { unsigned char t inb(0x61); outb(t 0xFC, 0x61); /* 關(guān)閉位0和位1 */ } int main(int argc, char **argv) { if (ioperm(0x42, 2, 1) ! 0 || ioperm(0x61, 1, 1) ! 0) { perror(ioperm); return 1; } int freq argc 1 ? atoi(argv[1]) : 1000; int ms argc 2 ? atoi(argv[2]) : 300; pcspk_on(freq); usleep(ms * 1000); pcspk_off(); return 0; }這段代碼的原理也不復(fù)雜。端口0x43是 8254 的控制字寄存器0xB6表示選擇通道 2、先讀寫低字節(jié)再讀寫高字節(jié)、工作方式 3方波。端口0x42是分頻值數(shù)據(jù)口先寫低 8 位再寫高 8 位。端口0x61的低兩位里位 0 是定時(shí)器門控位 1 是揚(yáng)聲器數(shù)據(jù)開關(guān)把這兩位都置 1 聲音才能通過功放電路出來停止時(shí)把這兩位清零即可。這個(gè)方案的“可玩性”最高風(fēng)險(xiǎn)也最大?,F(xiàn)代內(nèi)核在lockdown模式開啟時(shí)會(huì)禁止ioperm操作而且直接在用戶態(tài)操作硬件端口可能和內(nèi)核驅(qū)動(dòng)產(chǎn)生沖突我建議這條路線只用來做實(shí)驗(yàn)、理解硬件原理別寫進(jìn)生產(chǎn)腳本。3.3 evdev 事件發(fā)聲響現(xiàn)代不過度依賴 console 的方式如果你是普通用戶又想在自己的桌面上控制蜂鳴器最干凈的路徑是走輸入子系統(tǒng)。pcspkr模塊注冊(cè)的 PC Speaker 事件設(shè)備支持EV_SND類型的SND_TONE事件你往里面寫頻率值內(nèi)核會(huì)幫你處理剩下的定時(shí)器配置。這也是新版beep工具的-e參數(shù)背后的原理。寫起來很簡(jiǎn)單beep -e /dev/input/by-path/platform-pcspkr-event -f 880 -l 300手寫 C 代碼也不復(fù)雜打開/dev/input/...事件設(shè)備構(gòu)造struct input_eventtype 填EV_SNDcode 填SND_TONEvalue 填頻率write 出去就行。我實(shí)際測(cè)試下來這條路在桌面環(huán)境中比走/dev/console少一些怪問題因?yàn)樗魂P(guān)心當(dāng)前虛擬終端焦點(diǎn)在哪一個(gè) tty。4. 實(shí)戰(zhàn)那些讓人上癮的使用場(chǎng)景技術(shù)說了一堆蜂鳴器到底能在 GNU/Linux 日常里干什么我挑四個(gè)自己試過的場(chǎng)景每一個(gè)都是實(shí)實(shí)在在的痛點(diǎn)。4.1 長(zhǎng)編譯和備份跑完后的完成提示長(zhǎng)期跑make、rsync、大數(shù)據(jù)量壓縮的人都有過這種體驗(yàn)盯著終端不敢走開走了又怕錯(cuò)過結(jié)束時(shí)間。我的做法是在命令末尾接一串 beep 提示。比如編譯成功用兩個(gè)音失敗用一聲低沉長(zhǎng)音make { beep -f 880 -l 200 -n -f 1175 -l 300; echo done; } || { beep -f 200 -l 600; echo failed; }這樣人可以在編譯期間去倒杯水聽著聲音就知道結(jié)果。我甚至見過運(yùn)維同事把beep接到定時(shí)備份腳本里備份成功就在機(jī)房里“嘀”一聲整個(gè)運(yùn)維團(tuán)隊(duì)都形成條件反射了。4.2 無頭服務(wù)器的“活體檢測(cè)”信號(hào)沒有顯示器的服務(wù)器最怕的不是死機(jī)而是死得悄無聲息。我習(xí)慣給系統(tǒng)加一個(gè)開機(jī)自檢 beep如果系統(tǒng)正常啟動(dòng)到多用戶模式就會(huì)響一聲高音如果啟動(dòng)過程卡在某個(gè)階段什么聲音都沒有說明問題出在系統(tǒng)初始化早期。這招在老機(jī)器上非常管用。systemd 服務(wù)寫法如下[Unit] DescriptionBoot beep Aftermulti-user.target [Service] Typeoneshot ExecStart/usr/bin/beep -f 880 -l 200 -n -f 1109 -l 200 RemainAfterExityes [Install] WantedBymulti-user.target放到/etc/systemd/system/boot-beep.service然后systemctl enable boot-beep。以后再碰到半夜機(jī)器失聯(lián)你能通過“有沒有響過”快速判斷是沒起來還是網(wǎng)絡(luò)問題比拆機(jī)插顯示器快多了。4.3 用 GPIO 驅(qū)動(dòng)一顆“現(xiàn)代蜂鳴器”如果你手頭是 ARM 開發(fā)板或者工控主板很多板子自帶 GPIO 排針這時(shí)候可以接一顆主動(dòng)蜂鳴器用最簡(jiǎn)單的電平控制sudo gpioset gpiochip0 231 sleep 1 sudo gpioset gpiochip0 230主動(dòng)蜂鳴器給高電平就響給低電平就停不需要調(diào)頻率。如果想用被動(dòng)蜂鳴器就得借助 PWM 或軟件延時(shí)切換電平復(fù)雜度高一些。這個(gè)玩法已經(jīng)不是傳統(tǒng)意義上的 PC Speaker 了但思路是一樣的把“機(jī)器狀態(tài)”變成“人能感知的聲音”。4.4 虛擬機(jī)里懷舊我偶爾會(huì)開一個(gè) QEMU 虛擬機(jī)體驗(yàn)老系統(tǒng)發(fā)現(xiàn) QEMU 也能模擬 PC Speaker。啟動(dòng)參數(shù)大概是qemu-system-x86_64 \ -machine pcspk-audiodevpa0 \ -audiodev idpa0,driverpa \ -cdrom /path/to/boot.iso這樣虛擬機(jī)內(nèi)部的 GNU/Linux 系統(tǒng)里跑beep聲音會(huì)通過主機(jī)音頻設(shè)備放出來。雖然隔著虛擬機(jī)多少有點(diǎn)延遲但對(duì)于折騰老發(fā)行版、寫內(nèi)核模塊調(diào)試的人來說這比在物理機(jī)上反復(fù)重啟省事。5. 我踩過的坑排查手冊(cè)與注意事項(xiàng)關(guān)于蜂鳴器發(fā)聲的問題網(wǎng)上大多是零散提問很少有系統(tǒng)性的排查清單。我把自己趟過的坑整理成一張速查表按癥狀查對(duì)策能省很多時(shí)間。5.1 常見問題速查表癥狀可能原因排查手段敲 beep 沒任何聲音模塊未加載 / 被黑名單modprobe pcspkr后lsmod | grep pcspkr敲 beep 沒任何聲音主板沒有物理蜂鳴器看 SPEAKER 跳線、機(jī)箱前置喇叭只有一聲極短的“嗒”設(shè)備路徑錯(cuò)誤或權(quán)限不足用ls -l /dev/input/by-path/找 PC SpeakerOperation not permitted/dev/console 權(quán)限、setuid 限制或內(nèi)核 lockdown換-e事件設(shè)備、查啟動(dòng)參數(shù)聲音一直停不下來上層程序發(fā)送頻率后沒發(fā)送 0 停止檢查腳本有沒有在結(jié)束時(shí) ioctl 0SSH 里執(zhí)行 beep 本地聽不到服務(wù)器沒有接顯示器/機(jī)箱喇叭或控制臺(tái)無活動(dòng)終端到實(shí)體機(jī)跟前聽、連 VGA 線現(xiàn)代主板找不到 pcspkr-event主板蜂鳴器走 SIO/GPIO 而不是 8254查主板手冊(cè)、確認(rèn)是否需另接 SPEAKERX11 桌面下終端響鈴不再響圖形終端默認(rèn)屏蔽 PC Speaker 鈴聲用xset b on恢復(fù)或切到真虛擬終端5.2 權(quán)限是主要攔路虎beep命令最讓人困惑的一點(diǎn)是明明用 root 能響普通用戶就是不行。Debian 系的beep包默認(rèn)是 setuid root但較新版本為了安全在 setuid 狀態(tài)下會(huì)限制部分參數(shù)也不能讀取用戶自定義的配置文件。如果你想穩(wěn)妥地給普通用戶放開我建議用上一節(jié)說過的 udev 規(guī)則加audio組而不是依賴 setuid。我試過另一種方案給beep二進(jìn)制設(shè)置cap_sys_tty_configcapabilities但這東西在不同內(nèi)核版本上行為不完全一致。最省心、最可控的還是 udev 規(guī)則 事件設(shè)備路徑/dev/input/by-path/platform-pcspkr-event一旦對(duì)audio組開放權(quán)限問題基本就絕跡了。5.3 為什么 PC 喇叭的聲音那么“難聽”這個(gè)問題我琢磨過一陣子。蜂鳴器發(fā)出的不是正弦波而是 8254 定時(shí)器生成的方波。方波在頻域里帶著一串奇次諧波加上小喇叭/壓電片的諧振腔又很窄聽起來就干、硬、刺耳。反過來這也成了它的優(yōu)點(diǎn)在嘈雜機(jī)房里辨識(shí)度極高。別用 PC Speaker 放音樂去追求音質(zhì)它就是用來傳達(dá)“狀態(tài)”的不是用來取悅耳朵的。6. 把蜂鳴器當(dāng)樂器頻率、節(jié)奏和一個(gè)小播放腳本既然頻率可控蜂鳴器完全可以當(dāng)成一個(gè)單聲道、方波音色的“樂器”。很多人不知道用beep拼出簡(jiǎn)單旋律并不難。6.1 常用音符頻率速查先給一張夠用的頻率表全部基于十二平均律、A4 440Hz音符頻率音符頻率C4262C#4277D4294D#4311E4330F4349F#4370G4392G#4415A4440A#4466B4494C5523E5659G5784C61047一張表不用背用到的時(shí)候查一下就好。想算其他音符頻率公式是440 * 2^((n-69)/12)n 是 MIDI 音符號(hào)。6.2 不用聲卡的音樂盒腳本我寫了一個(gè)極簡(jiǎn)的播放函數(shù)把音符名映射到頻率再用beep播放。比如歡樂頌的第一句大概是這樣play_note() { local note$1 len$2 local freq case $note in C4) freq262;; D4) freq294;; E4) freq330;; F4) freq349;; G4) freq392;; A4) freq440;; B4) freq494;; C5) freq523;; *) freq0;; esac if [ $freq -gt 0 ]; then beep -f $freq -l $len else sleep $((len / 1000)) fi } # E E F G G F E D C C D E E D D for note in E4 E4 F4 G4 G4 F4 E4 D4 C4 C4 D4 E4 E4 D4 D4; do play_note $note 250 done跑起來就是一段很“方波味”的旋律。我還試過摩斯電碼點(diǎn)用 120 毫秒高音劃用 360 毫秒高音字母之間留 300 毫秒。SOS 的節(jié)奏明顯、辨識(shí)度高適合做緊急告警音。當(dāng)年路由器刷機(jī)失敗變磚時(shí)我就在引導(dǎo)腳本里加了這個(gè) SOS 提示機(jī)器能不能救回來聽聲音就能判斷。7. 一點(diǎn)私貨蜂鳴器在運(yùn)維日常里的位置用了這么多年 GNU/Linux我越來越覺得主板蜂鳴器是“最樸素的帶外管理”設(shè)備。它不需要網(wǎng)絡(luò)、不需要驅(qū)動(dòng)、不需要聲卡只要處理器還能執(zhí)行指令、8254 定時(shí)器還活著它就能告訴你系統(tǒng)狀態(tài)?,F(xiàn)代服務(wù)器已經(jīng)有 IPMI、BMC、OLED 屏幕這些高級(jí)手段但那些設(shè)備出問題的時(shí)候蜂鳴器反而是最后一道“我還活著”的信號(hào)。我現(xiàn)在給家里的 NAS 配了三段 beep開機(jī)正常是一短一高系統(tǒng)更新失敗是連續(xù)低音凌晨備份跑完是一聲 1000Hz 短音。鄰居可能覺得奇怪只有我自己知道那是機(jī)器在說“今天也平安無事”。如果你也有一臺(tái)不常開屏幕的 GNU/Linux 機(jī)器強(qiáng)烈建議花五分鐘把蜂鳴器用起來那種“閉著眼睛也知道系統(tǒng)在想什么”的感覺用慣了真的回不去。