I found different examples on the internet on how to run commands through Crystal, but they seem contradictory, and I would like to ask if you could provide one or more examples on how to run simple commands[1] and obtain their result (when there is a result).
Also, among the multiple commands I need to programmatically run, there is one command in particular which returns a new shell context, and I would like to know if Crystal could:
receive such shell context
run multiple command on this new context
exit from such context in some way, like running the “exit” command
If yes, I would like to know if you could provide some guidance or details about it.
Again, I cannot thank you enough for all the knowledge sharing on these years together!
[1] For example, with the Process class, or with another recommended class
My only issue now isn’t related to Process (everything is perfect!), but with the “blocking” that occurs after reading commands which return multiple lines on s.output.
When I do:
require "process"
Process.run(command: "/usr/bin/ssh", args: ["12.34.56.78", "-p1234", "-i /home/user/.ssh/id_rsa"]) do |s|
i = s.input
o = s.output
i.puts "cat /etc/nginx/nginx.conf"
o.each_line do |line|
puts line
end
i.puts "exit"
end
I’m able to read the complete output from cat (with its multiple lines), but Process.run remains stuck and doesn’t end, blocking the execution.
If the exit comes first, the solution is easy. Otherwise, I am not sure either.
require "process"
Process.run(command: "bash") do |s|
i = s.input
o = s.output
Random.rand(10).times do |n|
i.puts "echo Hello_#{n}"
end
i.puts "exit"
puts o.gets_to_end
end
I don’t think it is a very good idea, but it seems to me that Timeout could be used.
require "process"
Process.run(command: "bash") do |s|
i = s.input
o = s.output
o.read_timeout = 1
Random.rand(10).times do |n|
i.puts "echo Hello_#{n}"
end
begin
while l = o.gets
puts l
end
rescue IO::TimeoutError
puts "Timeout #{o.read_timeout}"
end
i.puts "exit"
end