下边的作业控制命令需要一个"作业标识符"作为参数. 请参考本章结尾部分的表格.
在后台列出所有正在运行的作业, 给出作业号. 并不象ps命令那么有用.
作业和进程的概念太容易混淆了. 特定的内建命令, 比如kill, disown, 和wait命令即可以接受作业号为参数, 也可以接受进程号为参数. 但是fg, bg和jobs命令就只能接受作业号为参数.
"1"是作业号(作业是被当前shell所维护的), 而"1384"是进程号(进程是被系统维护的). 为了kill掉作业/进程, 或者使用kill %1或者使用kill 1384. 这两个命令都行. 感谢, S.C. |
从shell的激活作业表中删除作业.
fg命令可以把一个在后台运行的作业放到前台来运行. 而bg命令将会重新启动一个挂起的作业, 并且在后台运行它. 如果使用fg或者bg命令的时候没有指定作业号, 那么默认将对当前正在运行的作业进行操作.
停止脚本的运行, 直到后台运行的所有作业都结束为止, 或者如果传递了作业号或进程号为参数的话, 那么就直到指定作业结束为止. 返回等待命令的退出状态码.
你可以使用wait命令来防止在后台作业没完成(这会产生一个孤儿进程)之前退出脚本.
例子 11-25. 在继续处理之前, 等待一个进程的结束
1 #!/bin/bash 2 3 ROOT_UID=0 # 只有$UID为0的用户才拥有root权限. 4 E_NOTROOT=65 5 E_NOPARAMS=66 6 7 if [ "$UID" -ne "$ROOT_UID" ] 8 then 9 echo "Must be root to run this script." 10 # "Run along kid, it's past your bedtime." 11 exit $E_NOTROOT 12 fi 13 14 if [ -z "$1" ] 15 then 16 echo "Usage: `basename $0` find-string" 17 exit $E_NOPARAMS 18 fi 19 20 21 echo "Updating 'locate' database..." 22 echo "This may take a while." 23 updatedb /usr & # 必须使用root身份来运行. 24 25 wait 26 # 将不会继续向下运行, 除非'updatedb'命令执行完成. 27 # 你希望在查找文件名之前更新database. 28 29 locate $1 30 31 # 如果没有'wait'命令的话, 而且在比较糟的情况下, 32 #+ 脚本可能在'updatedb'命令还在运行的时候退出, 33 #+ 这将会导致'updatedb'成为一个孤儿进程. 34 35 exit 0 |
可选的, wait也可以接受一个作业标识符作为参数, 比如, wait%1或者wait $PPID. 请参考作业标识符表.
在一个脚本中, 使用后台运行命令(&)可能会使这个脚本挂起, 直到敲ENTER, 挂起的脚本才会被恢复. 看起来只有在这个命令的结果需要输出到stdout的时候, 这种现象才会出现. 这是个很烦人的现象.
看起来只要在后台运行命令的后边加上一个wait命令就会解决这个问题.
|
这个命令的效果与Control-Z很相像, 但是它挂起的是这个shell(这个shell的父进程应该在合适的时候重新恢复它).
退出一个已经登陆上的shell, 也可以指定一个退出状态码.
给出执行命令所占用的时间, 使用如下的形式进行输出:
0m0.020s 0m0.020s |
通过发送一个适当的结束信号, 来强制结束一个进程(请参考例子 13-6).
例子 11-26. 一个结束自身的脚本程序
1 #!/bin/bash 2 # self-destruct.sh 3 4 kill $$ # 脚本将在此处结束自己的进程. 5 # 回忆一下,"$$"就是脚本的PID. 6 7 echo "This line will not echo." 8 # 而且shell将会发送一个"Terminated"消息到stdout. 9 10 exit 0 11 12 # 在脚本结束自身进程之后, 13 #+ 它返回的退出码是什么? 14 # 15 # sh self-destruct.sh 16 # echo $? 17 # 143 18 # 19 # 143 = 128 + 15 20 # 结束信号 |
killall命令将会通过名字来杀掉一个正在运行的进程, 而不是通过进程ID. 如果某个特定的命令有多个实例正在运行, 那么执行一次killall命令就会把这些实例全部杀掉.
这里所指的killall命令是在/usr/bin中, 而不是/etc/rc.d/init.d中的killall脚本. |
对于命令"COMMAND", command COMMAND会直接禁用别名和函数的查找.
译者注, 注意一下Bash执行命令的优先级:
1 1 别名 2 2 关键字 3 3 函数 4 4 内建命令 5 5 脚本或可执行程序($PATH) |
当你使用builtin BUILTIN_COMMAND的时候, 只会调用shell内建命令"BUILTIN_COMMAND", 而暂时禁用同名的函数, 或者是同名的扩展命令.
这个命令或者禁用内建命令或者恢复内建命令. 比如, enable -n kill将禁用内建命令kill, 所以当我们调用kill命令时, 使用的将是/bin/kill外部命令.
-a
选项会enable所有作为参数的shell内建命令,
不管它们之前是否被enable了. (译者注: 如果不带参数的调用enable
-a, 那么会恢复所有内建命令.)
-f filename
选项将会从适当的编译过的目标文件
[1]
中, 让enable命令以共享库的形式来加载内建命令.
这是从ksh中的autoloader命令移植过来的. 一个带有"autoload"声明的函数, 在它第一次被调用的时候才会被加载. [2] 这样做是为了节省系统资源.
注意, autoload命令并不是Bash核心安装时候的一部分. 这个命令需要使用命令enable -f来加载(参考上边的enable命令).
[1] | 一些可加载的内建命令的C源代码通常都放在/usr/share/doc/bash-?.??/functions目录下. 注意, enable的 |
[2] | autoload命令与typeset -fu效果相同. |