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'


在瘦了
38 声望5 粉丝

睿智哦