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