关于终端、Shell、Bash以及环境变量那点事
1. 关于终端、Shell、Bash以及环境变量那点事
在实际工作中,终端(terminal)、Shell、bash等概念都模糊化了,其实也并没有引起太大的歧义,本文对上述概念做一个梳理归纳
同时对环境变量的一些概念再进一步
2. 1 终端Terminal
先举个栗子!
我通过我个人笔记本的Xshell这款终端软件,利用SSH协议远程登录了阿里云一台ECS主机
注意,Xshell名字里虽然有Shell,但它就是是一个Terminal,而不是第一个Shell

终端软件是一款具有图形界面的管理软件,是一种文本的输入和输出环境,我们输入的ls命令具体是怎么工作的?
先回答第一个问题,终端、Shell、Bash到底有什么区别?
2.1 1.1 电传打印机teletypewriter
先从计算机的历史演变开始,最早的计算机非常昂贵且提及庞大
有一段时间,输出输出是靠一种电传打印机输入以及打印在纸上的,例如teletypewriter 电传打印机,如下图

可以看出来,电传打印机设备由一个键盘和一个打印机组成,用户通过键盘输入命令,计算机将结果打印在打印机上
这里就是一个很重要的一个概念,TTY(teletypewriter )设备,显而易见通过电传打印机这种tty设备,输入输出的时间和成本代价是极其高昂的
注意,tty设备特指的是硬件,我们在Linux系统还会看到类似tty和pts等概念,后续再说
2.2 1.2 终端设备
重要分割线,此时终端设备上场
正如前述所说,最早的计算机非常昂贵且提及庞大,都会被安置在单独的房间,而用户会在其他房间通过其他类型的设备进行连接,这里的连接是指专用的电线,这些其他类型设备就是终端设备
DEC VT100就是当时著名的终端设备型号

原先TTY设备被不断取代,一个很明显的变化就是:电子显示单元取代了传统电子打印机
另外这里的硬件终端设备都是专用设备,并没有采用CPU,而是采用了逻辑门等芯片
注意这里我特指了
硬件终端设备,随着个人电脑的普及,软件终端即将步入历史舞台
2.3 1.3 终端模拟器
现代Linux的内核都保留了终端模拟器和tty的驱动
1、硬件键盘设备通过内核的键盘驱动,再通过终端模拟器向tty驱动模拟发出输入信号
2、终端模拟器同时从tty驱动接收到输出信号,再通过显示器驱动,显示在最终的物理显示器上
3、这里的终端模拟器侦听来自键盘的事件并将其发送给tty驱动,不同之处在于没有物理设备或电缆连接到 TTY 驱动程序上它负责向内核tty驱动模拟tty设备
4、终端模拟器存在内核态和用户态之分,内核也提供了终端模拟器叫做虚拟终端,而用户态提供的终端模拟器,就是桌面环境提供的各种终端软件,例如Ubuntu GNOMEE Terminal,这点很重要,可以详细看《虚拟控制台和伪终端》章节
这里中间再插播一下有关于终端和控制台的区别,在实际工作中不必区分这么明显
终端和控制台的区别在于
1、控制台严格意义来说就是物理设备,它不需要通过串口线等物理连接方式连接到计算机上的,它本身就是计算机的一部分。一个终端可以有多个,例如多个用户通过终端软件同时连接到一台计算机上
2、严格意义来说,一台计算机只有一台控制台,但可以有多个终端
可以看出来这里的终端(Terminal)是一个物理设备的概念逐步向软件模拟的概念演进的过程
在没有shell之前,输入输出设备通过终端模拟器只能和应用进程进行交互,但是无法对内核进行交互式的处理,没办法去理解命令行的意义
了解shell之前,先记住一个很重要概念,shell是由终端进行调用,是运行在终端之内的
2.4 1.4 虚拟控制台和伪终端
接下来我们重新看看最开始的栗子!
通过Xshell这款终端软件通过SSH协议远程登录阿里云一台ECS主机
此时我们在本机的Xshell终端输入tty和who命令,返回如下内容
1234 | [root@localhost ~]# tty/dev/pts/0[root@localhost ~]# whoroot pts/0 2024-04-29 16:10 (114.84.238.103) |
通过
tty命令可以知道当前具体是什么终端
who命令可以显示当前登录的用户名、终端、登录时间等信息
注意,时间2024-04-29 16:10 后面的IP地址就是我本地用于远程SSH登录电脑的公网地址
但是如果我们通过本地控制台或者类似vSphere Web控制台进去后,出现如下欢迎界面【实际是这就是一个虚拟终端tty1】

