1

I have this question: creating an at job that copies all files in your home directory to /var/tmp within half an hour. You may want to create a sub-directory in /var/tmp. A message will appear to indicate that the copying task is successfully done and I try to solve like this :

cp * /var/tmp/ | (try to kill cp )| at now + 30 minute

but I am steel I didn't find command that kill cp?

the question in book and i try to solve it . what i understand that copy all file in home to /var/tmp and if the copy file encroach 30 within half an hour then i should stop it copy

2 Answers2

1

You could write a script, assuming you only have one cp command in the script, you could use $$ which returns the PID of the shell script, so ps -ef | grep $$ will return your script as well as the cp command, so ps -ef | grep -E "$$.*cp will return the PID of the cp command, then you simply do kill -15 <pid>. Here is a script that does it all, do NOT put "cp" in the name.

#!/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"

This script you can schedule with at or cron.

You probably would like to do the following if you have to use at to kill the script, name this one myScript.sh:

#!/bin/sh

echo $$ > /tmp/myPID    
cp -r .* /var/tmp/
rm /tmp/myPID

A second script named killerQueen.sh for at to kill the process after 30 minutes:

#!/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

run the following:

$ myScript.sh&
Job 1
$ at -f ./killerQueen.sh now + 30 minute

This second example is safer, because we kill the script that performs the copy, if it is still running, else we create a file named /tmp/message<pid_of_killerQueen> with the text "copy succeeded".

EDIT, after reading man at and your comment:

cp -r * /var/tmp& echo "kill -15 \$(ps -ef | grep \"$$.*cp \" | grep -v grep | awk '{print $2}')" | at now + 1 second
thecarpy
  • 405
0

Firs I would suggest you to use the rsync command to preserve unnecessary copy of unchanged files. Second you could push the rsync process into the background by using the command nohup. Then you can kill the process, using the PID of the job most recently placed into the background !$ (issued by the nohup command) at certain time:

#!/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

References:


Alternatively you could use the timeout command - as @steeldriver have suggested - in this way:

timeout 1800 rsync -arqvzh --ignore-errors "$HOME"/* "/var/tmp/" &

Where:

  • 1800 is the duration of the timeout in seconds.
  • & will push the process into the background, thus you could use the current shell.
pa4080
  • 30,621