bash shell作业管理


bash shell的作业管理(job control)

回到顶部
所有在shell下执行命令而产生的进程都是shell的子进程,而shell呈现给用户的就只是一个命令行。 一个命令进程在执行的过程中可能会一直占用命令行,这期间用户是没法进行其他操作的, 直到命令执行完毕进程退出才会返回到命令行中,这时候用户才可以输入下一条想要执行的命令。
最常见的是用wget命令从互联网下载一个比较大的文件,可能一个文件下载需要半个小时,但是我想在文件下载的过程中,还能同时开展编辑一个html文件的工作。 但是wget进程一直占着命令行,该怎么办呢?
再比如用cp拷贝一个几十G大小的超大文件时,cp进程会一直占用着shell命令行,这样用户就没法进行其他的工作了,只能等到cp进程执行完毕退出。 才能接着执行下一项工作。那有没有办法可以在下载或者拷贝文件的同时,还可以进行其他的工作呢?
shell的作业管理就是来解决这样的问题的。
上面更合理的做法是将wget进程或者cp进程丢到bash后台执行。只需要在命令的后面加上一个&符号即可将命令进程放到后台执行。 例如拷贝一个超大文件时候可以这样执行命令:
            [root@initroot ~]# cp file1 file2 &
            
这样cp进程就被放到shell后台中运行了,而不会占用shell的命令行了,这样我们就可以接着执行其他命令了。 当拷贝结束的时候,shell会提示用户cp命令执行结束。有了shell的作业管理机制,就方便多了。
作业管理机制是bash shell提供的功能,可以让用户在单一命令行下同时执行多个作业。 举例来说,在登入bash后, 想要一边复制文件、一边进行搜索文件、一边进行程序编译,还可以同时用vim编辑文本文件等!
很多同学肯定会有疑惑,不是可以使用ctrl+alt+[F1-F7]组合键切换不同的虚拟终端吗? 这个终端被占用了,那就再切换一个虚拟终端不就可以了吗? 干嘛还要这么麻烦的搞个作业管理呢?
虚拟终端也就六七个,总有用完的时候啊! 而且可以通过/etc/security/limits.conf文件设置登录用户同时可以登入的虚拟终端数。 在这种情况下,某些登录用户可能只能有一个虚拟终端!再说来回切换虚拟终端不觉得费劲吗? 而且上面我们刚刚说过了,虚拟终端最大的用处是当系统死机没有反应的时候,可以通过切换终端,找到出错的进程然后杀掉。 在图形界面模式下,可以通过terminal同时打开多个bash,只要内存允许,想打开几个就打开几个。 哪里还需要用到这个作业管理啊?简直就是多此一举啊!无聊啊,愤怒啊,不想学啊!
哈哈,终于还是暴露了本性,各种理由就是不想学啊!
其实bash的作业管理机制在历史中确实有过非常多的争议,但是作业管理机制最终还是得到了保留并最终完善, 至少说明这是bash的一项非常重要的功能,在实际的linux运维工作中,并不总是在图形界面模式下, 总会有必须要用到纯命令行模式的时候,所以bash的作业管理机制还是必须要掌握的!就不要心存侥幸了! 其实作业管理一点都不难的!我们现在就把它拿下!

什么是作业管理?

回到顶部
常用的bash作业管理命令工具有:
&:将作业放到bash后台运行;
ctrl+z:将在bash前台运行的作业放到bash后台暂停;
jobs:列出当前bash后台所有作业的状态信息;
fg:将在后台暂停的作业放到bash前台继续运行;
bg:将在bash前台运行的作业放到bash后台运行;
通过whereis或者type命令我们可以发现作业管理命令都是shell的内置命令, 所以作业管理机制其实是bash的内置功能,属于bash层面的概念。而进程是linux内核层面的概念,是linux内核管理资源的基本单位。
不是所有的linux进程都可以被bash的作业管理机制所管理,例如很多的系统守护进程(deamon)都不会受控与bash作业管理机制, 只有通过bash命令行启动的进程才可以被作为bash的作业。
通过bash作业管理命令管理的bash子进程就被称作是该bash的作业,例如上面的&就是一个作业管理命令, 也就是说bash的作业就是bash的子进程,但是bash的子进程在没有被作业管理命令管理的时候,一般不直接称呼为bash作业。 如果你硬要说是bash作业也没有什么问题,毕竟只要是在bash下执行的命令都可以被作业管理机制所管理。 只要bash的子进程经过了作业管理命令处理了,就可以称这个bash的子进程为该bash的作业。
作业这个概念也仅限于作业管理机制,如果bash没有作业管理机制,也就不存在作业的概念了,而进程依然是进程。
但是要注意一个bash作业可能包含多个shell子进程,例如通过管道连接起来的多个命令会组成一个作业,但是这个作业会有多个子进程产生。
另外bash的作业管理是只针对当前bash进程的,不能在一个bash进程环境中管理其他bash进程的作业!即使是root用户也不能。
那么什么是bash的前台和后台呢?
简单点说就是bash shell展现给我们的带有命令提示符的命令行界面就是bash前台, bash前台同时只能运行一个作业,一个作业大部分时候就只有一个进程,但是也可能有多个进程,例如多个命令通过管道连接。 也就是说bash前台同时只能运行一个前台作业,在前台运行的前台作业进程会一直霸占着命令行终端,直到前台作业进程退出。 前台作业无法在前台暂停,只能放到后台暂停。可以使用ctrl+c强制终止前台作业进程。
而bash后台可以让多个bash子进程同时暂停或者运行,在后台运行的作业称为后台作业,后台作业可以暂停,也可以运行,但是无法使用ctrl+c组合键强制终止, 如果要强制终止某个后台作业,需要先将后台作业移到前台,变成前台作业后才可以用ctrl+c组合键强制终止。 后台作业无法等待接收terminal/shell的输入(input),不能与用户进行交互。 所以如果将需要用户输入的进程放入后台后,是不能运行的,只能暂停!例如vim文本编辑器进程。 但是如果后台作业有输出信息,也会输出到前端屏幕,这样很容易造成前端屏幕的混乱,所以有输出信息的进程在放入后台后也需要暂停或者将输出重定向到非屏幕文件。
总之,要进行bash的job control,必须要注意到的限制是:
这些工作所触发的进程必须来自于同一个bash shell进程的子进程,只管理自己的bash;
前台:可以控制与下达命令的这个环境称为前台(foreground);
后台:可以自行运作的工作,无法使用ctrl+c强制终止,可使用bg/fg管理工作;
后台中执行的进程不能等待 terminal/shell 的输入(input)。
注意这里讨论的前台作业和后台作业的概念是针对bash环境的。而在linux系统中也存在前台进程组和后台进程组的概念,前台进程组和后台进程组是针对整个linux系统的概念。 linux的后台进程组是和linux终端完全脱离关系的一组相关进程,多数系统守护进程都是后台进程组。 而bash的后台作业还没有完全脱离终端,虽然不能获得stdin输入,但是还是可以拥有stdout和stderr输出的。
前台进程组是拥有控制终端的一组相关进程。多个进程组组成一个会话。 关于这方面的概念,我们后面还会继续讨论。只需要注意作业是bash自己内部的概念,而进程组和会话是linux系统层面的概念。这些概念之间可能会产生重叠。
讲了那么多理论,其实作业管理的命令就是上面说的那几条,实际比理论要简单多了。下面我们就来实际实践一下bash的作业管理机制。 通过实践来体会上面的理论概念!

initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读