查看由 agetty 解析的 /etc/issue

查看由 agetty 解析的 /etc/issue

如果我理解正确的话,/etc/issue将在控制台中显示代理

我想查看/etc/issue,如agetty- 所解析的,但我不想启动任何登录会话或任何相关内容。我只想要一个/etc/issue带有解析命令的 - 文本转储。

这可能吗? 怎么做?

答案1

我认为没有一个实用程序可以满足您的要求。来源代码函数 do_prompt(...) 基本上打开 /etc/issue 文件并逐个字符读取它,然后显示读取的字符,或者如果是,则\读取下一个字符,然后输入 switch 语句以显示相关信息。将其转换为脚本并不难……无论如何,这是相关代码

void
do_prompt(op, tp)
     struct options *op;
     struct termios *tp;
{
#ifdef  ISSUE
    FILE    *fd;
    int     oflag;
    int     c;
    struct utsname uts;

    (void) uname(&uts);
#endif

    (void) write(1, "\r\n", 2);         /* start a new line */
#ifdef  ISSUE                   /* optional: show /etc/issue */
    if ((op->flags & F_ISSUE) && (fd = fopen(op->issue, "r"))) {
    oflag = tp->c_oflag;            /* save current setting */
    tp->c_oflag |= (ONLCR | OPOST);     /* map NL in output to CR-NL */
    (void) tcsetattr(0, TCSADRAIN, tp);


    while ((c = getc(fd)) != EOF)
    {
        if (c == '\\')
          {
        c = getc(fd);

        switch (c)
          {
          case 's':
            (void) printf ("%s", uts.sysname);
            break;

          case 'n':
            (void) printf ("%s", uts.nodename);
            break;

          case 'r':
            (void) printf ("%s", uts.release);
            break;

          case 'v':
            (void) printf ("%s", uts.version);
            break;

          case 'm':
            (void) printf ("%s", uts.machine);
            break;

          case 'o':
           {
             char domainname[MAXHOSTNAMELEN+1];
#ifdef HAVE_GETDOMAINNAME
             if (getdomainname(domainname, sizeof(domainname)))
#endif
             strcpy(domainname, "unknown_domain");
             domainname[sizeof(domainname)-1] = '\0';
             printf ("%s", domainname);
           }
          break;

          case 'O':
           {
            char *dom = "unknown_domain";
            char host[MAXHOSTNAMELEN+1];
            struct addrinfo hints, *info = NULL;

            memset(&hints, 0, sizeof(hints));
            hints.ai_flags = AI_CANONNAME;

            if (gethostname(host, sizeof(host)) ||
                getaddrinfo(host, NULL, &hints, &info) ||
                info == NULL)
                fputs(dom, stdout);
            else {
                char *canon;

                if (info->ai_canonname &&
                    (canon = strchr(info->ai_canonname, '.')))
                    dom = canon + 1;
                fputs(dom, stdout);
                freeaddrinfo(info);
            }
           }
          break;

          case 'd':
          case 't':
            {
              /* TODO: use nl_langinfo() */
              char *weekday[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
                      "Fri", "Sat" };
              char *month[] = { "Jan", "Feb", "Mar", "Apr", "May",
                    "Jun", "Jul", "Aug", "Sep", "Oct",
                    "Nov", "Dec" };
              time_t now;
              struct tm *tm;

              (void) time (&now);
              tm = localtime(&now);

              if (c == 'd')
            (void) printf ("%s %s %d  %d",
                weekday[tm->tm_wday], month[tm->tm_mon],
                tm->tm_mday, 
                tm->tm_year < 70 ? tm->tm_year + 2000 :
                tm->tm_year + 1900);
              else
            (void) printf ("%02d:%02d:%02d",
                tm->tm_hour, tm->tm_min, tm->tm_sec);

              break;
            }

          case 'l':
              (void) printf ("%s", op->tty);
              break;

          case 'b':
            {
            int i;

            for (i = 0; speedtab[i].speed; i++) {
                if (speedtab[i].code == cfgetispeed(tp)) {
                printf("%ld", speedtab[i].speed);
                break;
                }
            }
            break;
            }
          case 'u':
          case 'U':
            {
              int users = 0;
              struct utmp *ut;
              setutent();
              while ((ut = getutent()))
                if (ut->ut_type == USER_PROCESS)
              users++;
              endutent();
              printf ("%d ", users);
              if (c == 'U')
                printf ((users == 1) ? _("user") : _("users"));
              break;
            }
          default:
            (void) putchar(c);
          }
          }
        else
          (void) putchar(c);
    }
    fflush(stdout);

    tp->c_oflag = oflag;            /* restore settings */
    (void) tcsetattr(0, TCSADRAIN, tp); /* wait till output is gone */
    (void) fclose(fd);
    }
#endif
    {
    char hn[MAXHOSTNAMELEN+1];
    if (gethostname(hn, sizeof(hn)) == 0)
        write(1, hn, strlen(hn));
    }
    (void) write(1, LOGIN, sizeof(LOGIN) - 1);  /* always show login prompt */
}

答案2

此项特定功能请求于util-linux#828.util
-linux 2.35(发布于 2020-01-21)引入对此有一个标志:

$ agetty --show-issue
Debian GNU/Linux bookworm/sid tabasco tty0

$

如果您使用的是旧版本的 util-linux,您可以这样做:

$ agetty -N8nl /bin/true -f <(sed "s@\\l@$(tty |sed 's:^/dev/::')@g" /etc/issue) -

这会抑制登录,但agetty会看到用户名-,因此我们拦截issue文件并替换\l为当前 TTY(来自tty删除前导的命令/dev/),因此它不会显示为--N抑制前导换行符,-8禁用 tty 奇偶校验检测,-n抑制登录(但不抑制登录命令的错误),并-l /bin/true在 的位置设置一个虚拟可执行文件/bin/login

答案3

你可以尝试

agetty -8n - linux
  • -8禁用奇偶校验检测,假设 tty 是 8 位干净的
  • -n禁止登录提示

更多细节,man agetty

相关内容