自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

udev 入門:管理設(shè)備事件的Linux子系統(tǒng)

系統(tǒng) Linux
udev 是一個(gè)為你的計(jì)算機(jī)提供設(shè)備事件的 Linux 子系統(tǒng)。通俗來講就是,當(dāng)你的計(jì)算機(jī)上插入了像網(wǎng)卡、外置硬盤(包括 U 盤)、鼠標(biāo)、鍵盤、游戲操縱桿和手柄、DVD-ROM 驅(qū)動(dòng)器等等設(shè)備時(shí),代碼能夠檢測(cè)到它們。

[[251969]]

創(chuàng)建這樣一個(gè)腳本,當(dāng)指定的設(shè)備插入時(shí)觸發(fā)你的計(jì)算機(jī)去做一個(gè)指定動(dòng)作。

udev 是一個(gè)為你的計(jì)算機(jī)提供設(shè)備事件的 Linux 子系統(tǒng)。通俗來講就是,當(dāng)你的計(jì)算機(jī)上插入了像網(wǎng)卡、外置硬盤(包括 U 盤)、鼠標(biāo)、鍵盤、游戲操縱桿和手柄、DVD-ROM 驅(qū)動(dòng)器等等設(shè)備時(shí),代碼能夠檢測(cè)到它們。這樣就能寫出很多可能非常有用的實(shí)用程序,而它已經(jīng)很好了,普通用戶就可以寫出腳本去做一些事情,比如當(dāng)某個(gè)硬盤驅(qū)動(dòng)器插入時(shí),執(zhí)行某個(gè)任務(wù)。

這篇文章教你去如何寫一個(gè)由一些 udev 事件觸發(fā)的 udev 腳本,比如插入了一個(gè) U 盤。當(dāng)你理解了 udev 的工作原理,你就可以用它去做各種事情,比如當(dāng)一個(gè)游戲手柄連接后加載一個(gè)指定的驅(qū)動(dòng)程序,或者當(dāng)你用于備份的驅(qū)動(dòng)器連接后,自動(dòng)執(zhí)行備份工作。

一個(gè)初級(jí)的腳本

使用 udev 的***方式是從一個(gè)小的代碼塊開始。不要指望從一開始就寫出完整的腳本,而是從最簡(jiǎn)單的確認(rèn) udev 觸發(fā)了某些指定的事件開始。

對(duì)于你的腳本,依據(jù)你的目標(biāo),并不是在任何情況下都能保證你親眼看到你的腳本運(yùn)行結(jié)果的,因此需要在你的腳本日志中確認(rèn)它成功觸發(fā)了。而日志文件通常放在 /var 目錄下,但那個(gè)目錄通常是 root 用戶的領(lǐng)地。對(duì)于測(cè)試目的,可以使用 /tmp,它可以被普通用戶訪問并且在重啟動(dòng)后就被清除了。

打開你喜歡的文本編輯器,然后輸入下面的簡(jiǎn)單腳本:

  1. #!/usr/bin/bash
  2.  
  3. echo $date > /tmp/udev.log

把這個(gè)腳本放在 /usr/local/bin 或缺省可運(yùn)行路徑的位置中。將它命名為 trigger.sh,并運(yùn)行 chmod +x 授予可運(yùn)行權(quán)限:

  1. $ sudo mv trigger.sh /usr/local/bin
  2. $ sudo chmod +x /usr/local/bin/trigger.sh

這個(gè)腳本沒有任何和 udev 有關(guān)的事情。當(dāng)它運(yùn)行時(shí),這個(gè)腳本將在文件 /tmp/udev.log 中放入當(dāng)前的時(shí)間戳。你可以自己測(cè)試一下這個(gè)腳本:

  1. $ /usr/local/bin/trigger.sh
  2. $ cat /tmp/udev.log
  3. Tue Oct 31 01:05:28 NZDT 2035

接下來讓 udev 去觸發(fā)這個(gè)腳本。

唯一設(shè)備識(shí)別

為了讓你的腳本能夠被一個(gè)設(shè)備事件觸發(fā),udev 必須要知道在什么情況下調(diào)用該腳本。在現(xiàn)實(shí)中,你可以通過它的顏色、制造商、以及插入到你的計(jì)算機(jī)這一事實(shí)來識(shí)別一個(gè) U 盤。而你的計(jì)算機(jī),它需要一系列不同的標(biāo)準(zhǔn)。

udev 通過序列號(hào)、制造商、以及提供商 ID 和產(chǎn)品 ID 號(hào)來識(shí)別設(shè)備。由于現(xiàn)在你的 udev 腳本還處于它的生命周期的早期階段,因此要盡可能地寬泛、非特定和包容。換句話說就是,你希望首先去捕獲盡可能多的有效 udev 事件來觸發(fā)你的腳本。

使用 udevadm monitor 命令你可以實(shí)時(shí)利用 udev,并且可以看到當(dāng)你插入不同設(shè)備時(shí)發(fā)生了什么。用 root 權(quán)限試一試。

  1. $ su
  2. # udevadm monitor

該監(jiān)視函數(shù)輸出接收到的事件:

  • UDEV:在規(guī)則處理之后發(fā)出 udev 事件
  • KERNEL:內(nèi)核發(fā)送 uevent 事件

udevadm monitor 命令運(yùn)行時(shí),插入一個(gè) U 盤,你將看到各種信息在你的屏幕上滾動(dòng)而出。注意那一個(gè) ADD 事件的事件類型。這是你所需要的識(shí)別事件類型的一個(gè)好方法。

udevadm monitor 命令提供了許多很好的信息,但是你可以使用 udevadm info 命令以更好看的格式來看到它,假如你知道你的 U 盤當(dāng)前已經(jīng)位于你的 /dev 樹。如果不在這個(gè)樹下,拔下它并重新插入,然后立即運(yùn)行這個(gè)命令:

  1. $ su -c 'dmesg | tail | fgrep -i sd*'

舉例來說,如果那個(gè)命令返回 sdb: sdb1,說明內(nèi)核已經(jīng)給你的 U 盤分配了 sdb 卷標(biāo)。

或者,你可以使用 lsblk 命令去查看所有連接到你的系統(tǒng)上的驅(qū)動(dòng)器,包括它的大小和分區(qū)。

現(xiàn)在,你的驅(qū)動(dòng)器已經(jīng)處于你的文件系統(tǒng)中了,你可以使用下面的命令去查看那個(gè)設(shè)備的相關(guān) udev 信息:

  1. # udevadm info -a -n /dev/sdb | less

這個(gè)命令將返回許多信息。現(xiàn)在我們只關(guān)心信息中的***個(gè)塊。

你的任務(wù)是從 udev 的報(bào)告中找出能唯一標(biāo)識(shí)那個(gè)設(shè)備的部分,然后當(dāng)計(jì)算機(jī)檢測(cè)到這些唯一屬性時(shí),告訴 udev 去觸發(fā)你的腳本。

udevadm info 命令處理一個(gè)(由設(shè)備路徑指定的)設(shè)備上的報(bào)告,接著“遍歷”父級(jí)設(shè)備鏈。對(duì)于找到的大多數(shù)設(shè)備,它以一個(gè)“鍵值對(duì)”格式輸出所有可能的屬性。你可以寫一個(gè)規(guī)則,從一個(gè)單個(gè)的父級(jí)設(shè)備屬性上去匹配插入設(shè)備的屬性。

  1. looking at device '/devices/000:000/blah/blah//block/sdb':
  2.   KERNEL=="sdb"
  3.   SUBSYSTEM=="block"
  4.   DRIVER==""
  5.   ATTR{ro}=="0"
  6.   ATTR{size}=="125722368"
  7.   ATTR{stat}==" 2765 1537 5393"
  8.   ATTR{range}=="16"
  9.   ATTR{discard\_alignment}=="0"
  10.   ATTR{removable}=="1"
  11.   ATTR{blah}=="blah"

一個(gè) udev 規(guī)則必須包含來自單個(gè)父級(jí)設(shè)備的一個(gè)屬性。

父級(jí)屬性是描述一個(gè)設(shè)備的最基本的東西,比如它是插入到一個(gè)物理端口的東西、或是一個(gè)容量多大的東西、或這是一個(gè)可移除的設(shè)備。

由于 KERNEL 卷標(biāo) sdb 可能會(huì)由于分配給在它之前插入的其它驅(qū)動(dòng)器而發(fā)生變化,因此卷標(biāo)并不是一個(gè) udev 規(guī)則的父級(jí)屬性的好選擇。但是,在做概念論證時(shí)你可以使用它。一個(gè)事件的***候選者是 SUBSYSTEM 屬性,它表示那個(gè)設(shè)備是一個(gè) “block” 系統(tǒng)設(shè)備(也就是為什么我們要使用 lsblk 命令來列出設(shè)備的原因)。

