常用檔案訪問權相關命令,以及 macOS launchd

語言: CN / TW / HK

前言

在維護 Jenkins Slave Node(這裡指 macOS 構建機)的過程,不可避免地是你會遇到一些檔案訪問許可權和程序常駐的問題。所以,如果要解決這些問題,就要求你瞭解 Linux 檔案訪問權(包括檔案和目錄,以下統稱檔案)和什麼是守護程序(macOS launchd)。

那麼,回到今天本文,也將會從常用 Linux 檔案訪問權相關命令開始,一步一步帶你瞭解這些其中的所以然。

一、Linux 檔案訪問權相關命令

首先,我們需要建立的基礎認知是在 Linux 系統中,檔案的訪問者身份劃分這 3 類:

  • 檔案屬主,某個使用者,例如 root
  • 檔案所屬組,某個使用者組,例如 staffwheel
  • 其他使用者,不是上面 2 者

下面,我們再來分別認識下在檢視和修改檔案訪問權過程會使用到的命令。

1.1 ls -l, ls -la

ls 這個命令,我想應該很多同學都知道,可以用於檢視某個目錄下有哪些檔案,例如: bash wujingchang@wujingchangdeMacBook-Pro ant-design % ls AUTHORS.txt README-zh_CN.md package-lock.json CHANGELOG.en-US.md README.md package.json CHANGELOG.zh-CN.md SECURITY.md renovate.json CNAME components scripts CODE_OF_CONDUCT.md docs site LICENSE index-style-only.js tests README-ja_JP.md index-with-locales.js tsconfig.json README-pt_BR.md index.js tsconfig.node.json README-sp_MX.md jest-puppeteer.config.js typings README-uk_UA.md node_modules webpack.config.js

ls-l Option 可以用於檢視檔案屬主、所屬組、讀寫許可權和檔案大小等資訊: ```bash wujingchang@wujingchangdeMacBook-Pro ant-design % ls -l -rw-r--r-- 1 wujingchang staff 50839 11 9 12:50 AUTHORS.txt -rw-r--r-- 1 wujingchang staff 320126 11 9 12:50 CHANGELOG.en-US.md -rw-r--r-- 1 wujingchang staff 334949 11 9 12:50 CHANGELOG.zh-CN.md -rw-r--r-- 1 wujingchang staff 16 11 9 12:50 CNAME -rw-r--r-- 1 wujingchang staff 3254 11 9 11:39 CODE_OF_CONDUCT.md -rw-r--r-- 1 wujingchang staff 1099 11 9 11:39 LICENSE -rw-r--r-- 1 wujingchang staff 10155 11 9 12:50 README-ja_JP.md -rw-r--r-- 1 wujingchang staff 9903 11 9 11:39 README-pt_BR.md -rw-r--r-- 1 wujingchang staff 9801 11 9 12:50 README-sp_MX.md -rw-r--r-- 1 wujingchang staff 10623 11 9 11:39 README-uk_UA.md -rw-r--r-- 1 wujingchang staff 9596 11 9 11:39 README-zh_CN.md

省略若干目錄

其中,如果當你還想隱藏檔案的資訊的時候則可以使用 `ls -la`。那麼,可以看到這裡主要 9 列,分別表示的含義為:讀寫許可權資訊、連結目錄數和檔案路徑長度(例如 `/demo/test` 此時為 2)、屬主、所屬組、檔案大小、建立月份、建立日、建立時間、檔名稱,例如 `AUTHORS.txt`:bash

讀寫許可權 連結目錄數和檔案路徑長度 屬主 所屬組 檔案大小 建立月 日 時間 檔名

-rw-r--r-- 1 wujingchang staff 50839 11 9 12:50 AUTHORS.txt ```

很顯然,我們關注的是第一列(檔案讀寫許可權資訊),而它則是由長度為 10 的字元組成:

  • 第 1 位 表示檔案還是目錄,例如檔案是 -、目錄是 d 和連結目錄是 l
  • 第 2~4 位表示屬組的許可權,其中 r 表示讀(Read)許可權,w 表示寫(Write)許可權,x 表示執行(execute)許可權,- 則表示無許可權
  • 第 5~7 位表示所屬組的許可權
  • 第 8 ~ 10 位表示其他使用者的許可權

例如,這裡 AUTHORS.txt 的讀寫許可權資訊 -rw-r--r-- 則表示:

  • - 普通檔案
  • rw- 可讀、可寫、不可執行(因為是一個普通檔案不是可執行程式)
  • r-- 可讀、不可寫、不可執行,也就是說同樣是 staff 組的使用者(除開 wujingchang)只能讀這個檔案不能寫
  • r-- 同上

1.2 chmod

