1. 程式人生 > >Linux(Ubuntu)無法調節亮度的終極解決方案(還原Fn組合鍵調節方法

Linux(Ubuntu)無法調節亮度的終極解決方案(還原Fn組合鍵調節方法

5年前我花了一週時間也沒解決的問題,現在只用了2個小時就完美解決了

重要提示

這篇文章展示了我的思考及嘗試過程,其中一些諸如檔案儲存的方法等簡單操作沒有加入,如果你很著急或是剛剛接觸Linux,請參考這篇精簡版【地址摸我】

參考資料:[1]https://blog.csdn.net/u013991521/article/details/49562365
[2]https://askubuntu.com/questions/762764/cant-change-brightness-in-ubuntu-16-04-lts

本人的一臺聯想昭陽E46G筆記本(無獨顯),在被換上i5 520M、4G記憶體、120G ssd之後繼續延續著他第8年的使命。
儘管如此,但即便是windows7也無法流暢的在這臺老機器上運行了。於是,我重新給他裝上了Linux系統(5年前嘗試了基於Debian 8 某Linux發行版,這次是Ubuntu 18.04 LTS)

不出所料,5年前的BUG又一次的出現了!!

只能在結束boot介面後到Ubuntu的logo出現的那短短几秒的時間可以通過Fn組合鍵調節亮度!!進入系統後使用Fn調節亮度,螢幕的亮度調節滑塊正常顯示,但螢幕背光沒有絲毫改變

全亮與一格亮度對比【沒有任何變化】
全亮與一格亮度對比【沒有任何變化】

然而這個現象在我的另一臺筆記本上卻沒有出現。

附上未出BUG機器的配置:
Model:ASUS X84L
CPU:intel B815 @1.60GHz
RAM:2G DDR3
HDD:320G WD
GPU:AMD HD6470m 1G

在查閱多方資料與不斷嘗試後,我發現是因為Intel整合顯示卡的原因。
原因如下:

fn調節的是/sys/class/backlight/acpi_video0/brightness檔案,而Intel的檔案是/sys/class/backlight/intel_backlight/brightness
-------來自參考資料[1]

參考資料[1]中給出了兩種解決方案:
1)通過修改/etc/default/grub 來實現對Intel顯示卡的支援
2)手動通過命令修改

然而第1種方案對我無效,而我喜歡經常調節亮度,法2實在過於麻煩。

參考資料[2]中也有一種方案,但依舊對我無效。

由於發現是外文資料,且國內好像無人翻譯,現翻譯在另一篇文章上,可以先嚐試一下【地址摸我】

解決思路

經過實驗發現,在通過Fn組合鍵促發亮度調節功能時,系統的亮度logo會有正常響應
在這裡插入圖片描述
而且,/sys/class/backlight/acpi_video0/brightness 會有變化

!我可以寫一個程式監控/sys/class/backlight/acpi_video0/brightness ,然後反手把讀出來的值經過處理寫到/sys/class/backlight/intel_backlight/brightness!

觀察得出:
我的/sys/class/backlight/acpi_video0/brightness 值的範圍在[0,10],且0時為最暗但不是黑屏,10為最亮

我的/sys/class/backlight/intel_backlight/brightness值的範圍在[0,4882],且0時為最暗且為黑屏,4882為最亮

寫入超出範圍的值均會觸發寫入錯誤。
注:圖片僅為檔案格式展示,不代表最低/高值

注:圖片僅為檔案格式展示,不代表最低/高值

於是就有了第一代程式

import time
import os
# 先賦777許可權(其實這裡給高了,不過沒關係
os.system("sudo chmod -R 777 /sys/class/backlight/intel_backlight/brightness")
while True:
	# 先讀取Fn組合鍵儲存的檔案
	acpi_l = open("/sys/class/backlight/acpi_video0/brightness")
	# 簡單的線性調整,偏置值+20 為了在調至最暗時不至於黑屏 480權重請自己測試,不同機型可能不一樣
	brightness= str(int(acpi_l.read()) * 480 + 20)
	acpi_l.close()
	
	# 以“w”模式開啟,方便清空
	intel_l = open("/sys/class/backlight/intel_backlight/brightness","w")
	intel_l.write(brightness)
	intel_l.close()
	# 等待0.5s,在不過多佔用系統資源的情況下獲得較好的體驗
	time.sleep(0.5)

先解釋下為什麼要每次給寫入許可權:因為sys目錄裡的許可權掉電會還原,所以每次都要打上。
然而這樣的操作很麻煩,每次先不說要開啟一個檔案,還要輸密碼,而且還要給他一個單獨的shell佔用著。

拓展1

我先建立了/etc/rc.local檔案(Ubuntu16.10以後就沒有了)
加入了

# 注:為了精簡,這裡的/etc/rc.local檔案內容僅包含有實際意義的部分
sudo chmod -R 777 /sys/class/backlight/intel_backlight/brightness
python /etc/auto_brightness/change.py

然後重啟

結果卡死在啟動介面!!
趕緊進入可讀寫的單使用者模式把rc.local刪了。

分析原因

Linux的開機啟動專案必須執行完才能進入桌面,然而 while True。。。。

難道這與開機自啟無緣了嗎?

拓展2

其實用screen就可以完美解決!
要使用screen,請先執行

sudo apt-get install screen

然後建立一個sh檔案

screen_name="auto_run"

screen -dmS $screen_name
#以下路徑為python程式的路徑
cmd="python3 /etc/auto_run/change.py";

screen -x -S $screen_name -p 0 -X stuff "$cmd"  

screen -x -S $screen_name -p 0 -X stuff '\n'   

在/etc/rc.local中加入
如果沒找到/etc/rc.local,請參考https://blog.csdn.net/weixin_43599336/article/details/85970601

sudo chmod -R 777 /sys/class/backlight/intel_backlight/brightness
# 剛剛的sh檔案路徑
sh /etc/auto_run/auto_run.sh

重啟

sudo reboot

問題解決!

在這裡插入圖片描述
通過反光就看得出來!!!

拓展3

你以為就這麼結束了嗎?
其實我覺得個人喜歡的亮度範圍在[500,2500]之間,如果用線性變化有時會出現加一格嫌亮,降一格覺得暗的情況。
於是我就開始用了一個新的處理函式
10.8x2 + 299x + 201
整個程式就變成了這樣

import time
while True:
        acpi_l = open("/sys/class/backlight/acpi_video0/brightness")
        l = int(acpi_l.read())
        brightness = str(int(10.8 * l * l + 299 * l + 201))

        intel_l = open("/sys/class/backlight/intel_backlight/brightness","w")
        intel_l.write(brightness)
        intel_l.close()
        time.sleep(0.5)

這個函式可以使亮度調節的中後段調節更加的細膩,更符合我的個人習慣
要注意的一點是:一點要確保當l在[0,10]時,你的函式值不會小於0或溢位最大值(我的是4880)