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
呼び出しプロセスに制御端末がないことを示します。
initで呼び出すときにBashに制御端末がないのはなぜですか?
ベストアンサー1
これ制御端子bash
準備(開封)されましたlogin
。したがって、bash
initskiingを直接呼び出すと、login
制御端末が信号処理に特別な役割を果たすため、上記の問題が発生します。
ソースコードによるとlogin.c(中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); openlog("login", LOG_ODELAY, LOG_AUTHPRIV); /* reopen */ /* * TIOCSCTTY: steal tty from other process group. */ if (ioctl(0, TIOCSCTTY, 1)) syslog(LOG_ERR, _("TIOCSCTTY failed: %m"));
新しいプロセスでログインシェルを実行します。(返品
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);
概念への追加リンク制御端子: