Bash
如果作為 init 呼叫,為什麼不能 bash 映射 ^C 到 intr 信號?
如果我將 bash 作為呼叫的第一個程序(即作為 init),結果它將顯示以下內容:
init: cannot set terminal process group (-1): Inappropriate ioctl for device init: no job control in this shell
並且沒有信號(例如^C,^Z)起作用。
通過閱讀bash-5.1.12的源碼,問題出在
job.c
4501行的表達式:(t = tcgetpgrp (shell_tty)) == -1
錯誤值為
ENOTTY
,表示呼叫程序沒有控制終端。為什麼 Bash 在作為 init 呼叫時沒有控制終端?
的控制終端由(實際上最初由,然後 getty execute )
bash
準備(打開)。因此,如果直接呼叫為 init skiping ,它會在上面拋出這個問題,因為控制終端在處理信號方面起著特殊的作用。login``getty``login``bash``login
根據源碼login.c(in ), in
util-linux
的呼叫過程大致如下:bash``login
- main() 呼叫 fork_session()
/* * Detach the controlling terminal, fork, and create a new session * and reinitialize syslog stuff. */ fork_session(&cxt);
- 分叉一個新程序。(在
fork_session()
功能中)child_pid = fork();
- 使新流程成為會話負責人。 為了獲得控制終端,該程序必須先成為會話領導者。(在
fork_session()
功能中)/* start new session */ setsid();
- **獲取會話負責人的控制 tty。**會話領導者通過
open
tty 獲取控制終端。(在fork_session()
功能中)/* make sure we have a controlling tty */ open_tty(cxt->tty_path);
- 在新程序中執行登錄 shell。(返回
main()
)/* if the shell field has a space: treat it like a shell script */ if (strchr(pwd->pw_shell, ' ')) { char *buff; xasprintf(&buff, "exec %s", pwd->pw_shell); child_argv[child_argc++] = "/bin/sh"; child_argv[child_argc++] = "-sh"; child_argv[child_argc++] = "-c"; child_argv[child_argc++] = buff; } else { char tbuf[PATH_MAX + 2], *p; tbuf[0] = '-'; xstrncpy(tbuf + 1, ((p = strrchr(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell), sizeof(tbuf) - 1); child_argv[child_argc++] = pwd->pw_shell; child_argv[child_argc++] = xstrdup(tbuf); } child_argv[child_argc++] = NULL; /* http://www.linux-pam.org/Linux-PAM-html/adg-interface-by-app-expected.html#adg-pam_end */ (void) pam_end(cxt.pamh, PAM_SUCCESS|PAM_DATA_SILENT); execvp(child_argv[0], child_argv + 1);
更多關於控制終端概念的連結: