理解shell
bash shell
bash shell程序可使用命令行参数修改shell启动方式
- -c string 从string中读取命令并进行处理
- -i 启动一个能够接收用户输入的交互shell
- -l 以登录shell的形式启动
- -r 启动一个受限shell,用户会被限制在默认目录中
- -s 从标准输入中读取命令
进程列表
pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls
#进程列表 会创建子shell去运行
(pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls)
#命令分组
{pwd ; ls ; cd /etc ; pwd ; cd ; pwd ; ls}
括号的加入使命令列表变成了进程列表,生成了一个子shell来执行对应的命令。
进程列表是一种命令分组( command grouping)。另一种命令分组是将命令放入花括号中,并在命令列表尾部加上分号( ;)。语法为{ command; }。使用花括号进行命令分组并不会像进程列表那样创建出子shell。
区分是否子shell执行
#打印子shell的层次
echo $BASH_SUBSHELL
后台模式
将命令置入后台模式,可以在命令末尾加上字符&
sleep 3000&
[1] 2396
#第一条信息是显示在方括号中的后台作业( background job)号( 1)。
#第二条是后台作业的进程ID( 2396)
jobs命令可以显示出当前运行在后台模式中的所有用户的进程(作业)。
jobs
[1]+ Running sleep 3000 &
#-l选项还能够显示出命令的PID
jobs -l
[1]+ 2396 Running sleep 3000 &
一旦后台作业完成,就会显示出结束状态。
[1]+ Done sleep 3000 &
协程
协程可以同时做两件事。它在后台生成一个子shell,并在这个子shell中执行命令。
coproc sleep 10
#后台作业号( 1)以及进程ID( 2544)。
[1] 2544
除了会创建子shell之外,协程基本上就是将命令置入后台模式。
jobs
[1]+ Running coproc COPROC sleep 10 &
coproc My_Job { sleep 10; }
[1] 2570
jobs
[1]+ Running coproc My_Job { sleep 10; } &
通过使用扩展语法,协程的名字被设置成My_Job。这里要注意的是,扩展语法写起来有点麻烦。必须确保在第一个花括号( {)和命令名之间有一个空格。还必须保证命令以分号( ;)结尾。另外,分号和闭花括号( })之间也得有一个空格。
外部命令
外部命令,有时候也被称为文件系统命令,是存在于bash shell之外的程序。它们并不是shell程序的一部分。外部命令程序通常位于/bin、 /usr/bin、 /sbin或/usr/sbin中。
可以使用which和type命令找到它
当外部命令执行时,会创建出一个子进程。这种操作被称为衍生( forking)。
ps -f
UID PID PPID C STIME TTY TIME CMD
christi+ 2743 2742 0 17:09 pts/9 00:00:00 -bash
christi+ 2801 2743 0 17:16 pts/9 00:00:00 ps -f
#外部命令ps很方便显示出它的父进程以及自己所对应的衍生子进程。
[外链图片转存中…(img-efnzGdbo-1659778521735)]
当进程必须执行衍生操作时,它需要花费时间和精力来设置新子进程的环境。所以说,外部命令多少还是有代价的。
bash shell外部命令
-
bzip2 采用Burrows-Wheeler块排序文本压缩算法和霍夫曼编码进行压缩
-
cat 列出指定文件的内容
-
chage 修改指定系统用户账户的密码过期日期
-
chfn 修改指定用户账户的备注信息
-
chgrp 修改指定文件或目录的默认属组
-
chmod 为指定文件或目录修改系统安全权限
-
chown 修改指定文件或目录的默认属主
-
chpasswd 读取一个包含登录名/密码的文件并更新密码
-
chsh 修改指定用户账户的默认shell
-
clear 从终端仿真器或虚拟控制台终端删除文本
-
compress 最初的Unix文件压缩工具
-
coproc 在后台模式中生成子shell,并执行指定的命令
-
cp 将指定文件复制到另一个位置
-
crontab 初始化用户的crontable文件对应的编辑器(如果允许的话)
-
cut 删除文件行中指定的位置
-
date 以各种格式显示日期
-
df 显示所有挂载设备的当前磁盘空间使用情况
-
du 显示指定文件路径的磁盘使用情况
-
emacs 调用emacs文本编辑器
-
file 查看指定文件的文件类型
-
find 对文件进行递归查找
-
free 查看系统上可用的和已用的内存
-
gawk 使用编程语言命令的流编辑器
-
grep 在文件中查找指定的文本字符串
-
gedit 调用GNOME桌面编辑器
-
getopt 解析命令选项(包括长格式选项)
-
groups 显示指定用户的组成员关系
-
groupadd 创建新的系统组
-
groupmod 修改已有的系统组
-
gzip 采用Lempel-Ziv编码的GNU项目压缩工具
-
head 显示指定文件内容的开头部分
-
help 显示bash内建命令的帮助页面
-
killall 根据进程名向运行中的进程发送一个系统信号
-
kwrite 调用KWrite文本编辑器
-
less 查看文件内容的高级方法
-
link 用别名创建一个指向文件的链接
-
ln 创建针对指定文件的符号链接或硬链接
-
ls 列出目录内容
-
makewhatis 创建能够使用手册页关键字进行搜索的whatis数据库
-
man 显示指定命令或话题的手册页
-
mkdir 在当前目录下创建指定目录
-
more 列出指定文件的内容,在每屏数据后暂停下来
-
mount 显示虚拟文件系统上挂载的磁盘设备或将磁盘设备挂载到虚拟文件系统上
-
mv 重命名文件
-
nano 调用nano文本编辑器
-
nice 在系统上使用不同优先级来运行命令
-
passwd 修改某个系统用户账户的密码
-
ps 显示系统上运行中进程的信息
-
pwd 显示当前目录
-
renice 修改系统上运行中应用的优先级
-
rm 删除指定文件
-
rmdir 删除指定目录
-
sed 使用编辑器命令的文本流行编辑器
-
sleep 在指定的一段时间内暂停bash shell操作
-
sort 基于指定的顺序组织数据文件中的数据
-
stat 显示指定文件的文件统计数据
-
sudo 以root用户账户身份运行应用
-
tail 显示指定文件内容的末尾部分
-
tar 将数据和目录归档到单个文件中
-
top 显示活动进程以及其他重要的系统统计数据
-
touch 新建一个空文件,或更新一个已有文件的时间戳
-
umount 从虚拟文件系统上删除一个已挂载的磁盘设备
-
uptime 显示系统已经运行了多久
-
useradd 新建一个系统用户账户
-
userdel 删除已有系统用户账户
-
usermod 修改已有系统用户账户
-
vi 调用vim文本编辑器
-
vmstat 生成一个详尽的系统内存和CPU使用情况报告
-
whereis 显示指定命令的相关文件,包括二进制文件、源代码文件以及手册页
-
which 查找可执行文件的位置
-
who 显示当前系统中的登录用户
-
whoami 显示当前用户的用户名
-
xargs 从STDIN中获取数据项,构建并执行命令
-
zip Windows下PKZIP程序的Unix版本
内建命令
内建命令和外部命令的区别在于前者不需要使用子进程来执行。它们已经和shell编译成了一体,作为shell工具的组成部分存在。不需要借助外部程序文件来运行。
cd和exit命令都内建于bash shell。可以利用type命令来了解某个命令是否是内建的。
type cd
cd is a shell builtin
type exit
exit is a shell builtin
因为既不需要通过衍生出子进程来执行,也不需要打开程序文件,内建命令的执行速度要更快,效率也更高。
要查看命令的不同实现,使用type命令的-a选项。
type -a echo
echo is a shell builtin
echo is /bin/echo
对于有多种实现的命令,如果想要使用其外部命令实现,直接指明对应的文件就可以了。例如,要使用外部命令pwd,可以输入/bin/pwd。
bash内建命令
-
: 扩展参数列表,执行重定向操作
-
. 读取并执行指定文件中的命令(在当前shell环境中)
-
alias 为指定命令定义一个别名
-
bg 将作业以后台模式运行
-
bind 将键盘序列绑定到一个readline函数或宏
-
break 退出for、 while、 select或until循环
-
builtin 执行指定的shell内建命令
-
caller 返回活动子函数调用的上下文
-
cd 将当前目录切换为指定的目录
-
command 执行指定的命令,无需进行通常的shell查找
-
compgen 为指定单词生成可能的补全匹配
-
complete 显示指定的单词是如何补全的
-
compopt 修改指定单词的补全选项
-
continue 继续执行for、 while、 select或until循环的下一次迭代
-
declare 声明一个变量或变量类型。
-
dirs 显示当前存储目录的列表
-
disown 从进程作业表中删除指定的作业
-
echo 将指定字符串输出到STDOUT
-
enable 启用或禁用指定的内建shell命令
-
eval 将指定的参数拼接成一个命令,然后执行该命令
-
exec 用指定命令替换shell进程
-
exit 强制shell以指定的退出状态码退出
-
export 设置子shell进程可用的变量
-
fc 从历史记录中选择命令列表
-
fg 将作业以前台模式运行
-
getopts 分析指定的位置参数
-
hash 查找并记住指定命令的全路径名
-
help 显示帮助文件
-
history 显示命令历史记录
-
jobs 列出活动作业
-
kill 向指定的进程ID( PID)发送一个系统信号
-
let 计算一个数学表达式中的每个参数
-
local 在函数中创建一个作用域受限的变量
-
logout 退出登录shell
-
mapfile 从STDIN读取数据行,并将其加入索引数组
-
popd 从目录栈中删除记录
-
printf 使用格式化字符串显示文本
-
pushd 向目录栈添加一个目录
-
pwd 显示当前工作目录的路径名
-
read 从STDIN读取一行数据并将其赋给一个变量
-
readarray 从STDIN读取数据行并将其放入索引数组
-
readonly 从STDIN读取一行数据并将其赋给一个不可修改的变量
-
return 强制函数以某个值退出,这个值可以被调用脚本提取
-
set 设置并显示环境变量的值和shell属性
-
shift 将位置参数依次向下降一个位置
-
shopt 打开/关闭控制shell可选行为的变量值
-
source 读取并执行指定文件中的命令(在当前shell环境中)
-
suspend 暂停shell的执行,直到收到一个SIGCONT信号
-
test 基于指定条件返回退出状态码0或1
-
times 显示累计的用户和系统时间
-
trap 如果收到了指定的系统信号,执行指定的命令
-
type 显示指定的单词如果作为命令将会如何被解释
-
typeset 声明一个变量或变量类型。
-
ulimit 为系统用户设置指定的资源的上限
-
umask 为新建的文件和目录设置默认权限
-
unalias 删除指定的别名
-
unset 删除指定的环境变量或shell属性
-
wait 等待指定的进程完成,并返回退出状态码
相比外部命令,内建命令提供了更高的性能,但shell中包含的内建命令越多,消耗的内存就会越大,而有些命令几乎永远也不会用到。
history
设置保存在bash历史记录中的命令数 修改名为HISTSIZE的环境变量
你可以唤回并重用历史列表中最近的命令 输入!! 然后按回车键就能够唤出刚刚用过的那条命令来使用
当输入!!时, bash首先会显示出从shell的历史记录中唤回的命令。然后执行该命令。命令历史记录被保存在隐藏文件.bash_history中,它位于用户的主目录中。这里要注意的是,bash命令的历史记录是先存放在内存中,当shell退出时才被写入到历史文件中。
要实现强制写入,需要使用history命令的-a选项。
.bash_history文件只有在打开首个终端会话时才会被读取。要想强制重新读取.bash_history文件,更新终端会话的历史记录,可以使用history -n命令。
你可以唤回历史列表中任意一条命令。只需输入惊叹号和命令在历史列表中的编号即可。
#查看历史命令
history
#强制存入历史命令
history -a
#强制读取历史命令
history -n
#执行上一条命令
!!
#执行历史命令
! + 历史编号
命令别名
查看当前可用的别名,使用alias命令以及选项-p
使用alias命令创建属于自己的别名
alias li='ls -li'
命令别名属于内部命令,一个别名仅在它所被定义的shell进程中才有效