On macOS why "ps" always shows session id as "0"

Session ID

The session ID is actually pid of iTerm2 --server login -fp in this case, ps in OS X doesn't show it correctly though. You can confirm it with below C code.

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 
  4 int main() {
  5   printf("pid: %d, process groupd id: %d, session ID: %d, ppid: %d\n",getpid(), getpgid(0), getsid(0), getppid());
  6 }
$ gcc getsid.c -o getsid ; ./getsid
pid: 25472, process groupd id: 25472, session ID: 25236, ppid: 25239

The session leader is process 25236, which is iTerm2 --server login -fp

$ pstree -p $$
-+= 00001 root /sbin/launchd
 \-+= 25234 shaobirui /Applications/iTerm.app/Contents/MacOS/iTerm2
   \-+= 25236 shaobirui /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp shaobirui
     \-+= 25237 root login -fp shaobirui
       \-+= 25239 shaobirui -bash
         \-+= 25329 shaobirui pstree -p 25239
           \--- 25330 root ps -axwwo user,pid,ppid,pgid,command

The other neat way is to check STAT field, you can see Ss, the second lower s actually means session leader.

$ ps -j
USER        PID  PPID  PGID   SESS JOBC STAT   TT       TIME COMMAND
shaobirui 25236 25234 25236      0    0 Ss   s000    0:00.03 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp shaobirui
shaobirui 25239 25237 25239      0    1 S    s000    0:00.05 -bash

Why Children Got Killed?

When session leader exits, it will send SIGHUP to all its descendants, which terminates processes by default. I reproduce it in two terminal emulators: iTerm2 and OS X termianl.

in iTerm2:

$ tty
/dev/ttys000

$ cat test.sh
trap "echo $$ got SIGUP > /tmp/out.txt;exit" 1
echo $$ is sleeping
sleep 5555

$ bash test.sh
25000 is sleeping

in OS X terminal:

$ pstree -p 25000
-+= 00001 root /sbin/launchd
 \-+= 24875 shaobirui /Applications/iTerm.app/Contents/MacOS/iTerm2
   \-+= 24877 shaobirui /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp shaobirui
     \-+= 24878 root login -fp shaobirui
       \-+= 24879 shaobirui -bash
         \-+= 25000 shaobirui bash test.sh
           \--- 25001 shaobirui sleep 5555

$ ps -j -o tpgid 24875 24878 24879 25000 25001
USER        PID  PPID  PGID   SESS JOBC STAT   TT       TIME COMMAND          TPGID
shaobirui 24875     1 24875      0    1 S      ??    0:07.97 /Applications/iT     0
shaobirui 24877 24875 24877      0    0 Ss   s000    0:00.04 /Applications/iT 25000
shaobirui 24879 24878 24879      0    1 S    s000    0:00.03 -bash            25000
shaobirui 25000 24879 25000      0    1 S+   s000    0:00.00 bash test.sh     25000
shaobirui 25001 25000 25000      0    1 S+   s000    0:00.00 sleep 5555       25000
shaobirui 22134 22133 22134      0    1 S    s001    0:00.40 -bash            25021

$ kill 24877

# all processes in that session are gone due to SIGHUP
$ ps -j -o tpgid 24875 24878 24879 25000 25001
USER        PID  PPID  PGID   SESS JOBC STAT   TT       TIME COMMAND TPGID
shaobirui 22134 22133 22134      0    1 S    s001    0:00.41 -bash   25032

$ cat /tmp/out.txt 
25000 got SIGUP