當我啟動 shell 時,在我的例子中是 bash 和/或 zsh,我需要向 .zshrc 和/或 .bashrc 添加哪些行來檢查程式是否已經在運行,以及程式是否尚未運行,啟動它?
範例:我正在啟動一個新的 zsh shell。如果 top 尚未運行,我想啟動 top 並讓它接管 shell。如果 top 已經在另一個視窗中運行,我希望 .zshrc 繼續加載並給我一個打開的終端。
6-16更新:
if ! pgrep -U $USER top >/dev/null; then
exec top
fi
上面的腳本滿足了我的要求。 -q 標誌對我不起作用,因為 -q 不是我的系統上的選項。所以我必須將 PID 透過管道傳輸到 /dev/null。謝謝 mveroone、Kusalananda 和 Thomas Dickey。
我有一些功能蔓延超出了原始問題的範圍。假設我在單一使用者係統上,無需輸入密碼即可成為 root 使用者。如果需要的話,我如何以root身分自動運行top?
6-18 好的,以 root 身分傳遞指令的功能蔓延問題已解決。我用它來啟動幾個
感謝您所有深思熟慮的回覆。
答案1
pgrep
像這樣使用:
if ! pgrep -u $USER top >/dev/null 2>&1; then
exec top
fi
解釋:
pgrep
如果發現該命令正在運行,則實用程式將以零退出代碼退出。因此,否定該測試。- 也可以使用 來將其限制為當前用戶
-u $USER
,這樣它就不會因為某種原因而獲取其他人的進程。$USER
是一個標準的 shell 變數。如果由於某種原因未定義,請嘗試使用$LOGNAME
,如果失敗,請使用$( id -n -u )
(但此時您必須問自己發生了什麼事,因為$LOGNAME
是也標準 shell 變數)。 - 我們不需要 的輸出
pgrep
,因此將標準輸出和錯誤流重定向到/dev/null
。
如果top
(或其他)未發現正在運行,則exec
根據OP的問題,它會替換外殼。
這應該適用於所有sh
相容的 shell。
編輯:pgrep
BSD 系統(OS X,OpenBSD,...)上的實作有一個-q
選項可以讓它丟棄任何輸出,但pgrep
Linux 上顯然沒有這個標誌。在 BSD 系統上,使用這個而不是稍微難看的重定向到/dev/null
.
答案2
如果程式始終從 shell 啟動並且您可以完全控制它(即它沒有在第 3 方程式中硬編碼),那麼您可以使用某種鎖定機制,例如lockfile
或flock
。例如透過新增
flock -n /tmp/top -c top
到.bashrc
/.zshrc
您將確保只有 shell 的第一個實例將運行該top
命令(除非您殺死它,然後將啟動另一個實例)。
您可能想要建立一個函數,以便能夠手動啟動命令(而不僅僅是在 shell 初始化時):
mytop () { flock -n /tmp/$0 -c top; }
mytop
只要你想跑就跑。
答案3
同意這pgrep
是要走的路,但也存在一些陷阱。您不需要使用該-q
選項,因為您可以重定向輸出pgrep
來消除該問題:
pgrep -U $USER top >/dev/null || exec top
陷阱在於它不是標準實用程序,因此您必須記住它可能不可移植。以下是一些幫助頁面連結:
環境USER
變數更加完善,但似乎不在 POSIX 的 shell 清單中(請參閱2.5.3 Shell 變數)。相反,它指出這USER
是已知正在使用的許多變數之一(請參閱註釋8.1 環境變數定義)。
這運行top
為你自己, 當然。如果您選擇讓它運行為根,然後您可以將 變更$USER
為然後使用(首選)或root
運行。 POSIX 中都不存在(top
sudo
su
查看列表)。後者 ( su
) 在類 Unix 系統上隨處可用,但sudo
通常是首選。所以你會有
pgrep -U root top >/dev/null || exec sudo top
除非您已設定sudo
為不需要密碼,否則 shell 啟動時將提示您輸入密碼top
。
答案4
我會在我的 .zshrc (或其他)中附加這樣的片段:
if pgrep -u $USER 程式名 然後 執行程式名 菲
警告 :我還沒有測試過這段程式碼。請不要在 root 或伺服器上唯一的使用者上使用它。確保失敗時可以恢復。