chmod 是 change mode 的縮寫,表示改變檔案的許可權。我們可以通過 chmod + 和要獲取的許可權 rwx 來更改具體的檔案許可權,例如 chmod +w 表示增加可寫的許可權,反之 -w 則表示移除可寫的許可權。

同樣是 AUTHORS.txt 檔案,我們把原本的可讀許可權去掉: bash wujingchang@wujingchangdeMacBook-Pro ant-design % chmod -r AUTHORS.txt 需要注意的是,-r 預設修改的是屬主的訪問許可權,我們可以通過 u-r(屬主)、g-r(所屬組)、o-r(其他使用者)的方式移除指定的讀取許可權。

那麼,現在 AUTHORS.txt 檔案的許可權資訊則是: bash wujingchang@wujingchangdeMacBook-Pro ant-design % ls -l AUTHORS.txt --w------- 1 wujingchang staff 50839 11 9 12:50 AUTHORS.txt

可以看到原先的 r 都被移除了,此時,如果嘗試開啟 open AUTHORS.txt,則會提示:

此外,除了使用字元 rwx 的方式修改,我們還可以用數字的方式修改(4 可讀,2 可寫,1 可執行),例如同樣是移除 AUTHORS.txt 的讀許可權: bash wujingchang@wujingchangdeMacBook-Pro ant-design % chmod 020 AUTHORS.txt

1.3 chown

chown是 change ownership 的縮寫,表示我們可以更改檔案的訪問權。例如,我們可以修改 AUTHORS.txt 檔案的屬主為 rootbash wujingchang@wujingchangdeMacBook-Pro ant-design % sudo chown root AUTHORS.txt 注意由於 root 是超級使用者,所以需要 sudo。然後,此時 AUTHORS.txt 的屬主則會變成 rootbash wujingchang@wujingchangdeMacBook-Pro ant-design % ls -l AUTHORS.txt -rw-r--r-- 1 root staff 50839 11 9 12:50 AUTHORS.txt 那現在我們能使用 open AUTHORS.txt 開啟嗎?答案是可以,因為 wujingchangroot 屬於同一個組 staff,而 -rw-r--r-- 的第 4~7 位 r-- 表示可讀、不可寫不可執行,並且其他使用者也是 r--。所以,此時仍然是可以開啟 AUTHORS.txt 檔案,但是開啟後會處於只讀的模式:

那麼,如果希望在修改檔案屬主的同時也修改檔案所屬組,可以在使用 chown 的時候通過 user:group 的方式修改: bash wujingchang@wujingchangdeMacBook-Pro ant-design % sudo chown root:wheel AUTHORS.txt wujingchang@wujingchangdeMacBook-Pro ant-design % ls -ls AUTHORS.txt 104 -rw-r--r-- 1 root wheel 50839 11 9 12:50 AUTHORS.txt 然後,則是其他使用者的可讀許可權,這可以通過 chmod 修改: bash wujingchang@wujingchangdeMacBook-Pro ant-design % open AUTHORS.txt wujingchang@wujingchangdeMacBook-Pro ant-design % sudo chmod o-r AUTHORS.txt wujingchang@wujingchangdeMacBook-Pro ant-design % ls -ls AUTHORS.txt 104 -rw-r----- 1 daemon wheel 50839 11 9 12:50 AUTHORS.txt The application cannot be opened for an unexpected reason, error=Error Domain=NSOSStatusErrorDomain Code=-5000 "afpAccessDenied: Insufficient access privileges for operation " UserInfo={_LSLine=3863, LSErrorDict={ Action = odoc; Documents = ( "AUTHORS.txt" ); ErrorCode = "-5000"; FullPaths = ( "/Users/wujingchang/Documents/repo/ant-design/AUTHORS.txt" ); }, _LSFunction=_LSOpenStuffCallLocal}

1.4 chgrp

chgrp 是 change group 的縮寫,表示我們可以更改檔案的所屬組的訪問權。也就是說,除開使用 chmod 的時候指明使用者組的方式修改所屬組的訪問權,我們還可以通過 chgrp 來直接修改 AUTHORS.txt 檔案的所屬組: bash wujingchang@wujingchangdeMacBook-Pro ant-design % sudo chgrp wheel AUTHORS.txt

二、Launchd

通常,我們在註冊連線 Jenkins Slave Node 的時候是希望它常駐在記憶體中。這在 Windows 機器上,我們可以通過 Services 的方式實現。而在 macOS 上,我們可以通過launchd 提供的守護程序相關的能力實現。

launchd 則是 Apple Inc 建立的一個初始化和作業系統服務管理守護程序。在 Launchd 中有 2 個主要的程式 launchd 和 launchctl,前者用於啟動系統和執行服務,後者用於控制服務。

所以,在 macOS 啟動過程,會載入 launchd,launchd 則會執行 /etc/rc,掃描系統 System、使用者 User 下、全域性的 /Library/LaunchDaemons 和 /Library/LaunchAgents 目錄下的指令碼,根據需要在 plist 上呼叫 launchctl,然後 launchd 啟動登入視窗。

