
我多年來一直是 GNU/Linux 用戶,但我不知道如何在 Mac 上取得可用的進程資訊。
我意識到在 Mac OS (Snow Leopard) 上的登入 shell 中$0
可以解決這個問題。-bash
這可能會破壞某些在 Linux 環境中正常運作的 shell 腳本*。
不幸的是,手冊頁沒有提到這個事實
如果使用命令檔案呼叫 bash,則 $0 將設定為該檔案的名稱。如果 bash 使用 -c 選項啟動,則 $0 將設定為要執行的字串之後的第一個參數(如果存在)。否則,它被設定為用於呼叫 bash 的檔名,如參數零所示。
減號有什麼特殊意義嗎?有沒有類似的/proc
命令列工具可以幫助我找到相關的執行檔?
*我真傻。當然,$0 將計算為腳本名稱,如手冊中所述
答案1
減號是系統告訴 shell 它作為登入 shell 呼叫並且應該獲取來源的方式~/.profile
(對於 Bourne 相容的 shell)。在 Linux、OSX 和所有其他 UNIX 上都是如此。腳本不會在登入 shell 中執行。對於腳本,$0
是腳本檔案的名稱(有或沒有完整路徑)。
添加:手冊頁確實解釋了(幾乎所有)不同的情況:
“如果使用命令檔案呼叫 bash,則 $0 將設定為該檔案的名稱。”這涵蓋了以 執行的腳本
bash myscript
,以及直接執行腳本並以 開頭的間接情況#!/bin/bash
。“如果 bash 使用 -c 選項啟動,則 $0 被設定為要執行的字串之後的第一個參數(如果存在)。”對於
-c
,$0
設定為調用者明確指示的任何內容。“否則,它被設定為用於調用 bash 的文件名,如參數零所示。”登入 shell 屬於這種情況:呼叫 shell 時除了參數零之外沒有任何參數,因此
$0
設定為參數零。它是login
、su
或任何處理登入的程序,該程式選擇傳遞給 shell 的參數,並在-
參數零前面加上 a 來告訴 shell 它是登入 shell。
也許對參數零的一些解釋是適當的。當程式執行時,最終execve
會發生系統呼叫。此系統調用需要三個參數:
檔案名,必須指定現有的可執行檔。核心載入該檔案並將執行轉移給它。
字串數組,稱為參數。該數組中的元素零是按照慣例與上面相同的檔案名,或如果透過搜尋環境變數確定可執行檔案的位置,則僅使用不含完整路徑的檔案名稱
$PATH
。此約定也有例外,例如登入 shell。另一個字串數組,稱為環境。
當您透過鍵入 來從 shell 呼叫程式時myprogram foo bar
,參數為execve
:
1. /usr/bin/myprogram
(假設這是 shell 找到 的位置myprogram
)
2. myprogram
, foo
, bar
3. 對於每個導出的 shell 變量,變數名後面跟著等號和值。
沒有通用的方法來尋找execve
從正在執行的程式傳遞到的可執行檔的名稱。在 Linux 下,通常可以透過進程 ID/proc/$$/exe
來取得。$$
每個 UNIX 都可以使用它,ps
但內部運作方式卻ps
大不相同。程式運行時可執行檔可能被刪除或重新命名;在這種情況下,ps
可能會報告過時的資訊或不報告任何資訊。
答案2
從man bash
:
exec [-cl] [-a name] [command [arguments]]
如果指定了 command,它將取代 shell。沒有建立新進程。這些參數成為命令的參數。如果提供了 -l 選項,shell 會在傳遞給指令的第 0 個參數的開頭放置一個破折號。這就是登入(1)的作用。 …
答案3
我不確定 -bash 發生了什麼,但是如果您在 shell 中再次運行 bash ,則 $0 的值似乎沒問題。
這似乎是 os x 正在做的一些特殊事情,因為如果您執行 /usr/bin/login(終端程式使用的預設腳本),則會出現與 $0 相同的問題。