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.

+3


source to share


1 answer


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.

+3


source







All Articles