/etc/udev/rules.d 目錄中打開一個(gè)名為 80-local.rules 的文件,然后輸入如下代碼:

  1. SUBSYSTEM=="block", ACTION=="add", RUN+="/usr/local/bin/trigger.sh"

保存文件,拔下你的測(cè)試 U 盤,然后重啟動(dòng)系統(tǒng)。

等等,重啟動(dòng) Linux 機(jī)器?

理論上說,你只需要運(yùn)行 udevadm control —reload 即可,它將重新加載所有規(guī)則,但是在我們實(shí)驗(yàn)的現(xiàn)階段,***要排除可能影響實(shí)驗(yàn)結(jié)果的所有因素。udev 是非常復(fù)雜的,為了不讓你躺在床上整晚都在思考為什么這個(gè)規(guī)則不能正常工作,是因?yàn)檎Z法錯(cuò)誤嗎?還是應(yīng)該重啟動(dòng)一下。所以,不管 POSIX 自負(fù)地告訴你過什么,你都應(yīng)該去重啟動(dòng)一下。

當(dāng)你的系統(tǒng)重啟動(dòng)完畢之后,(使用 Ctl+Alt+F3 或類似快捷鍵)切換到一個(gè)文本控制臺(tái),并插入你的 U 盤。如果你運(yùn)行了一個(gè)***的內(nèi)核,當(dāng)你插入 U 盤后你或許可以看到一大堆輸出。如果看到一個(gè)錯(cuò)誤信息,比如 “Could not execute /usr/local/bin/trigger.sh”,或許是因?yàn)槟阃耸谟柽@個(gè)腳本可運(yùn)行的權(quán)限。否則你將看到的是,一個(gè)設(shè)備插入,它得到內(nèi)核設(shè)備分配的一些東西,等等。

現(xiàn)在,見證奇跡的時(shí)刻到了。

  1. $ cat /tmp/udev.log
  2. Tue Oct 31 01:35:28 NZDT 2035

如果你在 /tmp/udev.log 中看到了***的日期和時(shí)間,那么說明 udev 已經(jīng)成功觸發(fā)了你的腳本。

改進(jìn)規(guī)則做一些有用的事情

現(xiàn)在的問題是使用的規(guī)則太通用了。插入一個(gè)鼠標(biāo)、一個(gè) U 盤、或某個(gè)人的 U 盤都將盲目地觸發(fā)這個(gè)腳本?,F(xiàn)在,我們開始專注于希望觸發(fā)你的腳本的是確定的某個(gè) U 盤。

實(shí)現(xiàn)上述目標(biāo)的一種方式是使用提供商 ID 和產(chǎn)品 ID。你可以使用 lsusb 命令去得到這些數(shù)字。

  1. $ lsusb
  2. Bus 001 Device 002: ID 8087:0024 Slacker Corp. Hub
  3. Bus 002 Device 002: ID 8087:0024 Slacker Corp. Hub
  4. Bus 003 Device 005: ID 03f0:3307 TyCoon Corp.
  5. Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 hub
  6. Bus 001 Device 003: ID 13d3:5165 SBo Networks

在這個(gè)例子中,TyCoon Corp 前面的 03f0:3307 就表示了提供商 ID 和產(chǎn)品 ID 的屬性。你也可以通過 udevadm info -a -n /dev/sdb | grep vendor 的輸出來查看這些數(shù)字,但是從 lsusb 的輸出中可以很容易地一眼找到這些數(shù)字。

現(xiàn)在,可以在你的腳本中包含這些屬性了。

  1. SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", RUN+="/usr/local/bin/thumb.sh"

測(cè)試它(是的,為了確保不會(huì)有來自 udev 的影響因素,我們?nèi)匀唤ㄗh先重新啟動(dòng)一下),它應(yīng)該會(huì)像前面一樣工作,現(xiàn)在,如果你插入一個(gè)不同公司制造的 U 盤(因?yàn)樗鼈兊奶峁┥?ID 不一樣)、或插入一個(gè)鼠標(biāo)、或插入一個(gè)打印機(jī),這個(gè)腳本將不會(huì)被觸發(fā)。

繼續(xù)添加新屬性來進(jìn)一步專注于你希望去觸發(fā)你的腳本的那個(gè)唯一的 U 盤。使用 udevadm info -a -n /dev/sdb 命令,你可以找出像提供商名字、序列號(hào)、或產(chǎn)品名這樣的東西。

為了保證思路清晰,確保每次只添加一個(gè)新屬性。我們(和在網(wǎng)上看到的其他人)在 udev 規(guī)則中所遇到的大多數(shù)錯(cuò)誤都是因?yàn)橐淮翁砑恿颂嗟膶傩裕婀譃槭裁床荒苷9ぷ髁?。逐個(gè)測(cè)試屬性是最安全的作法,這樣可以確保 udev 能夠成功識(shí)別到你的設(shè)備。

安全

編寫 udev 規(guī)則當(dāng)插入一個(gè)驅(qū)動(dòng)器后自動(dòng)去做一些事情,將帶來安全方面的擔(dān)憂。在我的機(jī)器上,我甚至都沒有打開自動(dòng)掛載功能,而基于本文的目的,當(dāng)設(shè)備插入時(shí),腳本和規(guī)則可以運(yùn)行一些命令來做一些事情。

在這里需要記住兩個(gè)事情。

  1. 聚焦于你的 udev 規(guī)則,當(dāng)你真實(shí)地使用它們時(shí),一旦讓規(guī)則發(fā)揮作用將觸發(fā)腳本。執(zhí)行一個(gè)腳本去盲目地復(fù)制數(shù)據(jù)到你的計(jì)算上,或從你的計(jì)算機(jī)上復(fù)制出數(shù)據(jù),是一個(gè)很糟糕的主意,因?yàn)橛锌赡軙?huì)遇到一個(gè)人拿著和你相同品牌的 U 盤插入到你的機(jī)器上的情況。
  2. 不要在寫了 udev 規(guī)則和腳本后忘記了它們的存在。我知道哪個(gè)計(jì)算上有我的 udev 規(guī)則,這些機(jī)器一般是我的個(gè)人計(jì)算機(jī),而不是那些我?guī)еラ_會(huì)或辦公室工作的計(jì)算機(jī)。一臺(tái)計(jì)算機(jī)的 “社交” 程度越高,它就越不能有 udev 規(guī)則存在于它上面,因?yàn)樗鼘撛诘貙?dǎo)致我的數(shù)據(jù)最終可能會(huì)出現(xiàn)在某個(gè)人的設(shè)備、或某個(gè)人的數(shù)據(jù)中、或在我的設(shè)備上出現(xiàn)惡意程序。

換句話說就是,隨著一個(gè) GNU 系統(tǒng)提供了一個(gè)這么強(qiáng)大的功能,你的任務(wù)是小心地如何使用它們的強(qiáng)大功能。如果你濫用它或不小心謹(jǐn)慎地使用它,最終將讓你出問題,它非??赡軙?huì)導(dǎo)致可怕的問題。

現(xiàn)實(shí)中的 Udev

現(xiàn)在,你可以確認(rèn)你的腳本是由 udev 觸發(fā)的,那么,可以將你的關(guān)注點(diǎn)轉(zhuǎn)到腳本功能上了。到目前為止,這個(gè)腳本是沒有用的,它除了記錄腳本已經(jīng)運(yùn)行過了這一事實(shí)外,再?zèng)]有做更多的事情。

我使用 udev 去觸發(fā)我的 U 盤的 自動(dòng)備份 。這個(gè)創(chuàng)意是,將我正在處理的文檔的主副本保存在我的 U 盤上(因?yàn)槲译S身帶著它,這樣就可以隨時(shí)處理它),并且在我每次將 U 盤插入到那臺(tái)機(jī)器上時(shí),這些主文檔將備份回我的計(jì)算機(jī)上。換句話說就是,我的計(jì)算機(jī)是備份驅(qū)動(dòng)器,而產(chǎn)生的數(shù)據(jù)是移動(dòng)的。源代碼是可用的,你可以隨意查看 attachup 的代碼,以進(jìn)一步限制你的 udev 的測(cè)試示例。

雖然我使用 udev 最多的情況就是這個(gè)例子,但是 udev 能抓取很多的事件,像游戲手柄(當(dāng)連接游戲手柄時(shí),讓系統(tǒng)去加載 xboxdrv 模塊)、攝像頭、麥克風(fēng)(當(dāng)指定的麥克風(fēng)連接時(shí)用于去設(shè)置輸入),所以應(yīng)該意識(shí)到,它能做的事情遠(yuǎn)比這個(gè)示例要多。

我的備份系統(tǒng)的一個(gè)簡(jiǎn)化版本是由兩個(gè)命令組成的一個(gè)過程:

  1. SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", SYMLINK+="safety%n"
  2. SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", RUN+="/usr/local/bin/trigger.sh"

***行使用屬性去檢測(cè)我的 U 盤,這在前面已經(jīng)討論過了,接著在設(shè)備樹中為我的 U 盤分配一個(gè)符號(hào)鏈接,給它分配的符號(hào)連接是 safety%n。這個(gè) %n 是一個(gè) udev 宏,它是內(nèi)核分配給這個(gè)設(shè)備的任意數(shù)字,比如 sdb1、sdb2、sdb3、等等。因此 %n 應(yīng)該是 1 或 2 或 3。

這將在 dev 樹中創(chuàng)建一個(gè)符號(hào)鏈接,因此它不會(huì)干涉插入一個(gè)設(shè)備的正常過程。這意味著,如果你在自動(dòng)掛載設(shè)備的桌面環(huán)境中使用它,將不會(huì)出現(xiàn)問題。

第二行運(yùn)行這個(gè)腳本。

我的備份腳本如下:

  1. #!/usr/bin/bash
  2.  
  3. mount /dev/safety1 /mnt/hd
  4. sleep 2
  5. rsync -az /mnt/hd/ /home/seth/backups/ && umount /dev/safety1

這個(gè)腳本使用符號(hào)鏈接,這將避免出現(xiàn) udev 命名導(dǎo)致的意外情況(例如,假設(shè)一個(gè)命名為 DISK 的 U 盤已經(jīng)插入到我的計(jì)算機(jī)上,而我插入的其它 U 盤恰好名字也是 DISK,那么第二個(gè) U 盤的卷標(biāo)將被命名為 DISK_,這將導(dǎo)致我的腳本不會(huì)正常運(yùn)行),它在我喜歡的掛載點(diǎn) /mnt/hd 上掛載了 safety1(驅(qū)動(dòng)器的***個(gè)分區(qū))。

一旦 safely 掛載之后,它將使用 rsync 將驅(qū)動(dòng)器備份到我的備份文件夾(我真實(shí)使用的腳本用的是 rdiff-backup,而你可以使用任何一個(gè)你喜歡的自動(dòng)備份解決方案)。

udev 讓你的設(shè)備你做主

udev 是一個(gè)非常靈活的系統(tǒng),它可以讓你用其它系統(tǒng)很少敢提供給用戶的方式去定義規(guī)則和功能。學(xué)習(xí)它,使用它,去享受 POSIX 的強(qiáng)大吧。

本文內(nèi)容來自 Slackermedia Handbook,它以 GNU Free Documentation License 1.3 許可證授權(quán)使用。

責(zé)任編輯:龐桂玉 來源: Linux中國(guó)
相關(guān)推薦

2021-07-22 08:03:08

Windows 操作系統(tǒng)Linux

2016-10-17 08:49:15

WindowsLinuxArch Linux

2021-08-10 11:30:30

Linux代碼中斷控制器

2021-08-03 15:10:26

Linux代碼驅(qū)動(dòng)

2021-12-08 08:41:31

Linux 中斷子系統(tǒng)Linux 系統(tǒng)

2016-07-22 10:50:56

Linux內(nèi)核無線子系統(tǒng)

2021-08-31 11:53:38

Linux inputLinux 系統(tǒng)

2017-07-14 14:35:27

Linux中斷系統(tǒng)

2009-10-21 17:29:34

Oracle管理系統(tǒng)

2023-04-12 15:31:11

系統(tǒng)服務(wù)管理鴻蒙

2021-12-15 10:02:25

鴻蒙HarmonyOS應(yīng)用

2021-06-07 08:13:11

LinuxIDLE 子系統(tǒng)

2012-02-29 00:57:41

Linux系統(tǒng)

2009-12-16 15:59:13

Linux設(shè)備文件管理

2021-09-17 14:38:58

鴻蒙HarmonyOS應(yīng)用

2021-05-06 07:53:20

LinuxUBI子系統(tǒng)

2018-04-15 21:26:36

Windows Linux 系統(tǒng)

2015-11-10 16:55:00

性能IO子系統(tǒng)Linux

2021-07-07 08:00:00

Linux開發(fā)虛擬機(jī)

2022-04-12 09:05:30

Linux時(shí)鐘
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)