If you want to stop the process, you can trapinterrupt the signal, write the current progress to a file, and then find this file when starting the backup:
progress_file = './script_progress.txt'
x = if File.exists?(progress_file)
File.read(progress_file).to_i
else
0
end
Signal.trap("INT") {
File.open(progress_file, 'w') { |f| f.write(x.to_s) }
exit
}
while x <= 10 do
puts x
x += 1
sleep(1)
end
Result:
$ rm script_progress.txt
$ ruby example.rb
0
1
2
3
^C$ cat script_progress.txt
4
$ ruby example.rb
8
10
12
14
16
18
20
You can also use at_exitto write the file at any time when the script exits (even if it just ends normally):
progress_file = './script_progress.txt'
x = if File.exists?(progress_file)
File.read(progress_file).to_i
else
0
end
at_exit do
File.open(progress_file, 'w') { |f| f.write(x.to_s) }
end
while x <= 10 do
puts x
x += 1
sleep(1)
end
Result:
$ ruby example.rb
0
1
2
3
4
^Cexample.rb:16:in `sleep': Interrupt
from example.rb:16:in `<main>'
$ ruby example.rb
10
12
14
16
18
20
, , , Process.kill:
pid = fork do
Signal.trap("USR1") {
$double = !$double
}
(0..10).each do |x|
puts $double ? x * 2 : x
sleep(1)
end
end
Process.detach(pid)
sleep(5)
Process.kill("USR1", pid)
sleep(6)
:
$ ruby example.rb
0
1
2
3
4
10
12
14
16
18
20
, ruby load:
File.open('print_number.rb', 'w') do |file|
file.write <<-contents
def print_number(x)
puts x
end
contents
end
pid = fork do
load './print_number.rb'
Signal.trap("USR1") {
load './print_number.rb'
}
(0..10).each do |x|
print_number(x)
sleep(1)
end
end
Process.detach(pid)
sleep(5)
File.open('print_number.rb', 'w') do |file|
file.write <<-contents
def print_number(x)
puts x * 2
end
contents
end
Process.kill("USR1", pid)
sleep(6)
:
$ ruby example.rb
0
1
2
3
4
10
12
14
16
18
20