linux getty命令

命令简介

getty(get tty)是Linux系统中用于管理终端登录的程序,负责在终端上显示登录提示,验证用户身份,并启动用户会话。它是系统初始化进程的重要组成部分,管理虚拟控制台和串行终端的登录界面。

注意:现代Linux系统中常用的getty实现包括agettymingettymgetty等,它们各有特点,适用于不同的场景。

基本语法

# 基本格式
getty [选项] 波特率 终端类型 [终端设备]

# 常用格式
getty 38400 tty1
getty -L 115200 ttyS0 vt100
getty -I "欢迎登录" tty2

agetty格式:

agetty [选项] 端口 终端类型
agetty -l /bin/login tty1 linux
agetty --noclear tty2

mingetty格式:

mingetty [选项] tty
mingetty --autologin root tty1
mingetty tty2

getty实现类型对比

类型 描述 特点 适用场景
agetty GNU getty实现,功能最全 支持串行和虚拟终端,可配置性强 通用Linux系统,需要丰富功能
mingetty 最小化getty,轻量级 只支持虚拟终端,功能简单 嵌入式系统,资源有限环境
mgetty 专门用于调制解调器 支持传真和数据通信 调制解调器拨入系统
uugetty UUCIP getty 文件传输和邮件处理 老式UUCP系统
fbgetty FrameBuffer getty 支持图形控制台 图形化启动环境

常用选项

选项 描述
-L 不进行载波检测(用于硬连线终端)
-m 尝试从调制解调器读取波特率
-I 初始字符串 在登录提示前显示初始字符串
-t 超时 设置登录超时时间(秒)
-h 不显示主机名在登录提示中
-w 等待回车键后显示登录提示
-n 不提示输入用户名
-l 登录程序 指定替代的登录程序
-f 问题文件 指定包含登录问题的文件
-H 登录主机名 在登录提示中指定主机名

agetty特有选项:

选项 描述
--noclear 不清屏,保留启动信息
--nohangup 登录失败后不断开连接
--autologin 用户 自动登录指定用户
--login-program 程序 指定登录程序(默认为/bin/login)
--login-options 选项 传递给登录程序的选项
--issue-file 文件 指定issue文件(默认为/etc/issue)
--noissue 不显示issue文件内容

实际示例

示例1:虚拟控制台配置

配置虚拟控制台(tty1-tty6):

# 查看当前活动的虚拟控制台
who
# 输出示例:
# root     tty1         2023-10-01 10:00
# user1    tty2         2023-10-01 10:05

# 查看所有tty设备
ls -la /dev/tty*
# 虚拟控制台:/dev/tty1, /dev/tty2, ...

# 在tty1上启动getty(手动启动)
sudo agetty tty1 linux
# 或
sudo getty 38400 tty1

# 配置自动登录(agetty)
# 在systemd服务文件中添加:--autologin root
# 或通过编辑/etc/inittab(sysvinit系统)

# 禁用虚拟控制台
# 编辑systemd服务文件,注释或删除对应配置
# 或运行:
sudo systemctl stop getty@tty3.service
sudo systemctl disable getty@tty3.service

# 启用虚拟控制台
sudo systemctl start getty@tty3.service
sudo systemctl enable getty@tty3.service

# 查看getty服务状态
sudo systemctl status getty@tty1.service
sudo systemctl status getty@tty2.service

# 重启getty服务
sudo systemctl restart getty@tty1.service

# 查看所有tty的getty进程
ps aux | grep getty
# 输出示例:
# root      1234  0.0  0.1  12345  6789 tty1    Ss+  10:00   0:00 /sbin/agetty --noclear tty1 linux

示例2:串行终端配置

配置串行端口作为登录终端:

# 查看串行端口
ls -la /dev/ttyS*
# 输出示例:/dev/ttyS0, /dev/ttyS1, /dev/ttyUSB0

# 设置串行端口权限
sudo chmod 666 /dev/ttyS0
# 或添加用户到dialout组
sudo usermod -a -G dialout $USER

# 在ttyS0上启动getty(波特率115200)
sudo agetty -L 115200 ttyS0 vt100
# 传统getty
sudo getty -L ttyS0 115200 vt100

# 配置自动登录串行终端
sudo agetty -L 115200 --autologin root ttyS0 vt100

# 在系统启动时启用串行终端
# 对于systemd系统,创建服务文件:
sudo nano /etc/systemd/system/serial-getty@ttyS0.service
# 内容:
[Unit]
Description=Serial Getty on %I
BindTo=dev-%i.device
After=dev-%i.device systemd-user-sessions.service

[Service]
ExecStart=-/sbin/agetty -L 115200 %I $TERM
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
KillMode=process

[Install]
WantedBy=multi-user.target

# 启用服务
sudo systemctl enable serial-getty@ttyS0.service
sudo systemctl start serial-getty@ttyS0.service

# 查看串行终端状态
sudo systemctl status serial-getty@ttyS0.service

# 测试串行终端连接
# 使用minicom或screen连接
sudo minicom -D /dev/ttyS0
# 或
screen /dev/ttyS0 115200

示例3:自定义登录界面

自定义登录提示和信息:

# 编辑issue文件(显示在登录提示前)
sudo nano /etc/issue
# 添加自定义信息,例如:
# 欢迎使用 MyLinux 系统
# 内核版本: \n
# 系统时间: \t
# 特殊字符:
# \d - 当前日期
# \l - 当前终端
# \m - 机器架构
# \n - 主机名
# \o - 域名
# \r - 内核版本
# \t - 当前时间
# \s - 操作系统名称
# \v - 内核版本

# 编辑issue.net文件(网络登录显示)
sudo nano /etc/issue.net
# 网络登录时显示的信息

# 测试issue文件
sudo agetty --issue-file /etc/issue tty1 linux

# 创建每个tty不同的issue文件
sudo nano /etc/issue.tty1
# 内容:这是tty1控制台
sudo agetty --issue-file /etc/issue.tty1 tty1 linux

# 在agetty中使用自定义欢迎信息
sudo agetty -I "欢迎登录生产服务器" tty1 linux

# 禁用issue文件显示
sudo agetty --noissue tty1 linux

# 修改登录提示文字
# 编辑/etc/login.defs
sudo nano /etc/login.defs
# 修改:
# LOGIN_STRING     "MyLinux Login: "

# 或通过agetty参数
sudo agetty --login-options "-h MyServer" tty1 linux

# 使用自定义登录程序
sudo agetty --login-program /bin/mylogin tty1 linux

# 创建自定义登录脚本
sudo nano /usr/local/bin/mylogin
#!/bin/bash
echo "自定义登录程序"
echo -n "用户名: "
read username
echo -n "密码: "
read -s password
echo
# 这里添加认证逻辑
# 成功后启动shell
exec /bin/bash

# 设置权限
sudo chmod +x /usr/local/bin/mylogin

# 使用自定义登录程序
sudo agetty --login-program /usr/local/bin/mylogin tty2 linux

示例4:systemd中的getty配置

在systemd系统中配置getty:

# 查看所有getty服务
systemctl list-units --type=service | grep getty
# 输出示例:
# getty@tty1.service    loaded active running   Getty on tty1
# getty@tty2.service    loaded active running   Getty on tty2

# 查看特定getty服务文件
systemctl cat getty@tty1.service
# 或
cat /usr/lib/systemd/system/getty@.service

# 创建自定义getty配置
sudo mkdir -p /etc/systemd/system/getty@tty1.service.d/
sudo nano /etc/systemd/system/getty@tty1.service.d/override.conf
# 内容:
[Service]
# 自动登录
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear %I $TERM
# 或自定义选项
# ExecStart=-/sbin/agetty -I "生产服务器" --noissue %I $TERM

# 重新加载systemd配置
sudo systemctl daemon-reload
sudo systemctl restart getty@tty1.service

# 创建新的getty实例
sudo cp /usr/lib/systemd/system/getty@.service /etc/systemd/system/getty-special@.service
sudo nano /etc/systemd/system/getty-special@.service
# 修改ExecStart行

# 启用新的getty实例
sudo systemctl enable getty-special@tty3.service
sudo systemctl start getty-special@tty3.service

# 修改默认的getty参数
# 编辑/etc/systemd/logind.conf
sudo nano /etc/systemd/logind.conf
# 修改:
# NAutoVTs=6          # 自动创建的虚拟终端数量
# ReserveVT=6         # 为显示管理器保留的VT
# KillUserProcesses=yes  # 用户注销时杀死其进程

# 重新启动logind服务
sudo systemctl restart systemd-logind

# 查看当前活动的虚拟终端
loginctl list-sessions
# 或
loginctl

# 强制注销特定tty的用户
sudo loginctl terminate-session 会话ID
# 或
sudo pkill -9 -t tty2

示例5:高级配置和脚本

高级getty配置和自动化脚本:

#!/bin/bash
# 文件名: configure-getty.sh
# 自动配置getty脚本

# 定义颜色
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color

# 函数:检查命令是否存在
check_command() {
    if ! command -v $1 &> /dev/null; then
        echo -e "${RED}错误: $1 命令未找到${NC}"
        exit 1
    fi
}

# 检查必要命令
check_command agetty
check_command systemctl

# 配置虚拟终端数量
configure_vt_count() {
    echo "配置虚拟终端数量..."

    # 当前VT数量
    CURRENT_VT=$(grep -i "^NAutoVTs" /etc/systemd/logind.conf 2>/dev/null | cut -d= -f2 | tr -d ' ')

    if [ -z "$CURRENT_VT" ]; then
        CURRENT_VT=6
    fi

    read -p "当前虚拟终端数量: $CURRENT_VT,请输入新的数量 (1-12): " NEW_VT

    if [[ $NEW_VT =~ ^[0-9]+$ ]] && [ $NEW_VT -ge 1 ] && [ $NEW_VT -le 12 ]; then
        # 备份原文件
        sudo cp /etc/systemd/logind.conf /etc/systemd/logind.conf.backup.$(date +%Y%m%d)

        # 更新配置
        if grep -q "^NAutoVTs" /etc/systemd/logind.conf; then
            sudo sed -i "s/^NAutoVTs=.*/NAutoVTs=$NEW_VT/" /etc/systemd/logind.conf
        else
            echo "NAutoVTs=$NEW_VT" | sudo tee -a /etc/systemd/logind.conf
        fi

        # 重启服务
        sudo systemctl restart systemd-logind

        echo -e "${GREEN}虚拟终端数量已设置为 $NEW_VT${NC}"
    else
        echo -e "${RED}无效的虚拟终端数量${NC}"
    fi
}

# 配置自动登录
configure_autologin() {
    echo "配置自动登录..."

    read -p "要自动登录的tty编号 (如1,2,3): " TTY_NUM
    read -p "自动登录的用户名: " USERNAME

    if id "$USERNAME" &>/dev/null; then
        # 创建覆盖配置文件
        OVERRIDE_DIR="/etc/systemd/system/getty@tty${TTY_NUM}.service.d"
        sudo mkdir -p $OVERRIDE_DIR

        cat << EOF | sudo tee $OVERRIDE_DIR/autologin.conf
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin $USERNAME --noclear %I \$TERM
EOF

        # 重新加载配置
        sudo systemctl daemon-reload
        sudo systemctl restart getty@tty${TTY_NUM}.service

        echo -e "${GREEN}tty${TTY_NUM} 已配置为自动登录用户 $USERNAME${NC}"
    else
        echo -e "${RED}用户 $USERNAME 不存在${NC}"
    fi
}

# 配置串行终端
configure_serial() {
    echo "配置串行终端..."

    read -p "串行端口 (如ttyS0, ttyUSB0): " SERIAL_PORT
    read -p "波特率 (如115200, 9600): " BAUD_RATE

    # 检查串行端口是否存在
    if [ ! -c "/dev/$SERIAL_PORT" ]; then
        echo -e "${RED}串行端口 /dev/$SERIAL_PORT 不存在${NC}"
        return
    fi

    # 创建串行getty服务
    cat << EOF | sudo tee /etc/systemd/system/serial-getty@${SERIAL_PORT}.service
[Unit]
Description=Serial Getty on %I
BindTo=dev-%i.device
After=dev-%i.device systemd-user-sessions.service

[Service]
ExecStart=-/sbin/agetty -L $BAUD_RATE %I \$TERM
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
KillMode=process

[Install]
WantedBy=multi-user.target
EOF

    # 启用服务
    sudo systemctl daemon-reload
    sudo systemctl enable serial-getty@${SERIAL_PORT}.service
    sudo systemctl start serial-getty@${SERIAL_PORT}.service

    echo -e "${GREEN}串行终端 $SERIAL_PORT 已配置,波特率 $BAUD_RATE${NC}"
}

# 主菜单
main_menu() {
    while true; do
        echo ""
        echo "=== Getty配置菜单 ==="
        echo "1. 配置虚拟终端数量"
        echo "2. 配置自动登录"
        echo "3. 配置串行终端"
        echo "4. 查看当前配置"
        echo "5. 重启所有getty服务"
        echo "6. 退出"
        echo ""

        read -p "请选择操作 (1-6): " choice

        case $choice in
            1)
                configure_vt_count
                ;;
            2)
                configure_autologin
                ;;
            3)
                configure_serial
                ;;
            4)
                echo "=== 当前getty配置 ==="
                echo "虚拟终端:"
                systemctl list-units --type=service | grep getty@tty
                echo ""
                echo "串行终端:"
                systemctl list-units --type=service | grep serial-getty
                echo ""
                echo "logind配置:"
                grep -E "^(NAutoVTs|ReserveVT)" /etc/systemd/logind.conf 2>/dev/null || echo "使用默认配置"
                ;;
            5)
                echo "重启所有getty服务..."
                sudo systemctl restart getty@tty*.service
                sudo systemctl restart serial-getty@*.service 2>/dev/null
                echo -e "${GREEN}所有getty服务已重启${NC}"
                ;;
            6)
                echo "退出配置脚本"
                exit 0
                ;;
            *)
                echo -e "${RED}无效的选择${NC}"
                ;;
        esac
    done
}

# 运行主菜单
main_menu

示例6:故障排查和安全配置

getty故障排查和安全增强:

# 1. 检查getty是否运行
ps aux | grep getty
# 应该看到agetty或getty进程

# 2. 检查tty设备权限
ls -la /dev/tty*
# 确保用户有访问权限

# 3. 查看系统日志
sudo journalctl -u getty@tty1.service
sudo journalctl -u getty@tty1.service -f  # 实时查看
sudo dmesg | grep tty

# 4. 手动测试getty
sudo pkill -9 -t tty1
sudo agetty tty1 linux
# 然后切换到tty1查看效果

# 5. 检查登录问题
# 查看/etc/login.defs配置
# 检查PAM配置
cat /etc/pam.d/login
cat /etc/pam.d/system-auth

# 6. 安全增强:限制root登录
# 编辑/etc/securetty
sudo nano /etc/securetty
# 注释掉允许root登录的tty
# 例如,只允许tty1
# tty1
# 其他行注释掉

# 7. 安全增强:禁用特定tty
sudo systemctl mask getty@tty6.service
# 或删除/etc/systemd/system/getty.target.wants/中的链接

# 8. 安全增强:设置登录超时
# 修改agetty参数
sudo nano /etc/systemd/system/getty@tty1.service.d/timeout.conf
[Service]
ExecStart=
ExecStart=-/sbin/agetty -t 60 --noclear %I $TERM  # 60秒超时

# 9. 安全增强:限制登录尝试次数
# 配置PAM
sudo nano /etc/pam.d/login
# 添加或修改:
# auth required pam_tally2.so deny=3 unlock_time=300
# 3次失败后锁定5分钟

# 10. 检查登录记录
last
lastb  # 失败的登录尝试
who
w

# 11. 查看utmp/wtmp记录
# utmp: 当前登录用户
# wtmp: 历史登录记录
# 查看二进制文件
sudo utmpdump /var/run/utmp
sudo utmpdump /var/log/wtmp

# 12. 重置tty
sudo stty sane < /dev/tty1
sudo reset

# 13. 检查终端类型
echo $TERM
# 应为linux, xterm, vt100等

# 14. 测试终端功能
tput lines
tput cols
# 显示终端行列数

# 15. 修复损坏的tty
# 如果tty无响应,尝试:
sudo chvt 2  # 切换到tty2
sudo chvt 1  # 切换回tty1
# 或
sudo systemctl restart getty@tty1.service

# 16. 启用串行终端安全
# 只允许特定用户通过串行登录
# 在PAM配置中添加串行终端检查
sudo nano /etc/pam.d/login
# 添加:
# auth [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die] pam_securetty.so
# 然后配置/etc/securetty包含串行终端

系统集成

systemd集成

现代Linux系统(systemd)中的getty配置:

  • 服务文件:/usr/lib/systemd/system/getty@.service
  • 实例配置:/etc/systemd/system/getty@tty1.service.d/
  • 主配置文件:/etc/systemd/logind.conf
  • 控制命令:systemctl, loginctl
SysV init集成

传统SysV init系统中的getty配置:

  • 主配置文件:/etc/inittab
  • 控制命令:init, telinit
  • 运行级别:/etc/rc.d/rc*.d/
  • 启动脚本:/etc/init.d/

/etc/inittab配置示例(SysV init):

# 传统inittab配置
# 格式:id:runlevels:action:process

