我有这样一个问题:创建一个 at 作业,在半小时内将主目录中的所有文件复制到/var/tmp
。您可能想要在中创建一个子目录/var/tmp
。将出现一条消息,表明复制任务已成功完成,我尝试这样解决:
cp * /var/tmp/ | (try to kill cp )| at now + 30 minute
但是我坚定我没有找到杀死 cp 的命令?
书中的问题,我尝试解决它。我的理解是将主目录中的所有文件复制到 /var/tmp,如果复制文件在半小时内侵占了 30 个文件,那么我应该停止复制
答案1
cp
您可以编写一个脚本,假设脚本中只有一个命令,您可以使用$$
它返回 shell 脚本的 PID,因此ps -ef | grep $$
将返回您的脚本以及命令cp
,因此ps -ef | grep -E "$$.*cp
将返回命令的 PID cp
,然后您只需执行即可kill -15 <pid>
。这是一个可以完成所有操作的脚本,请不要在名称中输入“cp”。
#!/bin/sh
cp -r .* /var/tmp/ &
#sleep 30 minutes then kill cp
sleep 1800 && kill -15 $(ps -ef | grep -E "$$.*cp " | awk '{print $2}') || echo "copy completed as kill failed"
at
您可以使用或来安排此脚本cron
。
at
如果您必须使用脚本来终止该脚本,您可能需要执行以下操作,请命名该脚本myScript.sh
:
#!/bin/sh
echo $$ > /tmp/myPID
cp -r .* /var/tmp/
rm /tmp/myPID
第二个脚本killerQueen.sh
用于at
在 30 分钟后终止该进程:
#!/bin/sh
if [ -f /tmp/myPID]; then
kill -15 $(cat /tmp/myPID)
echo "Copy not complete." > /tmp/message$$
else
echo "Copy successful." > /tmp/message$$
fi
运行以下命令:
$ myScript.sh&
Job 1
$ at -f ./killerQueen.sh now + 30 minute
第二个例子更安全,因为如果执行复制的脚本仍在运行,我们会终止它,否则我们会创建一个名为/tmp/message<pid_of_killerQueen>
“复制成功”的文件。
阅读man at
并发表评论后,请编辑:
cp -r * /var/tmp& echo "kill -15 \$(ps -ef | grep \"$$.*cp \" | grep -v grep | awk '{print $2}')" | at now + 1 second
答案2
首先,我建议您使用命令rsync
来保留未更改文件的不必要副本。其次,您可以将rsync
进程推入背景通过使用命令nohup
。然后,您可以kill
使用最近在特定时间放入后台的作业的 PID !$
(由nohup
命令发出)来查看进程:at
#!/bin/bash
nohup rsync -arqvzh --ignore-errors "$HOME"/* "/var/tmp/" > /dev/null 2>&1 &
echo "kill -9 $!" | at now +30 minutes -M > /dev/null 2>&1
参考:
或者你可以使用timeout
命令-as@steeldriver有建议- 这样:
timeout 1800 rsync -arqvzh --ignore-errors "$HOME"/* "/var/tmp/" &
在哪里:
- 1800 是暂停很快。
&
将会把进程推送到后台,这样你就可以使用当前的shell。