此时我们再次输入tty和who命令,返回如下内容
1234 | [root@localhost ~]# tty/dev/tty1[root@localhost ~]# whoroot tty1 2024-04-29 19:10 |
注意对比之前同样命令的返回结果的区别
1、前者``tty命令返回了/dev/pts/0后者返回了/dev/tty1`
2、前者who命令返回了pts/0,后者返回了tty1
3、后者who命令没有远程登录的IP地址信息了,说明这是一个本地的登录结果
1、tty0-6代表的就是虚拟终端,是由Linux kernel提供的虚拟控制台或者叫做虚拟终端
拿最容易理解的场景解释下:
我们都知道Linux6个用户界面,包括1个图形界面,5个字符界面 ,可以靠ctrl+alt+fn功能键进行切换
其中ctrl+alt+F2到ctrl+alt+F6代表了5个字符的虚拟终端,这些虚拟终端都是内核提供的,他们都位于内核态运行,例如下图

内核提供的虚拟终端,需要使用键盘/鼠标直接连接,或者使用类似vSphere Web控制台这种模拟的本地控制台进行操作

2、pty终端全称就是pseudoterminal即伪终端的意思,它与tty终端本质区别,在于pty终端是一个虚拟的,是运行在用户态的,tty终端运行在内核态
而我们远程连接到主机上时,当用户通过SSH等远程登录方式登录到Linux系统时,会在服务器上创建一个伪终端设备,用于与用户进行交互,才会显示root pts/0 2024-04-29 16:10 (114.84.238.103)这样的信息
在启动图形化界面的Linux桌面环境下,使用ctrl+alt+F1从字符界面切换到代表图形界面,这个图形界面下GUI终端就是是位于用户态
可以简单理解,是在GUI桌面环境下产生的伪终端概念
2.4.1 1.4.1 pty master-slave模型
伪终端有一个很重要的概念就是master-slave模型

1、当我们启动GNOME Terminal软件,进程就会打开/dev/ptmx获得一个字符描述符
2、然后在/dev/pts目录下创建序列文件
3、GNOME Terminal进程fork一个shell进程,例如Bash
4、我们使用键盘输入ls两个字符,由内核态的键盘驱动输出至GUI系统,由GUI系统输出至GNOME Terminal
5、GNOME Terminal会侦听键盘事件,然后将ls字符到获得的PTY master
6、PTY master输入字符发送到缓冲区,同时缓冲区也会发送回PTY master,交由终端模拟器通过显示驱动,显示在物理显示器上
7、Line Discilpine会进行字符检测,例如发现回车键时,就会直接将字符发送到PTY slave
8、Bash的标准输入是PTY slave
9、shell负责解析命令,当解析到ls命令时,是一个内置的命令,就会fork一个ls进程
10、ls进程执行完后输出值PTY slave
11、PTY slave输出值缓冲区
12、缓冲区再输出至pty master,由后者再输出至终端模拟器,由后者通过显示驱动显示你在物理显示器上
2.4.2 1.4.2 虚拟终端和伪终端互相通讯的试验
为了进一步验证pty master-slave模型,我们做一个虚拟终端和伪终端的通讯试验
在linux里,一切皆文件,在这个试验里/dev/pts/0就是对应通过who命令显示的第二个远程客户pts/0
我们在本地tty1终端里,输入ehco 'hello' > /dev/pts/0就可以将

实际上,如果你感兴趣的话,你完全可以通过两个伪终端进行试验,
pts/0和pts/1
3. 2 Shell
终端是一个可以调用shell的程序,它可以接受字符流的输入和输出用于人类可读取的方式显示出来
3.1 2.1 基本概念
操作系统包括内核(kernel)态和用户态,内核态和用户态的设计确保了操作系统的稳定性和安全性
内核不提供和用户的交互功能,可以使用shell这一层翻译官
shell为用户提供用户界面的软件,通常指的是命令行界面的解析器,负责用户层和内核之间的交互工作
shell的核心点就是命令行界面的解析器
在Linux环境下,可以记住两个经典的shell实现
1、Sh就是最经典的Unix shell,全称是Bourne Shell
2、Bash是shell的最常用的一种,Bash全称是Bourne-Again Shell
除了Bash以外,还有更多的其他shell,例如zsh、fish等
可以这么认为,
shell是一个统称,而bash、zsh、fish才是具体shell的具体实现
在Windows环境下,操作系统也提供了shell的功能
1、Windows 95 / 98下的command.exe
2、Windows NT内核下的cmd以及PowerShell
3、而图形界面壳层即为explorer.exe
记住之前反复提及的一个概念:shell是由终端进行调用,是运行在终端之内的

3.2 2.2 内部命令和外部命令
再次强调,shell负责命令的解析
内置命令(builtin command) 是shell解释程序内建的,有shell直接执行,不需要派生新的进程。有一些内部命令可以用来改变当前的shell环境
对于外部命令,shell会创建一个新的进程来执行命令,当命令的进程运行时,默认shell将等待直到该进程结束
常见的外部命令有:grep、more、cat、mkdir、rmdir、ls、sort、ftp、telnet、ssh、ps等
例如我们在《1.4.1 pty master-slave模型 》看到当bash检测到ls字符时,就会form一个ls进程
我们可以使用type命令去查看是否为内部或者外部命令
1234 | [root@localhost ~]# type echoecho is a shell builtin[root@localhost ~]# type lsls is aliased to `ls --color=auto' |
3.3 2.3 查看当前shell
要查看当前使用的shell,你可以使用echo $0或者echo $SHELL命令。
在终端中执行以下任一命令,可以看出当前shell是由/bin/bash这个具体程序负责用户态和内核态在命令交互的翻译工作
12 | [root@localhost ~]# echo $SHELL/bin/bash |
注意SHELL一定要是大写
查看当前用户可以使用的shell
12345 | [root@localhost ~]# cat /etc/shells/bin/sh/bin/bash/usr/bin/sh/usr/bin/bash |
或者使用chsh -l命令
123456789 | [root@localhost ~]# chsh -l/bin/sh/bin/bash/usr/bin/sh/usr/bin/bash/usr/bin/zsh/bin/zsh/usr/bin/tmux/bin/tmux |
3.4 2.3 切换下一次使用的shell
切换shell通常指的是在同一个终端会话中更换使用的shell程序
在Linux系统中,这可以通过输入不同的shell命令来完成。例如,如果你当前使用的是bash shell,你可以切换到其他shell,如zsh或者fish
注意
1、切换shell必须使用
-s参数2、下次重启shell才能使用
123 | [root@localhost ~]# chsh -s /bin/zshChanging shell for root.Shell changed. |
切换shell背后的原理其实很简单
chsh -s其实修改的就是/etc/passwd文件里和你的用户名相对应的那一行,现在来查看下
12 | [root@ethan ~]# cat /etc/passwd | grep zshroot:x:0:0:root:/root:/bin/zsh |
使用chsh加选项-s就可以修改登录的shell了!你会发现你现在执行echo $SHELL后仍然输出为/bin/bash,这是因为你需要重启你的shell才完全投入到zsh怀抱中去
4. 3 环境变量
Linux shell在执行命令过程中,有一个绕不开的概念就是Linux环境变量
而且Linux shell还存在交互式和非交互式的概念
Linux环境变量是一个存储在系统中的特殊变量,它为用户在Shell中执行命令时提供了一些有用的信息
例如,PATH 变量包含了一系列目录,Shell会在这些目录中查找可执行文件
4.1 3.1 环境变量的分类
按照生命周期来分:
1、永久的:需要用户修改相关的配置文件,变量永久生效
2、临时的:用户利用export命令,在当前终端下声明环境变量,关闭Shell终端失效
按照作用域来分:
1、系统环境变量:系统环境变量对该系统中所有用户都有效
2、用户环境变量:顾名思义,这种类型的环境变量只对特定的用户有效

