一Shell 与子Shell
Linux是一种用户控制的多作业操作系统,
系统允许多个系统用户同时提交作业,而
一个系统用户可以用多个Shell登录,
每个系统用户可以用一个Shell提交多个作业。
父子Shell是相对的,他描述了两个Shell进程的fork关系(交叉)。
父Shell:在控制终端或xterm窗口给出提示符的进程。
子Shell:被父Shell创建的进程。
Linux中只有fork函数可以创建子进程。
Shell命令分为:内键(build-in)和外部命令(external)
内建命令:由Shell本身执行的命令。
外部命令:由fork创建出来的子Shell执行。
二者区别:内键命令不会创建子Shell,外部命令创建子Shell。内键命令执行要比外部命令快。
内键命令:就是包含在bash Shell 工具包中的命令,是bash Shell的核心。
保留字也是bash Shell的核心,用于构建Shell语法结构,如if,for等;保留字本身不是命令,它只是命令的一部分。
二bash Shell中的冒号
①:表示永真,相当于TRUE关键字。
执行结果:
②:冒号可以清空一个文件:
③:冒号最重要的用法是:不做任何事情,只做参数展开。
所谓变量展开:就是把变量的值替换变量名。
三圆括号结构
圆括号强制将其命令运行到子Shell中。圆括号执行结束后,会回到父Shell中
基本格式:
( Command1 Command2 ....... CommandN ) |
Bash 3之后:内部变量BASH_SUBSHELL:记录了子Shell的层次,它是从0开始计数的,并且父Shell的BASH_SUBSHELL值为0.
子Shell的特点:
①:子Shell中的变量(包括环境变量使用export声明的)对父Shell是不可见的。
②:子Shell只能继承父Shell的一些属性,但是子Shell不可能返回来改变父Shell的属性。
子Shell只能从父Shell继承的属性如下:
---当前工作目录
---环境变量
---标准输入、标准输出、标准错误输出
---所有已经打开的文件标识符
---忽略的信号。
子Shell不能从父Shell继承的属性:
---除了环境变量和.bashrc文件中定义变量之外的Shell变量
---未被忽略的信号处理。
因此子Shell能够设置独立于父Shell的子环境。
子Shell可以接受父Shell通过管道传送过来的数据:
子Shell可以用于将以计算量较大的任务分为若干个小任务:
Wait命令:是bash Shell内建的一个命令,它用于等待后台执行的作业全部完成后才会继续执行下面的命令。
四Shell的限制模式
一般情况Shell都是运行在正常模式下的
限制模式:RSH(Restricted Shell):处于限制模式下的Shell执行一个脚本或脚本片段,将会禁用一些命令或操作,主要是为了安全考虑,目的是限制脚本用户的权限,尽可能减少脚本带来的危害。
限制内容如下:
①:用cd命令更改当前工作目录的命令
②:更改重要环境变量的值,包括$PATH,$SHELL,$BASH_ENV,$ENV和$SHELLOPTS(有些版本可以读取)
③:输出重定向符号>,>>,>|,>&,<>和&>
④:调用含有一个或多个斜杠(/)的命令名称
⑤:使用内键命令exec
⑥:使用set+r等命令关闭限制模式
开启Shell限制模式:
Set -r:就是开启Shell模式。
也可以使用:#!/bin/bash -r:来开启Shell限制模式
五进程管理
当Shell不是内键命令时,Linux系统利用fork对一个子进程执行该命令,父进程处于等待状态;然后,如果该命令或脚本包含编译过的可执行文件,内核将新程序装入到内存,并覆盖子进程,执行结束后,退出子进程,父进程被重新激活,开始读取Shell提示符后的下一条命令。
Fork是Linux系统的一系统调用。系统调用用于请求内核服务,这个也是进程访问硬件的唯一个办法。
Fork是创建新进程的系统调用,它创建的子进程是父进程的副本,两个进程用于同样的环境、打开的文件、用户标识符、当前工作目录和信号等。
Linux继承了UNIX的:允许用户控制多个进程的操作系统。叫做用户控制的多任务。
作业:一个正在执行的进程,一个作业可以包含多个进程,一个用户提交的作业的完成可能依赖于启动多个进程。作业是用户层面的概念。
进程:是操作系统层面的概念。一个具有一定独立功能的程序关于某个数据集合的一次运行活动,进程在运行过程中不断的改变其运行状态。一般有三个基本状态。
就绪,运行,阻塞。(这里不赘述,他们是比较重要的概念)
进程号:Linux系统为每个进程分配一个数字来标识该进程[]后面的数字
作业号:创建该进程的Shell为此进程创建一个数字,用于表示该进程。[]中的数字
使用&符号进一个进程放到后台执行时就会显示作业号和进程号。
他们的区别:
作业号:标识的是在此Shell下运行的所有进程。
进程号:标识整个系统下运行的所有进程。
作业控制:
作业的两种运行方式:前台运行和后台运行。
前台运行:能够控制当前终端或窗口,并且接受用户输入
后台运行:不在当前激活的窗口中运行,而是在用户“看不到”的情况下运行。
内建命令:fg可以将后台运行的作用放到前台。
fg %num:可以把指定作业号的进程放到前台执行 num是该进程的作业号。
&符号:使得作业在后台运行。
Shleep :命令 让进程休息一段时间:
Shleep 10:表示让进程休息10秒钟。
指定作业方法及其意义
参数 |
意义 |
%n |
n为后台作业的作业号 |
%string |
命令以string字符串开始的后台作 |
%?string |
命令包含string字符串的后台作 |
%+或%% |
最近提交的后台作业 |
%- |
最近第二个提交的后台作业 |
Jobs命令:用于显示所有的后台作业
Jobs -l 参数:附带显示作业的进程号。
Ctrl+Z 之后 输入bg可以让阻塞的作业转入后台运行。
注意:fg/bg/jobs只能以作业号作为参数来指定作业,他们是不能使用进程号的。
Kill/disown/wait他们既可以使用作业号也是可以使用进程号的。
Disown:用于从Shell的作业表中删除作业,作业表有jobs命令所列出的作业表。它可以指定删除作业表中的作业。
Disown %-:指定删除最后提交的第二个作业。
信号:
是Linux进程间通信的一个重要而复杂的概念。是在软件层面对中断的模拟。
一个进程接收到一个信号与处理器接收到一个中断请求可以说是一致的。
信号是异步的。
信号事件的发生有两个来源:硬件来源,如按下键盘;软件来源,如最常用的发送信号的函数如kill,raise等。
信号是进程间通信的唯一一种异步通信,可以看做是异步通知。信号机制通过POSIX实时扩展后,功能更加强大,除了基本的通知功能外,还可以传递附带信息。
向进程发送信息好多通过”Ctrl”加上一些功能键实现的:
组合键 |
信号类型 |
意义 |
Ctrl+C |
INT信号,即interrup信号 |
停止当前运行的作业 |
Ctrl+Z |
TSTP信号,即terminal Stop信号 |
使当前运行的作业暂时停止(转入阻塞状态) |
Ctrl+\ |
QUIT信号 |
Ctrl+C的强化版本,当Ctal+C无法停止作业时,使用 |
Ctrl+Y |
TSTP信号,即terminal Stop信号 |
当进程从终端读取输入数据时,暂时停止该进程 |
内建命令:kill可以用于向进程发送TERM信号(即terminal),功能与INF信号类型,也用于停止进程。
Kill可以用进程号、作业号或进程的命令名向任何作业发送信号。
Kill $$:表示把自己杀死。
退出码大于128表示是系统强制结束的。
退出码:128+N:N表示该脚本所收到信号的标号。
Kill -l:可以列出kill命令可以发送的所有信号及其标号。
Trap命令:
用于捕捉信号,是Linux的内键命令。
Trap command sig1 sig2 ... sigN:表示指定接收到其中任意某个信号时执行的命令。Command完成后,脚本继承收到信号前的操作,直到脚本结束。
使用trap忽略信号的用法:
Trap “” TERM INT:表示接收到 TERM INT中的一个信号都什么也不做。
杀死顽固的进程:
Kill -9 %num: -9就是9号信号KILL。Num是作业号