Execute the output of each bash file to a file
Is there a way to pipe each output to a file, like keeping track of the terminal to make a history of everything that's printed?
Also, when I use tee
it, it seems to stop the output of the actual program. How can I change this? I want to keep the normal output and just use a copy of it to save it to a file.
As an example, I have this ruby ββscript:
100.times do |i|
puts i
end
And running will $ruby script.rb | tee output.txt
save the result just fine, but it will only be printed after everything is working.
source to share
Execution with Bash
If you are using bash (which matches your tags) you can run script -a -c "ruby your_script.rb" -f your_file.out
.
So, for example, if you wrote the following script, saved it as test.rb
:
# test.rb
i = 0
while true do
i += 1
puts i
sleep 1
end
And then run script -a -c "ruby test.rb" -f test.out
, you will be able to update the file every time and see it growing one by one every second, even if the script is in the media resource; that is, it still works. This is because it "flushes" every outlet.
DRAWBACKS: You can only do this with a command script
in bash. Because of this, you create a dependency; if it script
doesn't exist or doesn't work as it does script
on my machine, then this approach may not work at all. Always be careful with dependencies.
Doing this in Ruby itself
Sometimes you may not run your script on bash and script
may not be available. What then? Well, you can just create a method that prints to a file and then to stdout, regardless of the operating system. Then it will clean up the file every time to make sure it is up to date.
# print_to_file.rb
class PrintOutputToFile
def self.file
@@file ||= File.open("my_output.log", "w")
end
def self.puts! some_data
file.write "#{some_data}\n"
file.flush
puts some_data
end
end
i = 0
while true do
i += 1
PrintOutputToFile.puts! i
sleep 1
end
Drawbacks: . This will clean up the file every time you run it. You may need to modify this little script if you want to keep a long term log that is retained across many runs. Also, this script will crash if you don't have file permissions. This is not intended for production, but simply as a proof of concept for those interested in implementing such a system.
Another way to do it in Ruby itself
You can also do this by copying the old puts method into proc and then overriding the puts method to write to the log file, but ending it with a call to the original puts method.
@@old_puts = method(:puts).to_proc
def puts(output)
@@file ||= File.open("your_log.txt", "w")
@@file.write "#{output}\n"
@@old_puts.call output
@@file.flush
end
DRAWBACKS: This is a step outside of the hack, and I honestly don't recommend it unless you really know what you are doing and absolutely must.
source to share