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

  • First of all cp * /var/tmp/ launched in your home directory will NOT recursively copy all files. Assuming, for example, that you have a "Music" directory in your home directory, no files from that directory will be copied. Then, it is not clear what you want to achieve. Do you want to copy files for 30 minutes then kill cp or do you want to launch cp every 30 minutes ? I am really trying to understand :-( – thecarpy Dec 03 '17 at 19:12
  • 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 – Zeno moon Dec 03 '17 at 19:17
  • 1
    Can you please [edit] your question to include the exact wording from the book for that task? – Videonauth Dec 03 '17 at 19:24
  • 1
    Sounds like you're trying to re-invent the timeout command – steeldriver Dec 04 '17 at 00:26

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
  • 383
  • 4
  • 12
  • it show a Messages that no such process i write like this : cp -r * /var/tmp & kill -15 $(ps -ef | grep -E "$$.*cp " | awk '{print $2}') | at now + 30 minute || echo "copy completed as kill failed" its correct ? – Zeno moon Dec 03 '17 at 19:55
  • Sorry. I do not use at that much and got a bit confused by your question ... of course, you want to echo the command to at, d'oh. And then, of course, you enter the beautiful world of escaping ... – thecarpy Dec 03 '17 at 20:43
  • it steel tell me that Syntax error.last token seen .s garbled time =( but it did the copy =( and i am so happy that you help me =) – Zeno moon Dec 03 '17 at 21:16
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
  • 29,831