首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

控制预定作业的持续时间(1)

控制预定作业的持续时间(1)

定时器进程shell 脚本中执行定时的基本工具是 sleep 命令,该命令将使运行中的 shell 在指定的一段时间内暂停执行。默认的暂停时间为数秒,但是可以使用 s、m 或 h 命令分别将时间值设置为秒、分钟或小时级别。这将延缓 shell 的执行,因此需要在另一个 shell 中运行实时任务,通过将任务放到使用 & 字符的后台中运行即可达到此目的。
首先,假定您需要使某个命令持续运行 10 分钟。您将编写清单 1 所示的 bash shell 脚本来按照指定的时间段运行 xclock 命令。请在您自己的系统中尝试运行。
清单 1. 首次尝试使用 runclock1.sh
1
2
3
4
5
6
7
#!/bin/bash
runtime=${1:-10m}
# Run xclock in background
xclock&
#Sleep for the specified time.
sleep $runtime
echo "All done"




您应该能看到类似图 1 所示的时钟。
图 1. 一个简单的 xclock这种方法惟一的缺陷就是:虽然脚本停止了运行,但是时钟仍然继续运行。
父进程,子进程和孤儿进程(orphan)清单 2 展示了一个增强的 runclock2.sh 脚本,它在 shell 完成后捕获 shell 和 xclock 进程的进程 id 信息,以及脚本输出和 ps 命令输出,并显示 xclock 的进程状态。
清单 2. 收集诊断信息 runclock2.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[ian@attic4 ~]$ cat runclock2.sh
#!/bin/bash
runtime=${1:-10m}
mypid=$$
# Run xclock in background
xclock&
clockpid=$!
echo "My PID=$mypid. Clock's PID=$clockpid"
ps -f $clockpid
#Sleep for the specified time.
sleep $runtime
echo "All done"
[ian@attic4 ~]$ ./runclock2.sh 10s
My PID=8619. Clock's PID=8620
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
ian       8620  8619  0 19:57 pts/1    S+     0:00 xclock
All done
[ian@attic4 ~]$ ps -f 8620
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
ian       8620     1  0 19:57 pts/1    S      0:00 xclock




注意:ps 的第一个输出中的父进程 id(PPID)为 8619,这是脚本的进程 id(PID)。当脚本终止后,这个时钟进程将变成孤儿进程并被指定为 init 进程(进程 1)的子进程。当父进程终止时,子进程不会立即终止,但是它将在用户注销系统后终止。
终止子进程终止子进程的解决方法就是使用 kill 命令进行显式终止。它将向进程发送一个信号,这通常都会使进程终止。稍后您将看到进程如何 trap 信号而使终止失败,但是这里我们将使用终止信号(SIGINT)来终止时钟。
要查看系统可用的信号列表,请使用 kill 命令和 -l 选项,如清单 3 所示。注意:有些信号可在所有 Linux 系统中通用,而有些信号只能用于特定的机器架构。其中一些信号是由系统生成,例如 floating point exceptions (SIGFPE) 或 segment violation (SIGSEGV),而另一些信号则由应用程序发送,例如 interrupt (SIGINT)、user signals (SIGUSR1 或 SIGUSR2) 或 unconditional terminate (SIGKILL)。
清单 3. Fedora Core 5 系统中的信号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[ian@attic4 ~]$ kill -l
1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT
17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU
25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH
29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN
35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4
39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6
59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX




在清单 2 中,我们使用 $! shell 变量捕获到 xclock 进程的 PID。清单 4 展示了如何使用这些信息向 xclock 进程发送终止信号情报(SIGTERM),从而终止该进程。
清单 4. 使用 runclock3.sh 终止子进程runclock3.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
[ian@attic4 ~]$ cat ./runclock3.sh
#!/bin/bash
runtime=${1:-10m}
mypid=$$
# Run xclock in background
xclock&
clockpid=$!
echo "My PID=$mypid. Clock's PID=$clockpid"
ps -f $clockpid
#Sleep for the specified time.
sleep $runtime
kill -s SIGTERM $clockpid
echo "All done"




清单 5 展示了在执行 runclock3.sh 时发生的操作。最后的 kill 命令确定 xclock 进程(PID 9285)确实已终止。
清单 5. 验证子进程是否终止
1
2
3
4
5
6
7
[ian@attic4 ~]$ ./runclock3.sh 5s
My PID=9284. Clock's PID=9285
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
ian       9285  9284  0 22:14 pts/1    S+     0:00 xclock
All done
[ian@attic4 ~]$ kill -0 9285
bash: kill: (9285) - No such process




如果没有查看信号规范,那么这里稍作说明:SIGTERM 是默认信号。信号名称中的 SIG 部分是可选的。无需使用 -s 和信号名,只需在信号数之前加上 - 前缀,因此清单 6 中显示的四种方法都能够终止进程 9285。注意特殊值 -0,正如清单 4 中的用法一样,它将测试是否可以将某个信号发送到进程。
清单 6. 使用 kill 命令指定信号的方法
1
2
3
4
kill -s SIGTERM 9285
kill -s TERM 9285
kill -15 9285
kill 9285

返回列表