for i in $( seq 1 $1 )
do
kill %$i
done
我尝试用这个脚本杀死已停止的作业,但有趣的是,即使我有空缺的作业,它也无法做到这一点。
$ jobs
[10] Stopped vim detect_thread.py
[11] Stopped python3 detect.py
[12]- Stopped python3 detect.py
[13]+ Stopped python3 detect.py
$ kill 13
bash: kill: (13) - No such process
$ ./delete.sh 13
./delete.sh: line 8: kill: %1: no such job
./delete.sh: line 8: kill: %2: no such job
./delete.sh: line 8: kill: %3: no such job
./delete.sh: line 8: kill: %4: no such job
./delete.sh: line 8: kill: %5: no such job
./delete.sh: line 8: kill: %6: no such job
./delete.sh: line 8: kill: %7: no such job
./delete.sh: line 8: kill: %8: no such job
./delete.sh: line 8: kill: %9: no such job
./delete.sh: line 8: kill: %10: no such job
./delete.sh: line 8: kill: %11: no such job
./delete.sh: line 8: kill: %12: no such job
./delete.sh: line 8: kill: %13: no such job
答案1
内置kill
函数仅识别%N
当前 shell 中运行的作业的格式。但是,shell 脚本在其自己单独的子 shell 中运行,并且在该子 shell 中,没有要终止的作业。通过一个例子可能会更清楚:
$ for i in {1..5}; do sleep 100 & done
[1] 2259152
[2] 2259153
[3] 2259154
[4] 2259155
[5] 2259156
$ for i in {1..5}; do kill %$i; done
[1] Terminated sleep 100
[2] Terminated sleep 100
[3] Terminated sleep 100
[4]- Terminated sleep 100
[5]+ Terminated sleep 100
正如您所看到的,如果您在同一个 shell 会话中运行两组命令,那么这将按预期工作。同样,如果您从同一个 shell 脚本启动和终止命令,它也会起作用:
#! /usr/bin/env bash
for i in {1..5}; do
sleep 100 &
done
## Show the running jobs
runningSleepJobs=$(pgrep -c sleep)
echo "There are $runningSleepJobs sleep jobs running!"
for i in {1..5}; do
kill %$i;
done
## Show that they've been stopped
runningSleepJobs=$(pgrep -c sleep)
echo "Now there are $runningSleepJobs sleep jobs running!"
如果我现在运行此脚本,我可以看到它既启动又按预期终止作业:
$ foo.sh
There are 5 sleep jobs running!
Now there are 0 sleep jobs running!
不过,有一种方法可以解决这个问题。代替执行你的脚本,你可以获取它以便它在当前 shell 中运行:
$ cat ~/bin/foo.sh
#! /usr/bin/env bash
for i in $( seq 1 $1 )
do
kill %$i
done
$ for i in {1..5}; do sleep 100 & done
[1] 2295221
[2] 2295222
[3] 2295223
[4] 2295224
[5] 2295225
$ jobs
[1] Running sleep 100 &
[2] Running sleep 100 &
[3] Running sleep 100 &
[4]- Running sleep 100 &
[5]+ Running sleep 100 &
$ . ~/scripts/foo.sh 5
[1] Terminated sleep 100
[2] Terminated sleep 100
[3] Terminated sleep 100
[4]- Terminated sleep 100
[5]+ Terminated sleep 100
答案2
shell 脚本将在其自己的环境中运行,这意味着作业管理将不知道执行脚本的 shell 的作业名册。用于.
在当前环境中运行脚本:
$ . ./delete.sh 13