在 Fedora Linux 系統(tǒng)上安裝 PowerShell
PowerShell(也可寫(xiě)作 pwsh)是一個(gè)功能強(qiáng)大的開(kāi)源命令行工具,它是面向?qū)ο蟮模晌④涢_(kāi)發(fā)和維護(hù)。它的語(yǔ)法特征冗長(zhǎng),但對(duì)用戶來(lái)說(shuō)比較直觀。本文介紹如何在主機(jī)上和在 Podman 或其他容器內(nèi)安裝 PowerShell。
為何使用 PowerShell
PowerShell,正如它的名字那樣,是一個(gè)強(qiáng)大的工具。它的句法冗長(zhǎng),但語(yǔ)義清晰。對(duì)那些不愿意寫(xiě)長(zhǎng)命令的開(kāi)發(fā)者來(lái)說(shuō),PowerShell 的大多數(shù)命令都有別名??梢允褂?nbsp;??Get-Alias?
? 或點(diǎn)擊 ??此處?? 查詢別名的使用方法。
PowerShell 和傳統(tǒng)的 Shell 最大的區(qū)別在于它的輸出管道。普通的 Shell 輸出的是字符串或字符流,PowerShell 輸出的是對(duì)象。這對(duì)命令管道的工作方式具有深遠(yuǎn)的影響,而且它具有很多的優(yōu)點(diǎn)。
演示例子
下面的例子體現(xiàn)的是冗長(zhǎng)而清晰的特點(diǎn)。以 ??#?
?? 號(hào)開(kāi)頭的行是注釋行。以 ??PS >?
?? 開(kāi)頭的行是命令行,??PS >?
? 是提示符:
上述例子說(shuō)明了:Bash 腳本經(jīng)常需要用 ??cut?
?、??sed?
?、??awk?
? 等工具對(duì)輸入/輸出進(jìn)行格式化,而使用
PowerShell 時(shí)通常就沒(méi)有這個(gè)必要了。這是因?yàn)?PowerShell 的工作機(jī)制跟傳統(tǒng)的 POSIX shell(例如
Bash、Zsh、Fish等)有本質(zhì)的不同。傳統(tǒng)的 Shell 的命令輸出形式是字符串,而在 PowerShell 中,命令輸出形式為對(duì)象。
Bash 與 PowerShell 的比較
下面的例子說(shuō)明了與 Bash 中的字符串輸出模式相比,PowerShell 的對(duì)象輸出模式的優(yōu)點(diǎn)。假設(shè)你需要寫(xiě)一段腳本,該腳本的作用顯示所有進(jìn)程,這些進(jìn)程一共占用了 200MB 內(nèi)存空間。如果使用 Bash,大致如下:
第一個(gè)顯而易見(jiàn)的差別就是可讀性,或更確切地說(shuō)是語(yǔ)義清晰度。 ??ps?
? 和 ??awk?
? 都不是自描述的。??ps?
? 命令的功能是顯示進(jìn)程狀態(tài);??awk?
? 是一種文本處理工具和語(yǔ)言,這個(gè)詞匯每個(gè)字母都是前期開(kāi)發(fā)人員的名字(Aho, Weinberger, Kernighan(詳見(jiàn) ??維基百科??)的首字母。然而,在把它與 PowerShell 作比較前,先看看這個(gè)腳本:
- ?
?ps -e?
? 輸出所有運(yùn)行中的進(jìn)程; ?-O rss?
? 輸出ps
的默認(rèn)輸出內(nèi)容,再加上 RSS 字段 —— 每個(gè)進(jìn)程使用的千字節(jié)數(shù)(以 KB 為單位);輸出結(jié)果類似于:
- ?
?|?
? 管道操作符使用左邊命令的輸出作為右邊命令的輸入。 - ?
?awk -F' '?
? 定義“空格”,作為輸入字段分隔符。以上面的例子來(lái)說(shuō),PID 是第一個(gè)字段,RSS 是第二個(gè)字段,依此類推。 - ?
?'{ if($2 >= (1024*200)) {?
? 是實(shí)際的 AWK 代碼起始處。它的作用是檢查第二個(gè)字段(RSS)是否包含一個(gè)大于或等于 1024*200 的數(shù)字; - ?
?printf(“%s\t%s\t%s\n”,$1,$2,$6);}?
? 腳本繼續(xù)。如果前面的條件成立,則輸出第一、第二和第六個(gè)字段(分別是 PID、RSS 和COMMAND
字段)。
考慮到這一點(diǎn),退一步說(shuō),編寫(xiě)這段腳本需要什么才能令它工作:
- 輸入命令?
?ps?
? 的輸出中必須包含我們想要過(guò)濾的字段。這在默認(rèn)情況下是沒(méi)有的,需要我們使用??-O?
? 標(biāo)志和??rss?
? 字段作為參數(shù)。 - 我們需要將?
?ps?
? 的輸出當(dāng)作一組輸入字段,所以我們還應(yīng)當(dāng)知道它們的順序和結(jié)構(gòu)。換句話說(shuō),我們至少需要確定??RSS?
? 是第二個(gè)字段。這也意味著我們需要提前知道??ps?
? 的輸出信息的大致情況。 - 然后我們需要知道過(guò)濾的數(shù)據(jù)是什么單位,以及相關(guān)工具的單位是什么。也就是我們需要知道?
?RSS?
? 和??awk?
? 字段使用 kb。不然我們就不能寫(xiě)出??($2 >= 1024*200)?
? 這樣的表達(dá)式。
現(xiàn)在,我們把前面的命令跟 PoserShell 中等價(jià)的命令比較:
首先應(yīng)該注意到,語(yǔ)義非常清晰。這些命令都是自描述的,能清晰描述它們做什么。
此外,不需要對(duì)輸入-輸出重新格式化,也不需要關(guān)心輸入命令使用的單位。這是因?yàn)?PowerShell 輸出的是對(duì)象,而非字符串。
考慮下述情況,就可以理解這些內(nèi)容。在 Bash 中,命令的輸出信息就是終端顯示的信息。在 PowerShell
中,終端顯示的信息并不等于實(shí)際可用的信息。這是由于 PowerShell 中的輸出-打印系統(tǒng)使用的也是對(duì)象。因此 PowerShell
中每一條命令都對(duì)輸出的對(duì)象的一些屬性作了可打印的標(biāo)記,也對(duì)一些屬性作了不可打印的標(biāo)記。然而,它總是包括所有的屬性,而 Bash
只包括它實(shí)際打印的內(nèi)容。我們可以把它想象成 JSON 對(duì)象。Bash 中的輸出位置被分為一些“字段”,以空格或制表符為標(biāo)志,在
PowerShell 中它是一個(gè)容易尋址的對(duì)象屬性,只需要知道它的名稱即可使用。就像上述例子中的 ??WorkingSet?
? 那樣。
為了看到一條命令的輸出對(duì)象的所有屬性和它們的類型,可以進(jìn)行以下操作:
安裝 PowerShell
PowerShell 安裝包的形式有若干種,包括 Fedora Linux 中使用的 RPM 安裝包。本文介紹在 Fedora Linux 中如何使用多種方法安裝 PowerShell。
我推薦使用原生的方法安裝。但我也會(huì)介紹如何在容器中安裝。我將展示使用官方微軟 PowerShell 容器和 Fedora Linux 30 的 Toolbox 容器。使用容器的優(yōu)點(diǎn)在于,所有的依賴?yán)壴谄渲?,并且與主機(jī)隔離,所以它一定是有效的。無(wú)論如何,雖然官方文檔只是明確指出支持 Fedora Linux 發(fā)行版的 28-30 版本,我還是建議使用原生的方法安裝。
注意: 官方支持意味著一定有效。但其他的版本也不是一定不兼容。也就是說(shuō),高于 30 的發(fā)行版也應(yīng)該有效。經(jīng)過(guò)測(cè)試,的確如此。
在容器中設(shè)置并運(yùn)行 PowerShell 比直接在主機(jī)上運(yùn)行它難度更大,安裝需要花費(fèi)更多時(shí)間,而且你還不能直接運(yùn)行主機(jī)的命令。
在主機(jī)上使用包管理器安裝 PowerShell
方法一:使用微軟倉(cāng)庫(kù)
安裝過(guò)程很直接,而且跟通過(guò)第三方倉(cāng)庫(kù)安裝其他軟件沒(méi)什么區(qū)別。
通俗地說(shuō),安裝過(guò)程可以分為四步:
- 添加新倉(cāng)庫(kù)的 GPG 密碼
- 在 DNF 倉(cāng)庫(kù)列表中新增相應(yīng)的倉(cāng)庫(kù)
- 刷新 DNF 緩存,將新倉(cāng)庫(kù)中的有關(guān)包包含進(jìn)來(lái)
- 安裝新包
然后使用命令 ??pwsh?
? 啟動(dòng) PowerShell。
欲刪除倉(cāng)庫(kù)和包,運(yùn)行以下命令:
方法 2:使用 PRM 文件
這種方法與第一種方法沒(méi)有明顯的差別。實(shí)際上,在安裝 RPM 文件時(shí),隱式添加了 GPG 密碼和倉(cāng)庫(kù)。這是由于 RPM 文件包含它們兩者的關(guān)聯(lián)關(guān)系,保存在它的元數(shù)據(jù)中。
首先,從 ??PowerShell GitHub 倉(cāng)庫(kù)?? 獲取相應(yīng)版本的 ??.rpm?
? 文件。然后查看 ??readme.md?
? 文件中的 “獲取 PowerShell” 部分的內(nèi)容。
第二步,輸入以下命令:
在 ??<version>?
? 和 ??<architecture>?
? 節(jié)點(diǎn)中填寫(xiě)各自的內(nèi)容,例如 ??powershell-7.1.3-1.rhel.7.x86_64.rpm??。
你也可以使用鏈接運(yùn)行它,不指定版本和架構(gòu),先把它下載到本地。
欲刪除 PowerShell,運(yùn)行以下命令:
通過(guò)容器安裝
方法一:使用 Podman 容器
Podman 是一個(gè)兼容 ??開(kāi)放容器倡議??(OCI)的、嵌入式的容器引擎,它可以代替 Docker。
微軟提供了 ??PowerShell Docker 容器集成工具??。下面的例子將在 Podman 中使用容器。
欲了解更多關(guān)于 Podman 的信息,可以訪問(wèn) ??Podman.io??。Fedora 雜志還有一個(gè)專為 Podman 設(shè)計(jì)的 ??標(biāo)簽??。
欲在 Podman 中使用 PowerShell,運(yùn)行以下腳本:
這段腳本為使用 PowerShell 創(chuàng)建了一個(gè) Podman 容器,并立即接入其中。它還將 ??/home?
? 和主機(jī)的根目錄掛載到容器中,確保它們?cè)谌萜髦惺强捎玫?。無(wú)論如何,在 ??/var/host?
? 目錄下,主機(jī)的根目錄是可訪問(wèn)的。
但是,在容器內(nèi)部,你只能間接運(yùn)行主機(jī)命令。有一種變通辦法,就是先運(yùn)行 ??chroot /var/host?
? 改變根目錄,然后運(yùn)行主機(jī)命令。
為了把命令拆分開(kāi)來(lái)講解,除非特別指定,以下所有內(nèi)容都是強(qiáng)制性的:
- ?
?-it?
? 創(chuàng)建一個(gè)持久環(huán)境,當(dāng)你進(jìn)入該環(huán)境后,不會(huì)輕易退出; - ?
?--privileged?
? 給予容器擴(kuò)展的權(quán)限(可選); - ?
?--rm?
? 當(dāng)你退出時(shí)移除容器; - ?
?--name?
? 設(shè)置容器名稱; - ?
?--env-host?
? 將所有主機(jī)的環(huán)境變量設(shè)置為容器的變量(可選); - ?
?--net=host --pid=host --ipc=host?
? 在主機(jī)的命名空間中運(yùn)行進(jìn)程(而非一組單獨(dú)的名稱空間); - ?
?--volume $HOME:$HOME?
? 掛載用戶目錄; - ?
?--volume /:/var/host?
? 將主機(jī)根目錄掛載到??/var/host?
?(可選); - ?
?mcr.microsoft.com/powershell?
? 進(jìn)入容器; - ?
?/usr/bin/pwsh?
? 可選但很方便的參數(shù):用別名??pwsh?
?,腳本中有了它,可以輸入??pwsh?
? 輕松訪問(wèn) Podman 容器; - ?
?-WorkingDirectory $(pwd)?
? 在當(dāng)前目錄下進(jìn)入容器(可選)。
欲移除 PowerShell 鏡像,運(yùn)行以下命令:
方法二:Fedora 系統(tǒng)的 Toolbox 容器
在不影響主機(jī)系統(tǒng)的情況下安裝持久化環(huán)境,使用 Toolbox 容器是一種巧妙的解決方案。它充當(dāng)了 Podman 的封裝器,負(fù)責(zé)提供大量的標(biāo)志,就像方法一中提到的那樣。因此,Toolbox 比 Podman 容易使用。它可以用來(lái)開(kāi)發(fā)和調(diào)試。有了 Toolbox,你可以運(yùn)行任何命令,跟你直接在 Fedora 工作站主機(jī)上運(yùn)行是一樣的。
安裝步驟跟在主機(jī)上安裝一樣,唯一的區(qū)別就是在容器內(nèi)部進(jìn)行。你需要確保已經(jīng)安裝了 ??toolbox?
? 包。
使用 Fedora 34 Toolbox 容器需要兩個(gè)步驟:
- 創(chuàng)建 Fedora 34 Toolbox 容器
- 運(yùn)行 Fedora 34 Toolbox 容器
接著,按照 ??方法一:使用微軟倉(cāng)庫(kù)?? 中的相關(guān)內(nèi)容操作。
可選但非常方便的做法:使用別名 ??pwsh?
?,可以輕松地訪問(wèn) Toolbox 容器:
欲移除 Toolbox 容器,需要確保你已經(jīng)使用 ??exit?
? 關(guān)閉了 Toolbox 會(huì)話,然后運(yùn)行以下命令: