Skip to main content

Shell

1. Shell是什么?—— CLI、Terminal、Console、Shell 的区别与联系

CLI (Command-line Interface),即命令行界面,与 GUI (Graphical User Interface),即图形用户界面相对。CLI/GUI 只是一种界面形式,对应着敲命令或点鼠标,并不代表着某类具体软件。

Terminal ,即终端,是人与计算机进行交互的接口。一台大型机可以连接很多终端机,用户在这些终端机上跟计算机进行交互,这些早期终端一般是电传打字机(TTY),电传打字机也是第一个 Unix 终端。因此,在历史上,终端是连接到计算机上的一种带输入输出功能的外设。

Console ,即控制台,是一个特殊的终端。这个终端的特殊之处在于,它是计算机自身的一个组成成分,是系统管理员的终端,拥有比普通用户的终端更大的权限。一台大型机一般只有一个控制台,却可以连接很多终端。在个人计算机上,由于你既能做一般工作,也能做管理员的工作,因此控制台与终端的界限也就消失了。

  随着个人计算机的普及和进化,大型机时代专门的终端硬件早已消失,我们只用自己的键盘、鼠标来控制计算机。但是终端的思想保留了下来,变成了操作系统中的软件 —— 终端模拟器(如 Win32 控制台)。终端模拟器可以捕获你的键盘输入,发送至命令行程序,拿到输出结果后再调用图形接口,将输出渲染至屏幕上。由于人们除了在博物馆再也见不到 TTY 这样的终端硬件了,于是就直接称终端模拟器为终端。

  特别的,由于在早期 Unix 多用户系统当中的终端都是 TTY,于是所有的终端硬件设备在 Unix/Linux 系统当中都以TTY命名,这一习惯延续至今。在现在,TTY 和终端设备已不再区分了。

Shell ,即“壳层”,是帮助用户与内核交互的一类程序。操作系统内核直接负责管理计算机硬件,处于操作系统最底层,由于其重要性是不能轻易由用户直接操作的,因此需要有 Shell 程序来作为用户操作系统的入口。Shell 是一类程序,可以有 CLI 形式的(如 sh、bash、zsh;cmd、powershell 等),也可以有 GUI 形式的(如 Windows 资源管理器 explorer.exe 等)。

  至于为什么叫“壳层”,看下面这张图或许就感觉有点形象了。

  或许现在你仍有些困惑,我们再来梳理一下。在用户用键盘和鼠标输入后,终端(Terminal)将这些输入发送给你选用的壳层(Shell),Shell 解析你的命令发送给操作系统内核去执行,并把执行结果返回给终端,终端调用图形接口将结果显示到屏幕上。

  以上基础知识我们有一些了解即可,目的是让我们跟计算机打交道时头脑更清楚。如果现在没搞清楚也不要紧,只要掌握下面的实用技能,就足以在日常工作中得心应手。

2. 常用 Shell 命令

https://www.linuxcool.com

3. Shell 脚本

Shell 脚本是一种在 Shell 中运行的脚本程序,由 Shell 作为脚本解释器,Shell 脚本的一行就相当于一个命令,也可以用分号分隔一行之中的不同命令。

3-1. Shell 脚本基础写法

注释

# hello!

变量

定义变量时,注意变量名和等号间不允许有空格。变量名也有限制,如只能包含英文字母、数字和下划线且不能以数字开头等。如:

a=1

引用变量时,注意要在变量名前加“$”符号。如:

echo $a

我们还可以查看环境变量。如显示家目录:

echo $HOME

删除变量用unset命令。如:

unset a

数组

定义数组:

array=(value0 value1 value2 value3)

读取数组元素:

echo ${array[0]}

使用 @ 符号可以获取数组中的所有元素:

echo ${array_name[@]}

分支

if else 语法格式:

if condition
then
command1
command2
...
commandN
else
command
fi

if else-if else 语法格式:

if condition1
then
command1
elif condition2
then
command2
else
commandN
fi

循环

for循环语法格式:

for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done

while循环语法格式:

while condition
do
command
done

在循环中,也可以跟C语言一样使用break和continue。此外,还有until循环,但一般不用。

3-2. 运行 Shell 脚本

直接运行shell脚本

在确保脚本具有可执行权限的前提下,可以直接执行脚本。

./test.sh # 注意不能写成test.sh,否则会去环境变量中查找

作为解释器参数运行 shell 脚本

bash test.sh # 参数是脚本路径

4. Shell 环境变量

环境变量是存储有关 shell 的工作环境的数据,以便程序或 shell 中运行的脚本能够访问到它们。系统会创建好一些环境变量,我们在安装新程序等操作时也要留意是否需要设置环境变量,否则会出现“command not found”的错误。

4-1. 查看环境变量

env # 查看全部全局变量
printenv HOME # 查看个别全局变量(HOME)
echo $HOME # 查看个别全局变量(HOME)

常用环境变量

  • HOME :当前用户的主目录
  • PATH : shell 查找命令的目录列表,由冒号分隔
  • PWD :当前工作目录

4-2. 设置环境变量

设置临时环境变量

可通过将局部变量导出到环境当中来设置环境变量,在该进程及其所创建的子进程中,该环境变量都是可见的,且子进程中的修改不会作用到父进程的环境变量。但是,这种设置是临时的,一旦退出当前shell就消失了。

variable="test"
export variable # 导出环境变量
unset variable # 删除环境变量

设置持久环境变量

如想设置持久的环境变量,就需要修改系统启动时用于加载环境变量的文件。这些文件各自有不同功能,首先,/etc 目录下的文件是系统级的,所有用户的终端都会加载;而 ~/ 也就是用户主目录下的文件是用户级的,只有该用户的终端会加载。其次,profile 文件在交互式登录 shell 当中加载,而 bashrc 文件在交互式非登录 shell 当中加载,不过由于 profile 文件当中引用了 bashrc 文件中的环境变量,因此也可认为在登录shell当中将二者都加载了。所谓登录就是指“用户登录到系统的 shell ” ,而其他的都是非登录 shell 。

因此,一般我们修改的文件有以下四个(其实绝大多数情况下修改~/.bashrc就够了):

/etc/profile # 系统级,登录shell当中加载
/etc/bashrc # 系统级,可认为都会被加载
~/.profile # 用户级,登录shell当中加载
~/.bashrc # 用户级,可认为都会被加载

修改 PATH 环境变量时,一般采用追加导出的方式,即在文件的最后一行加上:

export PATH=/usr/local/src/mongodb/bin:$PATH

使设置的环境变量立即生效

如果想不重启终端使设置的环境变量立即生效,可以用 source 命令。source 命令本意是在当前 shell 中依次执行一个文件中的每行命令,而不像 sh file name 与 ./file name 那样会建立一个子 shell 。通过执行 profile 或者 bashrc 中的全部命令,就重置了当前 shell 的全部环境变量。

source [file name]

5. SSH 简介

SSH = Secure Shell,即安全外壳协议,是为远程登录会话提供安全性的协议,一般用作远程登录到服务器。有关SSH的通信过程和加密原理在此就不做介绍了,感兴趣的同学可以查找网络资料。

通过用户名和主机名连接到服务器

ssh user@hostname # 主机名可以是IP地址或者域名

如果有密码验证,会要求输入密码。(输入密码时密码不会显示在屏幕上)

连接时指定端口

ssh -p [port] user@hostname # SSH默认连接到目标主机的22端口,可以通过-p指定其他端口

在远程主机执行一条命令

ssh user@hostname [command] # 仅执行一条命令,之后返回本地工作