# 虚拟控制台
1:2345:respawn:/sbin/getty 38400 tty1
2:2345:respawn:/sbin/getty 38400 tty2
3:2345:respawn:/sbin/getty 38400 tty3
4:2345:respawn:/sbin/getty 38400 tty4
5:2345:respawn:/sbin/getty 38400 tty5
6:2345:respawn:/sbin/getty 38400 tty6

# 串行终端
S0:2345:respawn:/sbin/getty -L ttyS0 115200 vt100
S1:2345:respawn:/sbin/getty -L ttyS1 9600 vt100

# 自动登录
A1:2345:respawn:/sbin/getty -n -l /bin/autologin 38400 tty1

# 特殊配置
# 单用户模式
~:S:wait:/sbin/sulogin

# 重启init
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

# 应用配置
sudo init q
# 或
sudo telinit q

常见问题

systemd系统:

# 编辑/etc/systemd/logind.conf
sudo nano /etc/systemd/logind.conf
# 修改:
NAutoVTs=8
ReserveVT=8

# 重启服务
sudo systemctl restart systemd-logind

# 立即生效(无需重启)
sudo systemctl start getty@tty7.service
sudo systemctl start getty@tty8.service
sudo systemctl enable getty@tty7.service
sudo systemctl enable getty@tty8.service

SysV init系统:

# 编辑/etc/inittab
sudo nano /etc/inittab
# 添加:
7:2345:respawn:/sbin/getty 38400 tty7
8:2345:respawn:/sbin/getty 38400 tty8

# 重新读取配置
sudo init q
# 或
sudo telinit q

注意:Linux内核通常支持最多63个虚拟控制台,但一般配置6-12个。

排查步骤:

  1. 检查getty进程:
    ps aux | grep tty1
    # 如果没有agetty进程,重启服务
    sudo systemctl restart getty@tty1.service
  2. 检查终端设备:
    ls -la /dev/tty1
    # 应该显示 crw--w----
    # 如果没有,创建设备文件
    sudo mknod /dev/tty1 c 4 1
    sudo chmod 620 /dev/tty1
    sudo chown root:tty /dev/tty1
  3. 切换虚拟终端:
    # 从其他tty切换
    sudo chvt 2
    sudo chvt 1
    # 或使用快捷键 Ctrl+Alt+F1, Ctrl+Alt+F2
  4. 重置终端设置:
    sudo stty sane < /dev/tty1
    sudo reset
    # 或发送重置序列
    echo -e "\033c" > /dev/tty1
  5. 检查系统日志:
    sudo journalctl -u getty@tty1.service
    sudo dmesg | grep tty
  6. 强制重启getty:
    sudo pkill -9 -t tty1
    sudo systemctl restart getty@tty1.service

方法1:通过/etc/securetty限制root登录

# 编辑/etc/securetty
sudo nano /etc/securetty
# 只允许特定tty
tty1
tty2
# 注释掉其他行
# 不允许root通过串行登录
# ttyS0
# ttyS1

方法2:通过PAM限制用户

# 编辑/etc/pam.d/login
sudo nano /etc/pam.d/login
# 添加:
auth required pam_listfile.so onerr=fail item=user sense=deny file=/etc/login.deny
# 然后创建拒绝列表
sudo nano /etc/login.deny
# 添加要拒绝的用户名,每行一个
baduser1
baduser2

方法3:通过shell限制

# 修改用户的shell为/sbin/nologin
sudo usermod -s /sbin/nologin username
# 或
sudo chsh -s /sbin/nologin username

# 创建自定义nologin消息
sudo nano /etc/nologin.txt
# 添加拒绝登录消息
# 然后设置用户shell
sudo usermod -s /sbin/nologin username

方法4:通过/etc/security/access.conf

# 编辑/etc/security/access.conf
sudo nano /etc/security/access.conf
# 添加:
-:baduser1:ALL
-:baduser2:tty1 tty2
# 格式:权限:用户:来源
# - 表示拒绝,+ 表示允许

特性 agetty mingetty
功能完整性 功能完整,支持丰富选项 最小化实现,功能有限
终端支持 虚拟终端和串行终端 仅虚拟终端
配置选项 丰富的命令行选项 很少的选项
发行版默认 多数现代发行版 某些最小化发行版
资源占用 较高 极低
自动登录 支持 支持(Red Hat系)
issue文件 支持 不支持

选择建议:

  • agetty:通用服务器和桌面系统,需要完整功能
  • mingetty:嵌入式系统、容器、资源有限环境