其中 LaunchDaemonsLaunchAgents 處於不同的檔案位置所執行的使用者有所不同:

| 型別 | 檔案位置 | 執行的使用者 | | ---- | ---- | ---- | | User Agents | ~/Library/LaunchAgents | 當前登入使用者 | | Global Agents | /Library/LaunchAgents | 當前登入使用者 | | Global Daemons | /Library/LaunchDaemons | root 或者指定的使用者 | | Global Agents | /System/Library/LaunchAgents | 當前登入使用者 | | Aystem Daemons | /System/Library/LaunchDaemons | root 或者指定的使用者 |

可以看到,LaunchAgents 是隻能以當前的登入使用者執行,而 LaunchDaemons 可以指定特定的使用者,並且需要注意的是隻有 LaunchAgents 可以訪問 macOS GUI 的。

如果,我們期望通過 launchd 執行指定的程式(launch Job 或 Service,以下統稱 launch Job),則需要在上述的檔案目錄下配置以 .plist 副檔名的 XML 檔案,這通常也被稱為 Plist 檔案。那麼,下面我們來一起看下如何建立一個 launchd Job?

2.1 launchd Job 建立

用於建立 launchd Job 的 Plist 檔案配置提供了諸多 Key-Value 來實現指定的宣告,這裡我們來看 4 個比較常用的 Key:

  • Label 用於表示 Daemon 的名稱,唯一標識
  • ProgramArguments 用於表示 Daemon 啟動時需要執行的命令列相關
  • UserName 用於表示啟動 Daemon 的使用者,例如你可以宣告為 wujingchang
  • KeepAlive 用於表示是否 Daemon 需要按需執行還是必須執行

那麼,以 Jenkins Slave Node 的連線為例,它需要我們在構建機器(macOS 機器)上通過指定的 Java 命令建立和 Jenkins 伺服器的遠端連線,這看起來會是這樣: bash java -jar agent.jar -jnlpUrl http://xxxxxxx/jenkins-agent.jnlp -secret xxxxxxxx -workDir D:\jenkins

所以,它的 lauchd Job 的配置會是: ```xml

Label com.jenkins.slavenode ProgramArguments java -jar -jnlpUrl http://xxxxxxx/jenkins-agent.jnlp -secret xxxxxxxx -workDir D:\jenkins UserName wujingchang KeepAlive ```

並且,需要注意的是 launchd Job 的 Plist 檔案需要按前面提及的 LaunchDaemons 的檔案位置存放(保證開機自啟的行為),例如這裡的 wujingchang 是當前使用者,那麼就把 Plist 檔案放到 ~/Library/LaunchDaemons 檔案目錄下。

2.2 launchctl 命令使用

在建立好 launchd Job 的 Plist 檔案後,後續在機器開啟的過程則會執行對應的 Job。那麼,也就是說我們剛建立的 launchd Job 需要等待下次開機才能執行。

所以,如果你新建立的 launchd Job 也需要馬上執行,那麼則可以使用 launchctl 提供的命令,常用的 launchctl 命令有:

  • launchctl load 載入啟動 launchd Job
  • launchctl unload 解除安裝停止 launchd Job
  • launchctl list 檢視已啟動的訪問 lauchd Job 資訊

那麼,回到上面的例子,我們可以使用 launchctl load 命令執行剛建立的 launch Job: bash launchctl load ~/Library/LaunchDaemons/slavenode.plist

此外,我們還可以通過 brew services 相關的命令來啟動和停止 launchd Job,具體大家可以通過 brew services --help 瞭解,這裡不做展開。

結語

通過,瞭解檔案訪問權修改和 launchd 相關的知識,可以讓我們在 Jenkins 排障的維護過程處理訪問許可權更得心應手,避免由於知識盲區的存在導致問題遲遲不能解決或者解決的成本較高的情況出現。並且,需要注意的是每個修改檔案訪問權相關的命令(chmodchownchgrp)都支援使用 -h Option 檢視相關的介紹,例如 chown -hbash wujingchang@wujingchangdeMacBook-Pro @ant-desgin % chown -h usage: chown [-fhnvx] [-R [-H | -L | -P]] owner[:group] file ... chown [-fhnvx] [-R [-H | -L | -P]] :group file ...

最後,如果文中存在表達不當或錯誤的地方,歡迎各位同學提 Issue ~

點贊

通過閱讀本篇文章,如果有收穫的話,可以點個贊,這將會成為我持續分享的動力,感謝~

我是五柳,喜歡創新、搗鼓原始碼,專注於原始碼(Vue 3、Vite)、前端工程化、跨端等技術學習和分享,歡迎關注我的微信公眾號 Code center GitHub