在一个脚本里,要获取其父shell时,使用了下面的方式:
#!/bin/bash
ps -ocomm= -p $(ps -oppid= $$)
它在某些环境下,父shell会显示为 “/usr/local/bin/zsh” 或者 “bash” ,而某些环境下却会显示为”-bash”或”-zsh”;这个开头多出来的连字符是怎么回事?查了一下,原来是表示的是”login shell”。
linux下可以在”/etc/passwd”里看到用户的login shell,而在mac下要确认当前用户的login shell,要通过下面的命令:
$ dscl . read /users/$USER UserShell
UserShell: /bin/bash
在mac下,当打开终端程序(Terminal.app)时,终端shell是login
进程的子进程(不管你配置那种command):
$ pstree
...
|-+= 01272 hongjiang /Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
| \-+= 01275 root login -pf hongjiang
| \-+= 01276 hongjiang -bash
...
$ ps -ef | grep login
0 1275 1272 0 2:05PM ttys000 0:00.05 login -pf hongjiang
# 把Terminal的启动命令修改为zsh也一样
|-+= 01988 hongjiang /Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
| \-+= 01991 root login -pf hongjiang /bin/zsh | \-+= 01992 hongjiang -zsh
而在mac的 iTerm.apprm 下,不管如果你配置的command是”Login shell”还是修改为其他shell,启动后shell没有再挂在login
进程下:
$ pstree
|-+= 00574 hongjiang /Volumes/Data/program/iTerm.app/Contents/MacOS/iTerm
| \-+= 02177 hongjiang /usr/local/bin/zsh
但在iTerm下如果使用的是“Login shell”显示的名称前边却是有连字符的,而其他shell则没有
$ ps $$
PID TT STAT TIME COMMAND
2220 s001 Ss 0:00.01 -/bin/bash
# 修改启动shell为zsh
➜ ps $$
PID TT STAT TIME COMMAND
2524 s000 Ss 0:00.16 /usr/local/bin/zsh
在linux下,从tty登录shell也是一样由login
进程启动的
$ ps -ef | grep bash
hongjia+ 2241 467 0 14:09 tty1 00:00:00 -bash
$ pstree
systemd─┬─NetworkManager─┬─2*[dhclient]
│ └─3*[{NetworkManager}]
├─...
├─login───bash
...
$ ps -ef | grep login
root 467 0.0 0.2 84584 2328 ? Ss 14:08 0:00 login -- hongjiang
使用su命令切换到一个用户shell下,默认情况这个shell并不是”login shell”不会去执行/etc/profile和home目录下相关配置:
$ sudo su hongjiang
$ ps -ef | grep $$
hongjia+ 2796 2795 0 14:57 pts/0 00:00:00 bash
要以”login shell”方式启动,需要对su
指定一个参数“-“
$ sudo su - hongjiang
$ ps -ef | grep $$
hongjia+ 3188 3187 0 15:35 pts/0 00:00:00 -bash
从bash文档里可以看到,要以”login shell”方式启动一个shell,要么第一个参数给一个特定的连字符“-”,要么显式的对bash设定”–login”参数。