Linux(基于《Linux命令行与shell脚本编程大全》的学习笔记)
5 理解shell
shell类型
系统启动什么样的shell程序取决于你个人的用户ID配置,在/etc/passwd文件中,在用户ID记录的第7个字段中列出了默认的shell程序。只要用户登录,默认的shell就开始运行
root:x:0:0:root:/root:/bin/bash
以上是passwd中的一段内容,上面的例子中就是使用了GUN bash shell 作为自己的默认shell程序,还有几种不常用的shell分别是
tcsh、dash、csh(有的可能已经消失,不同版本也不一样)
Ubuntu系统中使用dash作为默认shell
这些shell程序各自都可以被设置成用户的默认shell。由于bash shell应用较广,一般都使用bash
使用如下命令可以查看系统默认shell
ls -l /usr/bin/sh
也可以使用 /usr/bin/dash来直接启动dash shell(如果dash存在的话)
shell的父子关系
每次用户登录都会根据passwd中指定的shell类型启动一个shell程序,比如我现在使用的是bash shell那么就会启动,再输入等效的bash命令就会创建一个新的shell程序,这个程序被称为子shell,执行两次bash命令后使用ps -f查看如下:
第二列bash的ppid为第一个的pid,第三个的ppid为第二个的pid,我们再执行的ps命令其实是再第三个子bash中执行的
UID PID PPID C STIME TTY TIME CMD
root 26695 26692 0 16:42 pts/1 00:00:00 -bash
root 29198 26695 0 17:05 pts/1 00:00:00 bash
root 29226 29198 0 17:05 pts/1 00:00:00 bash
root 29246 29226 0 17:05 pts/1 00:00:00 ps -f
这样还不够直观,再使用ps中GUN长参数:ps –forest
PID TTY TIME CMD
26695 pts/1 00:00:00 bash
29198 pts/1 00:00:00 –\_ bash
29226 pts/1 00:00:00 —-\_ bash
30893 pts/1 00:00:00 ——\_ ps
这次可以看到他们之间的父子关系
可以使用exit来退出子shell
进程列表
可以在一行中通过分号’;’ 隔开需要依次执行的命令
pwd;ls;cd /etc;ll
上面这些例子所有的命令依次执行,但这并不是进程列表,命令列表若要成为进程列表,命令必须包在括号中
(pwd;ls;cd /etc;ll)
所谓的进程列表就是创建一个子shell来执行进程列表
我们通过环境变量命令 echo $BASH_SUBSHELL 来查看是否存在子shell,返回子shell的个数
当我们执行一个命令列表时
pwd;ls;cd /etc;ll;echo $BASH_SUBSHELL
可以看到在命令最后显示的数字为0,说明没有创建子shell
执行一个进程列表
(pwd;ls;cd /etc;ll;echo $BASH_SUBSHELL)
(pwd;ls;cd /etc;ll;(echo $BASH_SUBSHELL))
第一个进程列表结果为1,第二个为2,注意括号的数量
后台模式
sleep 命令
sleep [second] ,sleep 10 就是暂停十秒
sleep 1000 & 就是将sleep 命令置入后台运行 ,执行后会出现两条信息,第一个是在方括号中的后台作业job号,第二条是后台作业的进程id
在sleep 计时结束前使用 jobs命令可以看到运行在后台模式的进程jobs -l
一般情况下子shell的作用是进行繁重的处理工作,又不影响当前中端的操作,常见应用场景为解压、编译、打包等操作中
子shell 的另一种用法—协程
协程coproc可以同时做两件事,他可以在后台生成一个子shell,并在这个子shell中执行命令
coproc sleep 10
执行上面的命令,使用jobs查看子shell进程可以看到
[1]+ Running coproc COPROC sleep 10 &
上面的例子可以看出在执行子shell中后台的执行命令是coproc COPROC sleep 10 & COPROC是协程命令给进程的默认名称,我们也可以指定该名称
coproc My_Job { sleep 10; }
注意上面的命令的格式,如果使用扩展名,必须保证命令以;结尾,命令和两边的花括号有一个空格。如果使用多个协程,就需要对协程进行命名,不然名称会冲突,下面就是我尝试创建第二个协程的时候出现的警告。
coproc [24257:COPROC] still exists
也可以同时使用协程和上面的进程列表产生嵌套的子shell
coproc ( sleep 10; sleep 2; )
但是尽量不要使用嵌套,性能非常差!
外部命令
外部命令,又称作文件系统命令,是存在与bash shell之外的程序。他们并不是shell程序的一部分,外部命令程序京城位于/bin 、/sbin 中,ps就是一个外部命令,可以使用which 或者 tupe 命令找到他
which ps
/usr/bin/ps
type -a ps
ps is /usr/bin/ps
当外部命令执行时,会创建出一个子进程,这个子进程的父进程就是当前的bash shell
内建命令
内建命令是bash shell 中自带的命令,通过type 命令可以了解命令是否为内建命令
type cd;type type
cd is a shell builtin
type is a shell builtin
有些命令有多种实现,使用type -a可以查看命令的不同实现
history 命令
history 命令可以查看最近使用过的命令列表,默认保存1000条最近使用记录。如果要修改最大记录数,可以修改名为HISTSIZE的环境变量,命令历史保存在隐藏文件.bash_history中,这个文件位于用户主目录中,bash历史命令先保存在内存中,在shell退出后才被写入到历史文件中,如果需要强制写入则可以使用history -a命令,当存在多个bash客户端的时候,其他客户端的命令历史是不会通过history -a命令写入的,需要另一个命令history -n。
我们知道通过执行!!可以执行上一条命令,所以!20就是执行history记录中第20条记录
命令别名
alias 命令可以为常用命令(及参数)创建另一个名称,比如我们熟知的ls命令就是一个内置的别名命令
alias -p 可以查看当前可用的别名
alias cp=’cp -i’
alias egrep=’egrep –color=auto’
alias fgrep=’fgrep –color=auto’
alias grep=’grep –color=auto’
alias l.=’ls -d .* –color=auto’
alias ll=’ls -l –color=auto’
alias ls=’ls –color=auto’
alias mv=’mv -i’
alias rm=’rm -i’
定义一个别名的格式为 alias li=’ls -li’