Bash/Shell
本文最后更新于:2024年7月24日 晚上
简介
Shell是运行在终端中的文本互动程序,是用户与Linux内核之间的接口程序,是二者沟通的桥梁[1][2]。
Shell是一个命令语言解释器(command-language
interpreter)。拥有自己内建的shell命令集。此外,Shell也能被系统中其他有效的Linux实用程序和应用程序(utilities
and application programs)所调用。
不论何时你键入一个命令,它都被Linux
shell所解释。一些命令,比如打印当前工作目录命令(pwd),是包含在Linux
bash内部的(就象DOS的内部命令)。其他命令,比如拷贝命令(cp
)和移动命令(rm
),是存在于文件系统中某个目录下的单独的程序。而对用户来说,你不知道(或者可能不关心)一个命令是建立在Shell内部还是一个单独的程序[3]。
Linux的Shell种类众多,常见的有:
- Bourne Shell(/usr/bin/sh或/bin/sh,已经被 /bin/bash 所取代)
- Bourne Again Shell(/bin/bash,就是 Linux 默认的 shell)
- C Shell(/usr/bin/csh,已经被 /bin/tcsh 所取代,整合了 C Shell ,提供更多的功能)
- K Shell(/usr/bin/ksh,Kornshell 由 AT&T Bell lab. 发展出来的,兼容于 bash)
- Z Shell(基于 ksh 发展出来的,功能更强大的 shell)
- Shell for Root(/sbin/sh)
Bash(GNU Bourne-Again Shell)是最常用的一种Shell,它是sh(Bourne
Shell)的改进版,其中Bourne就是sh的作者。Bash是当前大多数Linux发行版的默认Shell,可以说,Bash之于Shell就如同Ubuntu之于Linux[4]。
使用指令cat /etc/shells
指令来查看当前Linux系统的可用Shell。(之所以会有这样一个文件来记录系统的可用Shell,是因为系统某些服务在运行过程中,会去检查用户能够使用的
shells ,而这些shell的查询就是藉由 /etc/shells 这个文件实现)
使用指令echo $SHELL
查看当前系统所使用的Shell种类,比如我系统中使用的就是Bash。
Bash能够作为所有Linux发行版的默认Shell,离不开它的以下几个优点[10]:
- 命令记忆功能(history)
通过按下键盘的上下键就能够找到曾经输入的所有指令,相信曾为你提供不少的便利。在大多数Linux发行版中,能够记忆的指令高达100条,这些指令都被记录在家目录下的/bash_history中,不过此文件中记录的是上一次登录所使用过的指令;
- 命令与文件名称补全(Tab按键的妙用) 这也是Bash
Shell提供的非常棒的功能,为我们省去了背诵各种繁杂指令和文件名称的功夫,我们只需要记住命令开头几个字母按下Tab键就能自动补全名称或者显示所有可运行指令;
- 别名配置(alias)
很多朋友喜欢使用的ll
指令其实是ls -al
的别名,可能他们还不自知(嘻嘻,想知道你的系统中使用了那些别名?在终端中键入alias
试试看吧!
- 工作控制、前景背景控制: (job control, foreground, background)
这个我不了解,详情请查看参考文献; - 程序化脚本: (shell scripts)
将你平时管理系统常需要下达的连续命令写成一个脚本文件,
该脚本可以通过对话交互式的方式来进行主机的侦测工作!整个设计下来几乎就是一个小型的程序语言;
- 通配符: (Wildcard)
通配符可以帮助用户查询与命令下达,举例来说,想要知道/usr/bin
底下有多少以
X 为开头的文件吗?使用:ls -l /usr/bin/X*
就可以知道了。
Shell中执行命令的方式
Shell有两种执行命令的方式:
(1)交互式(Interactive):解释执行用户的命令,用户输入一条命令,Shell就解释执行一条。比如我们平时经常在terminal命令行使用cd、pwd、mv、cp、tar
等命令,都属于此种方式。
(2)批处理(Batch):用户事先写一个Shell脚本(Script)如.sh文件,其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。
在使用交互式方法执行Shell命令时,通常有一些重要的快捷键需要我们掌握,掌握它们可以让我们执行命令时事半功倍。
Shell中命令的种类
Shell中命令有三类[5],分别是:
(1)内建(built-in)命令:是Shell程序的一部分,写在bash的源码builtins
里面的,通常在Shell程序被加载驻留在系统内存中,解析内部命令不需要创建子进程,因此执行速度快于下面的外部命令,比如history、cd、exit
[6],使用help
即可列出所有内建命令,也可以使用help COMMAND
查看内建函数的详细介绍;
(2)外部命令:保存在shell之外的脚本,提供了额外的功能,是Linux实用程序的一部分,功能比较强大,不随系统一起被加载到内存中,外部命令虽然不在Shell中,但其命令的调用时由shell程序控制的,外部命令是在bash之后额外安装的,通常放在/bin,/usr/bin,/sbin,/usr/sbin
等等。比如:ls
、vi
等;
(3)别名(alias):给某个命令的简称。
需要注意的是help
命令不带任何参数的话只用于显示内建命令的帮助信息,包括一些简要说明以及一些参数的使用以及说明,如果加上--help
的参数就可以查看外部命令的帮助信息了。
如果想查看更加详细的命令介绍,可以使用man
,比help
更加详细,而且无内建命令和外部命令之分,man
好比一个电子词典,里面多是对命令的详细解释信息,help
适合在紧急是忘记用哪个参数的时候用,不太紧急的适合可以用man
[6]。
> 比man更详细的帮助手册——info。
Shell编程[7]
在第二小节Shell中执行命令的方式中提到了批处理的方式执行Shell命令,这就涉及到Shell编程了,值得一提的是,业界所说的Shell通常都是指Shell脚本(script),但读者朋友要知道,Shell和Shell
script是两个不同的概念。由于习惯的原因,简洁起见,本文出现的"shell编程"都是指Shell脚本编程,不是指开发Shell自身。
Shell脚本以.sh后缀结尾,使用vi/vim
或touch
创建test.sh文件,并使用vi/vim
编辑,敲入一些代码,第一行一般为#!/bin/bash
。
1
2#!/bin/bash
echo "This is test"
#!
是一个约定的标记,告诉系统其后路径所指定的程序即是解释此脚本文件的Shell程序。我们在第一小节简介 中提到shell又分很多种类,其中Bash(Bourne Again
Shell)是最广泛使用的一种shell。在一般情况下,人们并不区分Bourne
Shell和Bourne Again
Shell,所以,像#!/bin/sh
,它同样也可以改为#!/bin/bash
。
完成编写后,保存退出,并使用chmod 777 test.sh
使其具有可执行权限,这样,我们的第一个Shell脚本就编写完成了。使用./test.sh
就可以执行此脚本,可以看出会在terminal打印出“This
is test”字符串。
Bash常见指令
- alias: 设置bash别名;
- bg: 使一个被挂起的进程在后台继续执行;
- cd: 改变当前工作目录;
- exit: 终止shell;
- export: 使变量的值对当前shell的所有子进程都可见;
- fc: 用来编辑历史命令列表里的命令;
- fg: 使一个被挂起的进程在前台继续执行;
- help: 显示bash内部命令的帮助信息;
- kill: 终止某个进程;
- pwd: 显示当前工作目录;
- unalias: 删除已定义的别名。
Bash常见环境变量(在/etc/profile文件中配置)
这里是几个最有用的环境变量,包括变量名和简单描述:
- EDITOR, FCEDIT: bash fc 命令的缺省编辑器;
- HISTFILE: 用于贮存历史命令的文件;
- HISTSIZE: 历史命令列表的大小,表明可以存储多少条历史指令,默认是1000条;
- PWD: 当前工作目录;
- PATH:
预设可执行文件或命令的搜索路径。
env
命令显示所有的环境变量 。环境变量以:
分开。环境变量名前$
符号表示该变量本次定义之- 前的值。由于文件的搜寻是依序由 PATH 的变量内的目录来查询,所以,目录的顺序也很重要; - USER: 用户登录时使用的用户名;
- HOME:当前用户主目录;
- LANG/LANGUGE:这个很重要,表示语系,很多信息都会用到他, 举例来说,当我们在启动某些 perl 的程序语言文件时,他会主动的去分析语系数据文件, 如果发现有他无法解析的编码语系,可能会产生错误!一般来说,我们中文编码通常是 zh_TW.Big5 或者是 zh_TW.UTF-8,这两个编码偏偏不容易被解译出来,所以有的时候,可能需要修订一下语系数据;
- SHELL:是指当前用户用的是哪种Shell。
set
命令显示所有本地定义的Shell变量,包括环境变量和自定义变量,而前面提到的env
指令只会显示环境变量; - LOGNAME:指当前用户的登录名。其值为
$USER
; - HOSTNAME:所使用的主机名。供应用程序使用;
- PS1:命令行的一级提示符(格数如下,用法如右):
export PS1="[\u@\h \w]\$"
[8];\d
代表日期,格式为weekday month date,例如:Wed Dec 12;
\H
完整的主机名称。例如:hostname是debian.linux;
\h
仅取主机的第一个名字,如上例,则为debian,.linux则被省略;
\t
显示时间为24小时格式,如:HH:MM:SS;
\T
显示时间为12小时格式;
\A
显示时间为24小时格式:HH:MM;
\u
当前用户的账号名称 如:root;
\v
BASH的版本信息 如:3.2;
\w
完整的工作目录名称。家目录会以~
代替 如显示/etc/default/
;
\W
利用basename取得工作目录名称,只会列出最后一个目录。如上例则只显示default;
\#
下达的第几个命令;
\$
提示字符,如果是root时,提示符为:#
,普通用户则为:$
; - PS2:命令行的二级提示符,默认为
>
[9]; - MAIL: 存放用户电子邮件的邮箱(ASCII码文件);
- INPUTRC: 存放的是针对键盘热键的信息(ASCII码文件);
- $:代表目前这个 Shell 的线程代号,即所谓的 PID (Process ID)
- ?:代表上一个运行的命令所回传的值
在这里对PS1这个变量进行进一步的解释,PS1这个变量就是用来定义每次使用终端时前面那一行的样式的,比如在这里定义的样式为yeyisheng@ubuntu:~$
注意,如果在shell中修改该变量的值,只是临时生效的,一旦注销或重启系统就会消失。要想永久生效,必须写入环境变量配置文件
- Shell 教程 | 菜鸟教程 (runoob.com) ↩︎
- Linux(四):什么是Bash、什么是shell?_bash shell-CSDN博客 ↩︎
- Shell | Linux基础概要 (gitbooks.io) ↩︎
- 知乎 (zhihu.com) ↩︎
- Bash编程入门-1:Shell与Bash - 知乎 (zhihu.com) ↩︎
- Linux:帮助命令——help、man、info的简单介绍_linux help - man-CSDN博客 ↩︎
- shell学习教程(超详细完整)_shell教程-CSDN博客 ↩︎
- linux shell中环境变量$PS1详解-CSDN博客 ↩︎
- BASH脚本基础:环境变量PS2介绍_shell ps2是什么-CSDN博客 ↩︎
- 鸟叔的Linux私房菜:基础版 ↩︎