Bash

如何檢測我是否在子外殼中?

  • June 19, 2019

我正在嘗試編寫一個函式來替換exit內置函式的功能,以防止自己退出終端。

我試圖使用SHLVL環境變數,但它似乎在子shell中沒有改變:

$ echo $SHLVL
1
$ ( echo $SHLVL )
1
$ bash -c 'echo $SHLVL'
2

我的功能如下:

exit () {
   if [[ $SHLVL -eq 1 ]]; then
       printf '%s\n' "Nice try!" >&2
   else
       command exit
   fi
}

這將不允許我exit在子shell中使用:

$ exit
Nice try!
$ (exit)
Nice try!

檢測我是否在子shell中的好方法是什麼?

在 bash 中,您可以$BASHPID比較$$

$ ( if [ "$$" -eq "$BASHPID" ]; then echo not subshell; else echo subshell; fi )
subshell
$   if [ "$$" -eq "$BASHPID" ]; then echo not subshell; else echo subshell; fi
not subshell

如果您不在 bash 中,$$則在子 shell 中應該保持不變,因此您需要一些其他方法來獲取您的實際程序 ID。

獲取實際 pid 的一種方法是sh -c 'echo $PPID'. 如果你只是把它放在一個簡單的( … )地方,它可能看起來不起作用,因為你的 shell 已經優化了 fork。嘗試額外的 no-op 命令( : ; sh -c 'echo $PPID'; : ),讓它認為 subshel​​l 太複雜而無法優化。這種方法歸功於 Stack Overflow 上的John1024 。

引用自:https://unix.stackexchange.com/questions/524506