对此进行更多解释问题。ls、cd、rm 等命令是否是应用程序,如果是,那么终端如何知道它们在哪里?终端是否只是与程序交互的界面,仅仅是程序之间相互交互?其次,如果只是程序之间相互交互,那么 bash 是否是唯一可以在终端中运行的语言?
答案1
终端可用于执行给定 PATH 内的程序 - 您可以通过echo $PATH
在 bash 终端中运行来找到它 - 示例输出:
/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/home/wilf/.local/bin:/home/wilf/bin:/usr/games
这是在终端启动时设置的 - 当它使用 BASH shell 时(许多 Linux 系统的默认设置),它~/.bashrc
会在启动前进行检查。然后,当您运行命令时,它会在路径中搜索该命令,如果找到,则执行该命令。
使用上面的例子$PATH
,我可以将一个可执行脚本放在/home/wilf/.local/bin
(例如extension-update
来自这里),然后能够在终端运行它,而无需指定可执行文件的完整路径(例如/home/wilf/.local/bin/extension-update
,/usr/bin/firefox
等)
答案2
终端
终端是一个界面,您可以在其中输入和执行基于文本的命令。使用终端完成某些任务比使用图形应用程序和菜单要快得多。另一个好处是允许访问更多命令和脚本。
与通过软件中心导航相比,安装应用程序的常见终端任务可以在单个命令内完成。
看这个帖子了解更多信息。
答案3
执行“ps -ef”您可以看到所有进程,包括终端进程:
tthtlc 2964 1 0 08:31 ? 00:00:02 gnome-terminal
只需“ps”,您只会看到您自己的终端:
PID TTY TIME CMD
2974 pts/0 00:00:00 bash
6420 pts/0 00:00:00 ps
看到“pts/0”了吗?转到 /dev/pts:
ls -al
total 0
drwxr-xr-x 2 root root 0 Jun 14 08:31 .
drwxr-xr-x 18 root root 4420 Jun 14 08:31 ..
crw--w---- 1 tthtlc tty 136, 0 Jun 14 09:03 0
crw--w---- 1 tthtlc tty 136, 1 Jun 14 09:02 1
crw--w---- 1 tthtlc tty 136, 2 Jun 14 09:02 2
crw--w---- 1 tthtlc tty 136, 3 Jun 14 09:02 3
crw--w---- 1 root tty 136, 6 Jun 14 08:31 6
crw--w---- 1 root tty 136, 8 Jun 14 08:31 8
c--------- 1 root root 5, 2 Jun 14 08:31 ptmx
在这里你可以看到我创建了 0、1、2 ==> 3 个终端。“gnome-terminal”被实现为一个进程,它在与上面列出的相同字符设备上打开 stdin、stdout 和 stderr。首先,注意到上面“bash”的 pid 2974 了吗?转到 /proc/2974/fd 查看打开的所有文件描述符:
/proc/2974/fd>ls -al
total 0
dr-x------ 2 tthtlc tthtlc 0 Jun 14 09:30 .
dr-xr-xr-x 8 tthtlc tthtlc 0 Jun 14 09:30 ..
lr-x------ 1 tthtlc tthtlc 64 Jun 14 09:30 0 -> /dev/pts/2
l-wx------ 1 tthtlc tthtlc 64 Jun 14 09:30 1 -> /dev/pts/2
l-wx------ 1 tthtlc tthtlc 64 Jun 14 09:30 2 -> /dev/pts/2
lrwx------ 1 tthtlc tthtlc 64 Jun 14 09:55 255 -> /dev/pts/2
所以这意味着 bash 的所有输入/输出/stderr 都来自 /dev/pts 设备驱动程序。
如果您打开多个 gnome 终端,并且取决于哪个是前台进程,实际的键盘将被重定向到相应的进程。例如,如果您执行“ strace -p <pid>
”,其中<pid>
当前进程为 2974,第一次在该终端中输入字符时,您将立即看到 read() - 下面我输入多个“f”:
read(0, "f", 1) = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "f", 1) = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, "f", 1) = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "f", 1) = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, "f", 1) = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "f", 1) = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, "f", 1) = 1
这就是终端的一般工作方式:逐个字符地读取,并同时逐个字符地输出(称为“回显”)到屏幕上。多个终端可以同时运行,但只有一个终端会直接获得键盘输入,其他终端将在 read() API 处阻塞。
答案4
我认为大部分问题都已经回答了。我只想补充一点。
您可以从终端运行任何应用程序。即使非终端(Chrome / Firefox 等应用程序)也将从终端运行。
要运行任何应用程序,用户必须知道该应用程序的文件路径并使用该文件位置调用该应用程序。例如
/bin/ls
但为了用户方便,定义了 PATH。并且可以从这些路径调用应用程序而无需调用完整路径。这就是您可以运行以下命令的原因:
ls
cat a_simple_text_file.txt
firefox ## this is the same as double clicking the firefox icon in your desktop
您可以编写自己的 shell 脚本并在终端上运行它。并且您可以使用任何编程语言(C、C++、python、Java、Objective-C、PHP)编写程序,它可以在终端上运行。每种编程语言都有自己的方式来显示输出、接受输入并自行构建运行。
“只是程序之间相互作用而已。”
从技术上讲,程序之间并不交互。所有程序都请求操作系统,操作系统与所有程序交互。(操作系统是指操作系统,Ubuntu / Windows / OSX 等)
例如。您想使用 Firefox 上传文件。当您单击网站上的上传按钮时。Firefox 将向操作系统请求文件管理器应用程序。文件管理器将接受您的选择并将文件位置发送到操作系统 >> Firefox。Firefox 将通过请求操作系统使用其他应用程序来上传文件。
现在你可以说,操作系统也是一个程序。所以,程序之间确实存在交互!