Ruby: 如何在后台将数据传递给程序 运行
Ruby: How to pass data to a program running in background
虽然 Ruby 是我现在选择的语言,但如果有人用另一种语言的示例回答这个问题,我并不介意,因为我对这个概念更感兴趣。
如果我后台有脚本运行;我将如何编写该脚本以便我可以在它仍然是 运行?
时将数据输入传递给它
如果我 运行 它在前台的终端中,解决方案就像创建一个线程一样简单,然后在 STDIN 上终止该线程,此时将调用一个单独的函数来处理用户输入。
但是考虑到这个脚本在后台是运行,这种方法并不实用。我认为参数是与程序交互的最佳方式(尽管我可能错了)。
当然有很多方法可以把数据传给后台程序,比如链接到一个文件,我也写数据,程序再读。 但是我希望这些数据严格通过终端输入。
详细说明: 有一个操作系统进程永远在后台 运行,但是我可以将数据传递给它以通过 运行 一个命令,例如:program_name -newdata
,我正在尝试将相同的功能编程到我自己的脚本之一中。
提前致谢。
有很多方法可以实现这种行为。假设你想要一些简单的东西,你可以尝试这些解决方案:
您可以通过文件传递数据,定义对该文件的特定访问权限并依赖于您的 OS。
您还可以实现经过身份验证的服务并将此服务绑定到本地套接字。
您可以使用 unix 套接字来使用消息传递。您可以在一个 executable 文件中完成,但为简单起见,我在两个单独的文件中完成。
在 program_name_background
文件中,您可以启动正在侦听 unix 套接字和解析消息的 UNIXServer(以及 运行 您在不同线程中需要的任何内容):
#!/usr/bin/ruby
require 'socket'
require 'json'
require 'FileUtils'
socket_path = "/tmp/program_name_background.sock"
at_exit { FileUtils.rm socket_path }
server = UNIXServer.new socket_path
loop do
client = server.accept
message = client.read
json_message = JSON.parse message, symbolize_names: true
p json_message
break if json_message[:type] == "SIGTERM"
end
在 program_name_control
文件中,您可以从命令行读取属性并将消息发送到后台进程:
#!/usr/bin/ruby
require 'socket'
require 'json'
case ARGV[0]
when "-newdata"
message = {
type: :newdata,
data: ARGV[1]
}
when "stop"
message = { type: :SIGTERM }
else
p "Error: unknown param: #{ARGV[0]}"
exit
end
client = UNIXSocket.open "/tmp/program_name_background.sock"
client.print JSON.generate(message)
client.close
对于解析选项,您可以使用内置的 OptionParser
你可以这样测试:
- 启动后台进程:
./program_name_background
- 从其他选项卡发送消息:
./program_name_control -newdata 118
您还可以为 /usr/local/bin
文件夹中的这些文件设置符号链接,这样您就可以从任何地方调用它们而无需前导 ./
您可以守护后台进程,这样它就不会附加到终端。
虽然 Ruby 是我现在选择的语言,但如果有人用另一种语言的示例回答这个问题,我并不介意,因为我对这个概念更感兴趣。
如果我后台有脚本运行;我将如何编写该脚本以便我可以在它仍然是 运行?
时将数据输入传递给它如果我 运行 它在前台的终端中,解决方案就像创建一个线程一样简单,然后在 STDIN 上终止该线程,此时将调用一个单独的函数来处理用户输入。 但是考虑到这个脚本在后台是运行,这种方法并不实用。我认为参数是与程序交互的最佳方式(尽管我可能错了)。
当然有很多方法可以把数据传给后台程序,比如链接到一个文件,我也写数据,程序再读。 但是我希望这些数据严格通过终端输入。
详细说明: 有一个操作系统进程永远在后台 运行,但是我可以将数据传递给它以通过 运行 一个命令,例如:program_name -newdata
,我正在尝试将相同的功能编程到我自己的脚本之一中。
提前致谢。
有很多方法可以实现这种行为。假设你想要一些简单的东西,你可以尝试这些解决方案:
您可以通过文件传递数据,定义对该文件的特定访问权限并依赖于您的 OS。
您还可以实现经过身份验证的服务并将此服务绑定到本地套接字。
您可以使用 unix 套接字来使用消息传递。您可以在一个 executable 文件中完成,但为简单起见,我在两个单独的文件中完成。
在 program_name_background
文件中,您可以启动正在侦听 unix 套接字和解析消息的 UNIXServer(以及 运行 您在不同线程中需要的任何内容):
#!/usr/bin/ruby
require 'socket'
require 'json'
require 'FileUtils'
socket_path = "/tmp/program_name_background.sock"
at_exit { FileUtils.rm socket_path }
server = UNIXServer.new socket_path
loop do
client = server.accept
message = client.read
json_message = JSON.parse message, symbolize_names: true
p json_message
break if json_message[:type] == "SIGTERM"
end
在 program_name_control
文件中,您可以从命令行读取属性并将消息发送到后台进程:
#!/usr/bin/ruby
require 'socket'
require 'json'
case ARGV[0]
when "-newdata"
message = {
type: :newdata,
data: ARGV[1]
}
when "stop"
message = { type: :SIGTERM }
else
p "Error: unknown param: #{ARGV[0]}"
exit
end
client = UNIXSocket.open "/tmp/program_name_background.sock"
client.print JSON.generate(message)
client.close
对于解析选项,您可以使用内置的 OptionParser
你可以这样测试:
- 启动后台进程:
./program_name_background
- 从其他选项卡发送消息:
./program_name_control -newdata 118
您还可以为 /usr/local/bin
文件夹中的这些文件设置符号链接,这样您就可以从任何地方调用它们而无需前导 ./
您可以守护后台进程,这样它就不会附加到终端。