4.2 3.2 交互式和非交互式shell
交互式shell包括登录和非登录两种shell
交互式登录 Shell
指需要用户名、密码登录后才能进入的 shell,例如:通过 ssh 或本地远程登录到终端,还有就是使用 --login 选项启动 Bash
交互式非登录 shell
指不需要用户名和密码即可打开的 shell,例如:直接命令 “bash” 就是打开一个新的非登录 shell,或者在 Linux Gnome 桌面环境打开一个“终端(terminal)”窗口也是一个非登录 shell
例如我们通过vim,在~/.bashrc末尾一句添加echo 打开一个bash
然后直接执行一个bash命令,打开一个子shell进程
12 | [root@localhost ~]# bash打开一个bash |
实际上我们发现~/.bashrc中就放alias别名设置
123 | alias rm='rm -i'alias cp='cp -i'alias mv='mv -i' |
交互式非登录 shell
指不与终端关联,一般是执行一个命令、一个脚本的 shell ,通常不需要人工干预,例如系统维护脚本、后台脚本
4.3 3.3 su命令是否带-的区别
使用su命令切换用户时,不会改变当前的环境变量,即仍然保持原用户的环境变量
而su -命令则会改变为切换到用户的环境变量,获得新用户的环境变量及执行权限
如图所示
su -命令会按优先级顺序执行
su命令则只会按照交互式nologin方式进行加载环境变量配置文件
4.4 3.4 修改环境变量的最佳实践
Linux 发行版更新的时候,会更新 /etc 里面的文件,比如 /etc/profile,因此建议不要直接修改这个文件
如果想修改所有用户的环境参数,建议在 /etc/profile.d目录里面新建.sh 脚本,如果想修改个人登录环境,一般是写在 ~/.bashrc 里面
提示:在享受本文内容的同时,请注意版权归属 徐州鑫坤机电设备有限公司https://www.xzxkjd.com如果您觉得有价值欢迎分享,但请务必注明出处,感谢您的理解,谢谢!
以下部分内容需要登录查看 立即登录
相关内容
- 关于终端、Shell、Bash以及环境变量那点事
- 供需裂口持续扩大:2025年铜价暴涨,产业链如何应对?
- 铜,新时代的“石油”?2025年价格狂飙背后的战略博弈
- 从能源革命到智能时代:2025铜价暴涨背后的全球新逻辑
- 铜价创历史新高!绿色转型与供需失衡背后的财富浪潮
- 2025铜价为何一飞冲天?三大核心驱动力深度解析
- 上海非急救出租服务全解析
- 深耕中考复读赛道 深圳深才教育为复读生搭建升学桥梁
- 阳光下的童年:那些被温暖照亮的纯真时光
- 群晖DSM7.0-7.21监控套件Surveillance Station 9.20-11289开心版60个许可证设置教程(无重启、无断流、无卡死、史上最完美)
- 云服务器+SD-WAN组网和域名DNS解析
- 在云主机上安装iKuai OS,实现SD-WAN组网,利用云主机80;443端口搭建企业网站。个人博客。让云主机当做你的堡垒机,实现数据本地化。
简体中文
繁體中文
English
Nederlands
Français
Русский язык
Polski
日本語
ภาษาไทย
Deutsch
Português
español
Italiano
한어
Suomalainen
Gaeilge
dansk
Tiếng Việt
Pilipino
Ελληνικά
Maori
tongan
ᐃᓄᒃᑎᑐᑦ
ଓଡିଆ
Malagasy
Norge
bosanski
नेपालीName
čeština
فارسی
हिंदी
Kiswahili
ÍslandName
ગુજરાતી
Slovenská
היברית
ಕನ್ನಡ್Name
Magyar
தாமில்
بالعربية
বাংলা
Azərbaycan
lifiava
IndonesiaName
Lietuva
Malti
català
latviešu
УкраїнськаName
Cymraeg
ກະຣຸນາ
తెలుగుQFontDatabase
Română
Kreyòl ayisyen
Svenska
հայերեն
ဗာရမ်
پښتوName
Kurdî
Türkçe
български
Malay
मराठीName
eesti keel
മലമാലം
slovenščina
اوردو
አማርኛ
ਪੰਜਾਬੀName
albanian
Hrvatski
Suid-Afrikaanse Dutch taal
ខ្មែរKCharselect unicode block name




