如何获取当前的终端名称?
ps
我的意思是TTY 列中显示的名称,例如:
root@dor-desktop:/home/dor/Documents/LAMP_setup/webs_install/do/install# ps aux | egrep 'mysql|(^USER)'
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
dor 2238 0.2 1.9 448052 79796 ? S 17:27 0:17 gedit /home/dor/Documents/LAMP_setup/webs_install/do/install/mysql.install /home/dor/Documents/LAMP_setup/webs_install/do/install/mysql.setup
root 4975 0.1 0.5 324984 22876 ? S 18:12 0:04 gedit /usr/local/mysql/bin/mysqld_safe
root 8160 0.0 0.0 4108 664 pts/2 S 19:08 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --skip-networking --skip-grant-tables --user=mysql --basedir=/usr/local/mysql --ledir=/usr/local/mysql/libexec
mysql 8279 0.0 0.4 146552 19032 pts/2 Sl 19:08 0:00 /usr/local/mysql/libexec/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/var --user=mysql --skip-networking --skip-grant-tables --log-error=/usr/local/mysql/var/dor-desktop.err --pid-file=/usr/local/mysql/var/dor-desktop.pid --socket=/usr/local/mysql/mysql.sock --port=3306
root 8342 0.0 0.0 7632 1024 pts/2 R+ 19:14 0:00 egrep --color=auto mysql|(^USER)
在上面的示例中,我需要获取pts/2
可能是执行这些命令的当前终端的名称。
答案1
tty
现在我必须输入 30 个字符,其中 3 个字符就足够了...:-)
答案2
回复:“你可以简单地解释一下这个命令是什么,它的作用是什么,以及你还可以用它做什么,哇哦,这将是一个更好的答案。-鲍比”
当前终端(或控制台,我们老人们有时也这么称呼它)的 Unix 名称是: /dev/tty ,可以用来从命令提示符轻松创建一个新的多行文件: cp /dev /tty README.md (点击然后将光标放在一个新的空白行上,您可以在其中输入文本,再次按回车键,输入第二行,等等。输入完行后,执行 control-d ,这会导致 cp 命令退出您将使用单个命令创建一个多行文件)。
答案3
回复:“你可以简单地解释一下这个命令是什么,它的作用是什么,以及你还可以用它做什么,哇哦,这将是一个更好的答案。-鲍比”
或者我们真的可以发疯,并说“去查看源代码以获取更多信息”。所以我做了。
真正获得名字tty.c
, 辅助功能ttyname
被召唤STDIN_FILENO
。这两个都在unistd.h
(为了证明,run )中定义grep "STDIN_FILENO\|ttyname" /usr/include/unistd.h
,它被拉入tty.c
通过#include "system.h"
(去这里查看
system.h
)。
现在ttyname
是定义在的外部依赖项glib_c/sysdeps/posix/ttyname.c
。它依次使用fstats
文件描述符STDIN_FILENO
( 0
),并使用该函数gettyname
实际检索指向 tty 名称的指针。 fstat
最终导致INLINE_SYSCALL
在fxstat.c
,最终调用internal_syscall2
,在这一点上我不走运。我真的不知道那是做什么的。
但是,我相信它调用stat
了fd 0
.它完成了这一切,并确保不要停在“stdin”或类似的东西上。无论哪种方式,您都可以通过查看来实现相同的行为
stat /dev/stdin # -> /proc/self/fd/0
stat /proc/self/fd/0 # -> /dev/pts/<some number>
然后/dev/pts/<some number>
是你的tty
.
更新
我试图弄清楚这一切的真相,但我不会像上面那样详细。到目前为止,我已经推断出syscall
间接寻址最终到达一个名为 的函数,然后调用立即调用的vfs_fstat
函数。这使用了一个宏,该宏返回此处定义的结果:fdget_raw
__fget_light
current
get_current
static __always_inline struct task_struct *get_current(void)
{
return this_cpu_read_stable(current_task);
}
无论如何,task_struct
有一个files
类型为 的条目,我猜它保留了与当前任务相关files_struct
的列表。files
这是一个数组,并且fd
是数组的索引。为了总结这一切,我们只需要找出fd 0
引用这个数组的真正含义(即,当创建一个任务时,实际放在那里的是什么)。然后,我们只需要在源代码中查看是否/proc/self
准确地反映了该数组,然后我们就可以确定我们认为发生的事情确实发生了......
答案4
还有使用@P
操作符的 Shell 参数扩展。可以按照类似$PS1
约定获取终端设备:
$myvar='\l'
echo ${myvar@P}
这将扩展\l
到当前终端设备的基本名称。
参考资料: man bash