tty (teletype) 命令是最简单的Unix命令之一,它的主要功能是显示当前用户正在使用的终端设备文件名。这个命令在网络管理、脚本编写和系统调试中非常有用。
tty 是"teletypewriter"(电传打字机)的缩写,源自Unix系统的早期历史。在Unix中,每个终端会话都对应一个设备文件。
tty [选项]
注意: tty 命令不接受任何参数,只接受选项。
| 选项 | 说明 |
|---|---|
-s 或 --silent 或 --quiet |
静默模式,不输出任何内容,只返回退出状态 |
--help |
显示帮助信息 |
--version |
显示版本信息 |
# 显示当前终端设备文件名
tty
# 输出示例:
# /dev/pts/0
# 或物理终端:
# /dev/tty1
# 静默模式,不显示输出,只通过退出状态码表示结果
tty -s
# 检查命令执行结果
echo $?
# 返回值说明:
# 0 - 标准输入是终端
# 1 - 标准输入不是终端
# 2 - 语法错误
# 3 - 写入错误
#!/bin/bash
# 检查脚本是否在终端中运行
if tty -s; then
echo "脚本在终端中运行:$(tty)"
else
echo "脚本不在终端中运行(可能是管道或重定向)"
fi
# 另一个示例:仅允许在终端中运行脚本
if ! tty -s; then
echo "错误:此脚本必须在终端中运行!"
exit 1
fi
echo "继续执行脚本..."
# 在SSH会话中
tty
# 输出:/dev/pts/1
# 在物理控制台
tty
# 输出:/dev/tty1
# 通过管道执行
echo "test" | tty
# 输出:not a tty
# 重定向输入时
tty < /dev/null
# 输出:not a tty
| 设备文件 | 说明 | 典型场景 |
|---|---|---|
/dev/tty[1-63] |
物理终端(虚拟控制台) | 通过 Ctrl+Alt+F1-F6 切换 |
/dev/pts/[0-9]* |
伪终端(Pseudo-Terminal Slave) | SSH连接、终端模拟器、screen/tmux会话 |
/dev/ttyS[0-9]* |
串行终端 | 串口连接、控制台重定向到串口 |
/dev/console |
系统控制台 | 系统消息、内核输出 |
/dev/tty |
当前控制终端 | 引用当前终端的特殊文件 |
/dev/ptmx |
伪终端主设备 | 创建伪终端对的master端 |
# 查看当前所有登录用户和他们的终端
who
# 输出示例:
# alice tty1 2023-10-01 09:30
# bob pts/0 2023-10-01 09:35 (:0)
# charlie pts/1 2023-10-01 09:40 (192.168.1.100)
# 使用who am i查看自己的终端
who am i
# 或使用who -m
who -m
# 查看当前shell的进程信息
ps -p $$
# 查看所有进程及其终端
ps aux | grep -E 'TTY|pts'
# 查看特定终端的进程
ps -t pts/0
# 查看谁在登录以及他们在做什么
w
# 输出示例:
# 09:45:01 up 2 days, 3:15, 3 users, load average: 0.08, 0.03, 0.05
# USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
# alice tty1 :0 09:30 2:15 0.10s 0.10s -bash
# bob pts/0 :0 09:35 1.00s 0.20s 0.01s w
# charlie pts/1 192.168.1.100 09:40 5.00s 0.15s 0.15s vim
#!/bin/bash
# 判断脚本是否在交互式终端中运行
if [[ -t 0 ]]; then
echo "交互式模式"
else
echo "非交互式模式(管道、重定向等)"
fi
#!/bin/bash
# 确保脚本只能从特定终端运行
ALLOWED_TTY="/dev/tty1"
CURRENT_TTY=$(tty)
if [[ "$CURRENT_TTY" != "$ALLOWED_TTY" ]]; then
echo "错误:只能从 $ALLOWED_TTY 运行此脚本"
exit 1
fi
# 记录脚本运行的终端
LOG_FILE="/var/log/script.log"
echo "$(date): 脚本在 $(tty) 中启动" >> "$LOG_FILE"
# 或使用logger发送到系统日志
logger -t myscript "在 $(tty) 中执行"
伪终端由一对设备组成:
应用程序通过主设备与从设备通信,从设备看起来像一个真正的终端。
# 使用script命令创建伪终端会话
script -f /dev/pts/2
# 使用socat创建伪终端
socat -d -d pty,raw,echo=0 pty,raw,echo=0
# 在Python中创建伪终端
python3 -c "
import pty
import os
master, slave = pty.openpty()
print(f'Master: {os.ttyname(master)}')
print(f'Slave: {os.ttyname(slave)}')
"
| 特殊文件 | 说明 | 示例 |
|---|---|---|
/dev/tty |
当前进程的控制终端 | echo "test" > /dev/tty |
/dev/console |
系统控制台 | echo "test" > /dev/console |
/dev/null |
空设备,丢弃所有写入 | command > /dev/null 2>&1 |
/dev/zero |
提供无限的空字符(0x00) | dd if=/dev/zero of=file bs=1M count=10 |
/dev/random |
真随机数生成器 | head -c 32 /dev/random | base64 |
/dev/urandom |
伪随机数生成器 | head -c 32 /dev/urandom | base64 |
可能原因: 标准输入不是终端设备
常见场景和解决方案:
# 场景1:通过管道执行
echo "test" | tty
# 输出:not a tty
# 原因:标准输入是管道而不是终端
# 场景2:输入重定向
tty < /dev/null
# 输出:not a tty
# 原因:标准输入是文件而不是终端
# 场景3:cron作业或init脚本
# 这些环境通常没有终端设备
# 解决方案:
# 使用tty -s检查环境,避免在非终端环境中执行终端相关操作
if tty -s; then
# 只在终端环境中执行的代码
echo "当前终端: $(tty)"
fi
可能原因: 终端设备文件权限问题
排查步骤:
# 1. 检查终端设备文件权限
ls -l $(tty)
# 输出示例:
# crw--w---- 1 alice tty 136, 0 Oct 1 09:30 /dev/pts/0
# 权限说明:
# c - 字符设备文件
# rw--w---- - 所有者可读写,组用户可写,其他用户无权限
# 2. 检查用户是否在tty组中
groups
id -nG
# 3. 检查设备文件的组所有权
stat -c "%G" $(tty)
# 4. 临时解决方法(不推荐用于生产环境)
sudo chmod a+rw $(tty)
# 5. 永久解决方法:将用户添加到tty组
sudo usermod -a -G tty $USER
# 需要重新登录生效
可能原因: 终端断开或设备文件被删除
排查步骤:
# 1. 检查终端设备文件是否存在
ls -l /dev/pts/0
# 2. 检查进程是否还在运行
ps -p $$
echo "当前PID: $$"
# 3. 尝试重新打开终端设备
exec < /dev/tty
# 4. 使用screen或tmux恢复会话
# 如果使用screen:
screen -r
# 如果使用tmux:
tmux attach
# 5. 检查网络连接(对于SSH会话)
ssh -O check user@host
# 6. 重新连接SSH会话
ssh -t user@host "bash -i"
# 使用stty查看终端设置
stty -a
# 获取终端大小
tput lines # 行数
tput cols # 列数
# 在脚本中获取终端尺寸
LINES=$(tput lines)
COLUMNS=$(tput cols)
echo "终端尺寸: ${COLUMNS}x${LINES}"
# 设置终端行数
stty rows 40
# 设置终端列数
stty cols 120
# 禁用回显(用于密码输入)
stty -echo
read -p "输入密码: " password
stty echo
echo
# 设置原始模式
stty raw
# ...执行需要原始模式的操作
stty cooked
# 查看TERM环境变量
echo $TERM
# 常见终端类型:
# xterm - X Window终端
# xterm-256color - 支持256色的X终端
# linux - Linux控制台
# vt100 - 老式视频终端
# screen - GNU screen
# tmux - tmux终端
# 测试终端功能
tput longname
echo "终端长名称: $(tput longname)"
who显示登录用户
w显示登录用户及活动
stty终端设置
ps进程状态
mesg控制终端消息
script终端会话录制
screen终端多路复用器
tmux终端多路复用器