Open3 模組
Open3 模組支援建立子程序,並存取其 $stdin、$stdout 和 $stderr 串流。
此處內容¶ ↑
這些方法會在新程序或子殼中執行給定的指令,或在新程序和/或子殼中執行多個指令
-
這些方法會在程序或子殼中執行單一指令,接受輸入 $stdin 的字串,並傳回 $stdout、$stderr 或兩者的字串輸出
-
Open3.capture2
:執行指令;傳回 $stdout 的字串。 -
Open3.capture2e
:執行指令;傳回合併 $stdout 和 $stderr 的字串。 -
Open3.capture3
:執行指令;傳回 $stdout 和 $stderr 的字串。
-
-
這些方法會在程序或子殼中執行單一指令,並傳回 $stdin、$stdout 和/或 $stderr 的管線
-
Open3.popen2
:執行指令;傳回 $stdin 和 $stdout 的管線。 -
Open3.popen2e
:執行指令;傳回 $stdin 和合併 $stdout 和 $stderr 的管線。 -
Open3.popen3
:執行指令;傳回 $stdin、$stdout 和 $stderr 的管線。
-
-
這些方法會在程序和/或子殼中執行一個或多個指令,傳回第一個 $stdin、最後一個 $stdout 或兩者的管線
-
Open3.pipeline_r
:傳回最後一個 $stdout 的管線。 -
Open3.pipeline_rw
:傳回第一個 $stdin 和最後一個 $stdout 的管線。 -
Open3.pipeline_w
:傳回第一個 $stdin 的管線。 -
Open3.pipeline_start
:不會等待程序完成。 -
Open3.pipeline
:等待處理程序完成。
-
以上每種方法都接受
-
環境變數名稱和值的選用雜湊;請參閱 執行環境。
-
必需的字串引數,為
command_line
或exe_path
;請參閱 引數 command_line 或 exe_path。 -
執行選項的選用雜湊;請參閱 執行選項。
常數
- VERSION
公開類別方法
基本上是 Open3.popen3
的包裝器,它
-
透過使用提供的引數(雜湊
options
中的特定項目除外;請參閱下方)呼叫Open3.popen3
來建立子處理程序。 -
將子處理程序的標準輸出作為字串
stdout_s
傳回。 -
將
Process::Status
物件作為status
傳回,它代表子處理程序的結束狀態。
傳回陣列 [stdout_s, status]
stdout_s, status = Open3.capture2('echo "Foo"') # => ["Foo\n", #<Process::Status: pid 2326047 exit 0>]
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會成為呼叫 Open3.popen3
時的領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會成為呼叫 Open3.popen3
時的尾隨引數 options
;請參閱 執行選項。
提供雜湊 options
;兩個選項在方法 Open3.capture2
中具有區域效果
-
如果項目
options[:stdin_data]
存在,則移除該項目,並將其字串值傳送至命令的標準輸入Open3.capture2('tee', stdin_data: 'Foo') # => ["Foo", #<Process::Status: pid 2326087 exit 0>]
-
如果項目
options[:binmode]
存在,則移除該項目,並將內部串流設定為二進位模式。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.capture2('if true; then echo "Foo"; fi') # Shell reserved word. # => ["Foo\n", #<Process::Status: pid 2326131 exit 0>] Open3.capture2('echo') # Built-in. # => ["\n", #<Process::Status: pid 2326139 exit 0>] Open3.capture2('date > date.tmp') # Contains meta character. # => ["", #<Process::Status: pid 2326174 exit 0>]
命令列也可能包含命令的引數和選項
Open3.capture2('echo "Foo"') # => ["Foo\n", #<Process::Status: pid 2326183 exit 0>]
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.capture2('/usr/bin/date') # => ["Fri Sep 29 01:00:39 PM CDT 2023\n", #<Process::Status: pid 2326222 exit 0>]
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.capture2('doesnt_exist') # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.capture2('echo', 'C #') # => ["C #\n", #<Process::Status: pid 2326267 exit 0>] Open3.capture2('echo', 'hello', 'world') # => ["hello world\n", #<Process::Status: pid 2326299 exit 0>]
# File lib/open3.rb, line 775 def capture2(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) binmode = opts.delete(:binmode) popen2(*cmd, opts) {|i, o, t| if binmode i.binmode o.binmode end out_reader = Thread.new { o.read } if stdin_data begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end end i.close [out_reader.value, t.value] } end
基本上是 Open3.popen3
的包裝器,它
-
透過使用提供的引數(雜湊
options
中的特定項目除外;請參閱下方)呼叫Open3.popen3
來建立子處理程序。 -
傳回合併的子處理程序標準輸出和標準錯誤的字串
stdout_and_stderr_s
。 -
將
Process::Status
物件作為status
傳回,它代表子處理程序的結束狀態。
傳回陣列 [stdout_and_stderr_s, status]
stdout_and_stderr_s, status = Open3.capture2e('echo "Foo"') # => ["Foo\n", #<Process::Status: pid 2371692 exit 0>]
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會成為呼叫 Open3.popen3
時的領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會成為呼叫 Open3.popen3
時的尾隨引數 options
;請參閱 執行選項。
給定雜湊 options
;兩個選項在方法 Open3.capture2e
中具有局部效果
-
如果項目
options[:stdin_data]
存在,則移除該項目,並將其字串值傳送至命令的標準輸入Open3.capture2e('tee', stdin_data: 'Foo') # => ["Foo", #<Process::Status: pid 2371732 exit 0>]
-
如果項目
options[:binmode]
存在,則移除該項目,並將內部串流設定為二進位模式。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.capture2e('if true; then echo "Foo"; fi') # Shell reserved word. # => ["Foo\n", #<Process::Status: pid 2371740 exit 0>] Open3.capture2e('echo') # Built-in. # => ["\n", #<Process::Status: pid 2371774 exit 0>] Open3.capture2e('date > date.tmp') # Contains meta character. # => ["", #<Process::Status: pid 2371812 exit 0>]
命令列也可能包含命令的引數和選項
Open3.capture2e('echo "Foo"') # => ["Foo\n", #<Process::Status: pid 2326183 exit 0>]
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.capture2e('/usr/bin/date') # => ["Sat Sep 30 09:01:46 AM CDT 2023\n", #<Process::Status: pid 2371820 exit 0>]
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.capture2e('doesnt_exist') # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.capture2e('echo', 'C #') # => ["C #\n", #<Process::Status: pid 2371856 exit 0>] Open3.capture2e('echo', 'hello', 'world') # => ["hello world\n", #<Process::Status: pid 2371894 exit 0>]
# File lib/open3.rb, line 902 def capture2e(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) binmode = opts.delete(:binmode) popen2e(*cmd, opts) {|i, oe, t| if binmode i.binmode oe.binmode end outerr_reader = Thread.new { oe.read } if stdin_data begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end end i.close [outerr_reader.value, t.value] } end
基本上是 Open3.popen3
的包裝器,它
-
透過使用提供的引數(雜湊
options
中的特定項目除外;請參閱下方)呼叫Open3.popen3
來建立子處理程序。 -
傳回子處理程序的標準輸出和標準錯誤的字串
stdout_s
和stderr_s
。 -
將
Process::Status
物件作為status
傳回,它代表子處理程序的結束狀態。
傳回陣列 [stdout_s, stderr_s, status]
stdout_s, stderr_s, status = Open3.capture3('echo "Foo"') # => ["Foo\n", "", #<Process::Status: pid 2281954 exit 0>]
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會成為呼叫 Open3.popen3
時的領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會成為呼叫 Open3.popen3
時的尾隨引數 options
;請參閱 執行選項。
給定雜湊 options
;兩個選項在方法 Open3.capture3
中具有局部效果
-
如果項目
options[:stdin_data]
存在,則移除該項目,並將其字串值傳送至命令的標準輸入Open3.capture3('tee', stdin_data: 'Foo') # => ["Foo", "", #<Process::Status: pid 2319575 exit 0>]
-
如果項目
options[:binmode]
存在,則移除該項目,並將內部串流設定為二進位模式。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.capture3('if true; then echo "Foo"; fi') # Shell reserved word. # => ["Foo\n", "", #<Process::Status: pid 2282025 exit 0>] Open3.capture3('echo') # Built-in. # => ["\n", "", #<Process::Status: pid 2282092 exit 0>] Open3.capture3('date > date.tmp') # Contains meta character. # => ["", "", #<Process::Status: pid 2282110 exit 0>]
命令列也可能包含命令的引數和選項
Open3.capture3('echo "Foo"') # => ["Foo\n", "", #<Process::Status: pid 2282092 exit 0>]
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.capture3('/usr/bin/date') # => ["Thu Sep 28 05:03:51 PM CDT 2023\n", "", #<Process::Status: pid 2282300 exit 0>]
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.capture3('doesnt_exist') # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.capture3('echo', 'C #') # => ["C #\n", "", #<Process::Status: pid 2282368 exit 0>] Open3.capture3('echo', 'hello', 'world') # => ["hello world\n", "", #<Process::Status: pid 2282372 exit 0>]
# File lib/open3.rb, line 648 def capture3(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) || '' binmode = opts.delete(:binmode) popen3(*cmd, opts) {|i, o, e, t| if binmode i.binmode o.binmode e.binmode end out_reader = Thread.new { o.read } err_reader = Thread.new { e.read } begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end i.close [out_reader.value, err_reader.value, t.value] } end
基本上是 Process.spawn
的包裝器,它
-
透過呼叫
Process.spawn
為每個指定的cmds
建立一個子程序。 -
將每個子程序的
stdout
管線傳遞到下一個子程序的stdin
,或對於最後一個子程序,傳遞到呼叫者的stdout
。 -
等待子程序結束。
-
傳回
Process::Status
物件的陣列(每個子程序一個)。
範例
wait_threads = Open3.pipeline('ls', 'grep R') # => [#<Process::Status: pid 2139200 exit 0>, #<Process::Status: pid 2139202 exit 0>]
輸出
Rakefile README.md
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
如果第一個參數是雜湊,它會成為每個呼叫 Process.spawn
的主要參數 env
;請參閱 執行環境。
如果最後一個參數是雜湊,它會成為每個呼叫 Process.spawn
的尾端參數 options
;請參閱 執行選項。
cmds
中的每個剩餘參數為下列其中之一:
-
command_line
:字串,以 shell 保留字或特殊內建函數開頭,或包含一個或多個元字元。 -
exe_path
:字串路徑,指向要呼叫的可執行檔。 -
包含
command_line
或exe_path
的陣列,以及命令的零個或多個字串參數。
請參閱 參數 command_line 或 exe_path。
# File lib/open3.rb, line 1334 def pipeline(*cmds) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end pipeline_run(cmds, opts, [], []) {|ts| ts.map(&:value) } end
基本上是 Process.spawn
的包裝器,它
-
透過呼叫
Process.spawn
為每個指定的cmds
建立一個子程序。 -
將每個子程序的
stdout
管線傳遞到下一個子程序的stdin
,或對於最後一個子程序,傳遞到呼叫者的stdout
。
此方法不會等待子程序結束,因此呼叫者必須這麼做。
如果沒有提供區塊,會傳回包含下列 2 個元素的陣列:
-
最後一個子程序的
stdout
串流。 -
所有子程序的等待執行緒陣列。
範例
last_stdout, wait_threads = Open3.pipeline_r('ls', 'grep R') # => [#<IO:fd 5>, [#<Process::Waiter:0x000055e8de2f9898 dead>, #<Process::Waiter:0x000055e8de2f94b0 sleep>]] puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end
輸出
Rakefile README.md
如果提供區塊,會使用最後一個子程序的 stdout
串流和等待程序陣列呼叫區塊。
Open3.pipeline_r('ls', 'grep R') do |last_stdout, wait_threads| puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end end
輸出
Rakefile README.md
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
如果第一個參數是雜湊,它會成為每個呼叫 Process.spawn
的主要參數 env
;請參閱 執行環境。
如果最後一個參數是雜湊,它會成為每個呼叫 Process.spawn
的尾端參數 options
;請參閱 執行選項。
cmds
中的每個剩餘參數為下列其中之一:
-
command_line
:字串,以 shell 保留字或特殊內建函數開頭,或包含一個或多個元字元。 -
exe_path
:字串路徑,指向要呼叫的可執行檔。 -
包含
command_line
或exe_path
的陣列,以及命令的零個或多個字串參數。
請參閱 參數 command_line 或 exe_path。
# File lib/open3.rb, line 1104 def pipeline_r(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [out_w], [out_r], &block) end
基本上是 Process.spawn
的包裝器,它
-
透過呼叫
Process.spawn
為每個指定的cmds
建立一個子程序。 -
將每個子程序的
stdout
管線傳遞到下一個子程序的stdin
,或對於第一個子程序,從呼叫者的stdin
,或對於最後一個子程序,傳遞到呼叫者的stdout
。
此方法不會等待子程序結束,因此呼叫者必須這麼做。
如果沒有提供區塊,會傳回包含下列 3 個元素的陣列:
-
第一個子程序的
stdin
串流。 -
最後一個子程序的
stdout
串流。 -
所有子程序的等待執行緒陣列。
範例
first_stdin, last_stdout, wait_threads = Open3.pipeline_rw('sort', 'cat -n') # => [#<IO:fd 20>, #<IO:fd 21>, [#<Process::Waiter:0x000055e8de29ab40 sleep>, #<Process::Waiter:0x000055e8de29a690 sleep>]] first_stdin.puts("foo\nbar\nbaz") first_stdin.close # Send EOF to sort. puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end
輸出
1 bar 2 baz 3 foo
給定一個區塊,使用第一個子程序的 stdin
串流、最後一個子程序的 stdout
串流,以及等待程序的陣列呼叫該區塊。
Open3.pipeline_rw('sort', 'cat -n') do |first_stdin, last_stdout, wait_threads| first_stdin.puts "foo\nbar\nbaz" first_stdin.close # send EOF to sort. puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end end
輸出
1 bar 2 baz 3 foo
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
如果第一個參數是雜湊,它會成為每個呼叫 Process.spawn
的主要參數 env
;請參閱 執行環境。
如果最後一個參數是雜湊,它會成為每個呼叫 Process.spawn
的尾端參數 options
;請參閱 執行選項。
cmds
中的每個剩餘參數為下列其中之一:
-
command_line
:字串,以 shell 保留字或特殊內建函數開頭,或包含一個或多個元字元。 -
exe_path
:字串路徑,指向要呼叫的可執行檔。 -
包含
command_line
或exe_path
的陣列,以及命令的零個或多個字串參數。
請參閱 參數 command_line 或 exe_path。
# File lib/open3.rb, line 1014 def pipeline_rw(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [in_r, out_w], [in_w, out_r], &block) end
基本上是 Process.spawn
的包裝器,它
-
透過呼叫
Process.spawn
為每個指定的cmds
建立一個子程序。 -
不等待子程序結束。
如果沒有給定區塊,則傳回所有子程序的等待執行緒陣列。
範例
wait_threads = Open3.pipeline_start('ls', 'grep R') # => [#<Process::Waiter:0x000055e8de9d2bb0 run>, #<Process::Waiter:0x000055e8de9d2890 run>] wait_threads.each do |wait_thread| wait_thread.join end
輸出
Rakefile README.md
給定一個區塊,使用等待程序的陣列呼叫該區塊。
Open3.pipeline_start('ls', 'grep R') do |wait_threads| wait_threads.each do |wait_thread| wait_thread.join end end
輸出
Rakefile README.md
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
如果第一個參數是雜湊,它會成為每個呼叫 Process.spawn
的主要參數 env
;請參閱 執行環境。
如果最後一個參數是雜湊,它會成為每個呼叫 Process.spawn
的尾端參數 options
;請參閱 執行選項。
cmds
中的每個剩餘參數為下列其中之一:
-
command_line
:字串,以 shell 保留字或特殊內建函數開頭,或包含一個或多個元字元。 -
exe_path
:字串路徑,指向要呼叫的可執行檔。 -
包含
command_line
或exe_path
的陣列,以及命令的零個或多個字串參數。
請參閱 參數 command_line 或 exe_path。
# File lib/open3.rb, line 1272 def pipeline_start(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end if block pipeline_run(cmds, opts, [], [], &block) else ts, = pipeline_run(cmds, opts, [], []) ts end end
基本上是 Process.spawn
的包裝器,它
-
透過呼叫
Process.spawn
為每個指定的cmds
建立一個子程序。 -
將每個子程序的
stdout
導管到下一個子程序的stdin
,或者,對於第一個子程序,將呼叫者的stdout
導管到子程序的stdin
。
此方法不會等待子程序結束,因此呼叫者必須這麼做。
如果沒有提供區塊,會傳回包含下列 2 個元素的陣列:
-
第一個子程序的
stdin
串流。 -
所有子程序的等待執行緒陣列。
範例
first_stdin, wait_threads = Open3.pipeline_w('sort', 'cat -n') # => [#<IO:fd 7>, [#<Process::Waiter:0x000055e8de928278 run>, #<Process::Waiter:0x000055e8de923e80 run>]] first_stdin.puts("foo\nbar\nbaz") first_stdin.close # Send EOF to sort. wait_threads.each do |wait_thread| wait_thread.join end
輸出
1 bar 2 baz 3 foo
給定一個區塊,使用第一個子程序的 stdin
串流,以及等待程序的陣列呼叫該區塊。
Open3.pipeline_w('sort', 'cat -n') do |first_stdin, wait_threads| first_stdin.puts("foo\nbar\nbaz") first_stdin.close # Send EOF to sort. wait_threads.each do |wait_thread| wait_thread.join end end
輸出
1 bar 2 baz 3 foo
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
如果第一個參數是雜湊,它會成為每個呼叫 Process.spawn
的主要參數 env
;請參閱 執行環境。
如果最後一個參數是雜湊,它會成為每個呼叫 Process.spawn
的尾端參數 options
;請參閱 執行選項。
cmds
中的每個剩餘參數為下列其中之一:
-
command_line
:字串,以 shell 保留字或特殊內建函數開頭,或包含一個或多個元字元。 -
exe_path
:字串路徑,指向要呼叫的可執行檔。 -
包含
command_line
或exe_path
的陣列,以及命令的零個或多個字串參數。
請參閱 參數 command_line 或 exe_path。
# File lib/open3.rb, line 1195 def pipeline_w(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true pipeline_run(cmds, opts, [in_r], [in_w], &block) end
基本上是 Process.spawn
的包裝器,它
-
透過使用給定的引數呼叫
Process.spawn
來建立子程序。 -
建立串流
stdin
和stdout
,它們是子程序中的標準輸入和標準輸出串流。 -
建立執行緒
wait_thread
,等待子程序結束;該執行緒有方法pid
,它傳回子程序的程序識別碼。
如果沒有給定區塊,則傳回陣列 [stdin, stdout, wait_thread]
。呼叫者應關閉兩個傳回的串流。
stdin, stdout, wait_thread = Open3.popen2('echo') # => [#<IO:fd 6>, #<IO:fd 7>, #<Process::Waiter:0x00007f58d52dbe98 run>] stdin.close stdout.close wait_thread.pid # => 2263572 wait_thread.value # => #<Process::Status: pid 2263572 exit 0>
給定一個區塊,使用三個變數(兩個串流和等待執行緒)呼叫該區塊,並傳回區塊的傳回值。呼叫者不需要關閉串流。
Open3.popen2('echo') do |stdin, stdout, wait_thread| p stdin p stdout p wait_thread p wait_thread.pid p wait_thread.value end
輸出
#<IO:fd 6> #<IO:fd 7> #<Process::Waiter:0x00007f58d59a34b0 sleep> 2263636 #<Process::Status: pid 2263636 exit 0>
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會在呼叫 Process.spawn
時,變成領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會在呼叫 Process.spawn
時,變成尾隨引數 options
;請參閱 執行選項。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.popen2('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word. Open3.popen2('echo') {|*args| p args } # Built-in. Open3.popen2('date > date.tmp') {|*args| p args } # Contains meta character.
輸出(對於上述每個呼叫都類似)
# => [#<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f7577dfe410 dead>]
命令列也可能包含命令的引數和選項
Open3.popen2('echo "Foo"') { |i, o, t| o.gets } "Foo\n"
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.popen2('/usr/bin/date') { |i, o, t| o.gets } # => "Thu Sep 28 09:41:06 AM CDT 2023\n"
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.popen2('doesnt_exist') { |i, o, t| o.gets } # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.popen2('echo', 'C #') { |i, o, t| o.gets } # => "C #\n" Open3.popen2('echo', 'hello', 'world') { |i, o, t| o.gets } # => "hello world\n"
相關
-
Open3.popen2e
:使子處理程序的標準輸入和標準輸出與標準錯誤串流的合併可用於個別串流。 -
Open3.popen3
:使子處理程序的標準輸入、標準輸出和標準錯誤串流可用於個別串流。
# File lib/open3.rb, line 365 def popen2(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) end
基本上是 Process.spawn
的包裝器,它
-
透過使用給定的引數呼叫
Process.spawn
來建立子程序。 -
建立串流
stdin
、stdout_and_stderr
,它們是子處理程序中的標準輸入和標準輸出與標準錯誤串流的合併。 -
建立執行緒
wait_thread
,等待子程序結束;該執行緒有方法pid
,它傳回子程序的程序識別碼。
如果沒有給定區塊,則傳回陣列 [stdin, stdout_and_stderr, wait_thread]
。呼叫者應關閉兩個傳回的串流。
stdin, stdout_and_stderr, wait_thread = Open3.popen2e('echo') # => [#<IO:fd 6>, #<IO:fd 7>, #<Process::Waiter:0x00007f7577da4398 run>] stdin.close stdout_and_stderr.close wait_thread.pid # => 2274600 wait_thread.value # => #<Process::Status: pid 2274600 exit 0>
給定一個區塊,使用三個變數(兩個串流和等待執行緒)呼叫該區塊,並傳回區塊的傳回值。呼叫者不需要關閉串流。
Open3.popen2e('echo') do |stdin, stdout_and_stderr, wait_thread| p stdin p stdout_and_stderr p wait_thread p wait_thread.pid p wait_thread.value end
輸出
#<IO:fd 6> #<IO:fd 7> #<Process::Waiter:0x00007f75777578c8 sleep> 2274763 #<Process::Status: pid 2274763 exit 0>
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會在呼叫 Process.spawn
時,變成領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會在呼叫 Process.spawn
時,變成尾隨引數 options
;請參閱 執行選項。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.popen2e('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word. Open3.popen2e('echo') {|*args| p args } # Built-in. Open3.popen2e('date > date.tmp') {|*args| p args } # Contains meta character.
輸出(對於上述每個呼叫都類似)
# => [#<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f7577d8a1f0 dead>]
命令列也可能包含命令的引數和選項
Open3.popen2e('echo "Foo"') { |i, o_and_e, t| o_and_e.gets } "Foo\n"
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.popen2e('/usr/bin/date') { |i, o_and_e, t| o_and_e.gets } # => "Thu Sep 28 01:58:45 PM CDT 2023\n"
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.popen2e('doesnt_exist') { |i, o_and_e, t| o_and_e.gets } # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.popen2e('echo', 'C #') { |i, o_and_e, t| o_and_e.gets } # => "C #\n" Open3.popen2e('echo', 'hello', 'world') { |i, o_and_e, t| o_and_e.gets } # => "hello world\n"
相關
-
Open3.popen2
:使子處理程序的標準輸入和標準輸出串流可用於個別串流,但無法存取標準錯誤串流。 -
Open3.popen3
:使子處理程序的標準輸入、標準輸出和標準錯誤串流可用於個別串流。
# File lib/open3.rb, line 508 def popen2e(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[[:out, :err]] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) ensure if block in_r.close in_w.close out_r.close out_w.close end end
基本上是 Process.spawn
的包裝器,它
-
透過使用給定的引數呼叫
Process.spawn
來建立子程序。 -
建立串流
stdin
、stdout
和stderr
,它們是子處理程序中的標準輸入、標準輸出和標準錯誤串流。 -
建立執行緒
wait_thread
,等待子程序結束;該執行緒有方法pid
,它傳回子程序的程序識別碼。
如果沒有給定區塊,則傳回陣列 [stdin, stdout, stderr, wait_thread]
。呼叫者應關閉三個傳回的串流。
stdin, stdout, stderr, wait_thread = Open3.popen3('echo') # => [#<IO:fd 8>, #<IO:fd 10>, #<IO:fd 12>, #<Process::Waiter:0x00007f58d5428f58 run>] stdin.close stdout.close stderr.close wait_thread.pid # => 2210481 wait_thread.value # => #<Process::Status: pid 2210481 exit 0>
如果給定區塊,則使用四個變數(三個串流和等待執行緒)呼叫區塊,並傳回區塊的傳回值。呼叫者不需要關閉串流
Open3.popen3('echo') do |stdin, stdout, stderr, wait_thread| p stdin p stdout p stderr p wait_thread p wait_thread.pid p wait_thread.value end
輸出
#<IO:fd 6> #<IO:fd 7> #<IO:fd 9> #<Process::Waiter:0x00007f58d53606e8 sleep> 2211047 #<Process::Status: pid 2211047 exit 0>
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會在呼叫 Process.spawn
時,變成領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會在呼叫 Process.spawn
時,變成尾隨引數 options
;請參閱 執行選項。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.popen3('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word. Open3.popen3('echo') {|*args| p args } # Built-in. Open3.popen3('date > date.tmp') {|*args| p args } # Contains meta character.
輸出(對於上述每個呼叫都類似)
[#<IO:(closed)>, #<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f58d52f28c8 dead>]
命令列也可能包含命令的引數和選項
Open3.popen3('echo "Foo"') { |i, o, e, t| o.gets } "Foo\n"
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.popen3('/usr/bin/date') { |i, o, e, t| o.gets } # => "Wed Sep 27 02:56:44 PM CDT 2023\n"
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.popen3('doesnt_exist') { |i, o, e, t| o.gets } # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.popen3('echo', 'C #') { |i, o, e, t| o.gets } # => "C #\n" Open3.popen3('echo', 'hello', 'world') { |i, o, e, t| o.gets } # => "hello world\n"
小心避免死結。輸出串流 stdout
和 stderr
有固定大小的緩衝區,所以大量讀取其中一個但未讀取另一個,當未讀取的緩衝區填滿時可能會造成死結。為避免這種情況,stdout
和 stderr
應同時讀取(使用執行緒或 IO.select
)。
相關
-
Open3.popen2
:使子處理程序的標準輸入和標準輸出串流可用於個別串流,但無法存取標準錯誤串流。 -
Open3.popen2e
:使子處理程序的標準輸入和標準輸出與標準錯誤串流的合併可用於個別串流。
# File lib/open3.rb, line 218 def popen3(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w err_r, err_w = IO.pipe opts[:err] = err_w popen_run(cmd, opts, [in_r, out_w, err_w], [in_w, out_r, err_r], &block) end
私人實例方法
基本上是 Open3.popen3
的包裝器,它
-
透過使用提供的引數(雜湊
options
中的特定項目除外;請參閱下方)呼叫Open3.popen3
來建立子處理程序。 -
將子處理程序的標準輸出作為字串
stdout_s
傳回。 -
將
Process::Status
物件作為status
傳回,它代表子處理程序的結束狀態。
傳回陣列 [stdout_s, status]
stdout_s, status = Open3.capture2('echo "Foo"') # => ["Foo\n", #<Process::Status: pid 2326047 exit 0>]
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會成為呼叫 Open3.popen3
時的領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會成為呼叫 Open3.popen3
時的尾隨引數 options
;請參閱 執行選項。
提供雜湊 options
;兩個選項在方法 Open3.capture2
中具有區域效果
-
如果項目
options[:stdin_data]
存在,則移除該項目,並將其字串值傳送至命令的標準輸入Open3.capture2('tee', stdin_data: 'Foo') # => ["Foo", #<Process::Status: pid 2326087 exit 0>]
-
如果項目
options[:binmode]
存在,則移除該項目,並將內部串流設定為二進位模式。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.capture2('if true; then echo "Foo"; fi') # Shell reserved word. # => ["Foo\n", #<Process::Status: pid 2326131 exit 0>] Open3.capture2('echo') # Built-in. # => ["\n", #<Process::Status: pid 2326139 exit 0>] Open3.capture2('date > date.tmp') # Contains meta character. # => ["", #<Process::Status: pid 2326174 exit 0>]
命令列也可能包含命令的引數和選項
Open3.capture2('echo "Foo"') # => ["Foo\n", #<Process::Status: pid 2326183 exit 0>]
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.capture2('/usr/bin/date') # => ["Fri Sep 29 01:00:39 PM CDT 2023\n", #<Process::Status: pid 2326222 exit 0>]
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.capture2('doesnt_exist') # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.capture2('echo', 'C #') # => ["C #\n", #<Process::Status: pid 2326267 exit 0>] Open3.capture2('echo', 'hello', 'world') # => ["hello world\n", #<Process::Status: pid 2326299 exit 0>]
# File lib/open3.rb, line 775 def capture2(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) binmode = opts.delete(:binmode) popen2(*cmd, opts) {|i, o, t| if binmode i.binmode o.binmode end out_reader = Thread.new { o.read } if stdin_data begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end end i.close [out_reader.value, t.value] } end
基本上是 Open3.popen3
的包裝器,它
-
透過使用提供的引數(雜湊
options
中的特定項目除外;請參閱下方)呼叫Open3.popen3
來建立子處理程序。 -
傳回合併的子處理程序標準輸出和標準錯誤的字串
stdout_and_stderr_s
。 -
將
Process::Status
物件作為status
傳回,它代表子處理程序的結束狀態。
傳回陣列 [stdout_and_stderr_s, status]
stdout_and_stderr_s, status = Open3.capture2e('echo "Foo"') # => ["Foo\n", #<Process::Status: pid 2371692 exit 0>]
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會成為呼叫 Open3.popen3
時的領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會成為呼叫 Open3.popen3
時的尾隨引數 options
;請參閱 執行選項。
給定雜湊 options
;兩個選項在方法 Open3.capture2e
中具有局部效果
-
如果項目
options[:stdin_data]
存在,則移除該項目,並將其字串值傳送至命令的標準輸入Open3.capture2e('tee', stdin_data: 'Foo') # => ["Foo", #<Process::Status: pid 2371732 exit 0>]
-
如果項目
options[:binmode]
存在,則移除該項目,並將內部串流設定為二進位模式。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.capture2e('if true; then echo "Foo"; fi') # Shell reserved word. # => ["Foo\n", #<Process::Status: pid 2371740 exit 0>] Open3.capture2e('echo') # Built-in. # => ["\n", #<Process::Status: pid 2371774 exit 0>] Open3.capture2e('date > date.tmp') # Contains meta character. # => ["", #<Process::Status: pid 2371812 exit 0>]
命令列也可能包含命令的引數和選項
Open3.capture2e('echo "Foo"') # => ["Foo\n", #<Process::Status: pid 2326183 exit 0>]
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.capture2e('/usr/bin/date') # => ["Sat Sep 30 09:01:46 AM CDT 2023\n", #<Process::Status: pid 2371820 exit 0>]
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.capture2e('doesnt_exist') # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.capture2e('echo', 'C #') # => ["C #\n", #<Process::Status: pid 2371856 exit 0>] Open3.capture2e('echo', 'hello', 'world') # => ["hello world\n", #<Process::Status: pid 2371894 exit 0>]
# File lib/open3.rb, line 902 def capture2e(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) binmode = opts.delete(:binmode) popen2e(*cmd, opts) {|i, oe, t| if binmode i.binmode oe.binmode end outerr_reader = Thread.new { oe.read } if stdin_data begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end end i.close [outerr_reader.value, t.value] } end
基本上是 Open3.popen3
的包裝器,它
-
透過使用提供的引數(雜湊
options
中的特定項目除外;請參閱下方)呼叫Open3.popen3
來建立子處理程序。 -
傳回子處理程序的標準輸出和標準錯誤的字串
stdout_s
和stderr_s
。 -
將
Process::Status
物件作為status
傳回,它代表子處理程序的結束狀態。
傳回陣列 [stdout_s, stderr_s, status]
stdout_s, stderr_s, status = Open3.capture3('echo "Foo"') # => ["Foo\n", "", #<Process::Status: pid 2281954 exit 0>]
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會成為呼叫 Open3.popen3
時的領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會成為呼叫 Open3.popen3
時的尾隨引數 options
;請參閱 執行選項。
給定雜湊 options
;兩個選項在方法 Open3.capture3
中具有局部效果
-
如果項目
options[:stdin_data]
存在,則移除該項目,並將其字串值傳送至命令的標準輸入Open3.capture3('tee', stdin_data: 'Foo') # => ["Foo", "", #<Process::Status: pid 2319575 exit 0>]
-
如果項目
options[:binmode]
存在,則移除該項目,並將內部串流設定為二進位模式。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.capture3('if true; then echo "Foo"; fi') # Shell reserved word. # => ["Foo\n", "", #<Process::Status: pid 2282025 exit 0>] Open3.capture3('echo') # Built-in. # => ["\n", "", #<Process::Status: pid 2282092 exit 0>] Open3.capture3('date > date.tmp') # Contains meta character. # => ["", "", #<Process::Status: pid 2282110 exit 0>]
命令列也可能包含命令的引數和選項
Open3.capture3('echo "Foo"') # => ["Foo\n", "", #<Process::Status: pid 2282092 exit 0>]
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.capture3('/usr/bin/date') # => ["Thu Sep 28 05:03:51 PM CDT 2023\n", "", #<Process::Status: pid 2282300 exit 0>]
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.capture3('doesnt_exist') # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.capture3('echo', 'C #') # => ["C #\n", "", #<Process::Status: pid 2282368 exit 0>] Open3.capture3('echo', 'hello', 'world') # => ["hello world\n", "", #<Process::Status: pid 2282372 exit 0>]
# File lib/open3.rb, line 648 def capture3(*cmd) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end stdin_data = opts.delete(:stdin_data) || '' binmode = opts.delete(:binmode) popen3(*cmd, opts) {|i, o, e, t| if binmode i.binmode o.binmode e.binmode end out_reader = Thread.new { o.read } err_reader = Thread.new { e.read } begin if stdin_data.respond_to? :readpartial IO.copy_stream(stdin_data, i) else i.write stdin_data end rescue Errno::EPIPE end i.close [out_reader.value, err_reader.value, t.value] } end
基本上是 Process.spawn
的包裝器,它
-
透過呼叫
Process.spawn
為每個指定的cmds
建立一個子程序。 -
將每個子程序的
stdout
管線傳遞到下一個子程序的stdin
,或對於最後一個子程序,傳遞到呼叫者的stdout
。 -
等待子程序結束。
-
傳回
Process::Status
物件的陣列(每個子程序一個)。
範例
wait_threads = Open3.pipeline('ls', 'grep R') # => [#<Process::Status: pid 2139200 exit 0>, #<Process::Status: pid 2139202 exit 0>]
輸出
Rakefile README.md
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
如果第一個參數是雜湊,它會成為每個呼叫 Process.spawn
的主要參數 env
;請參閱 執行環境。
如果最後一個參數是雜湊,它會成為每個呼叫 Process.spawn
的尾端參數 options
;請參閱 執行選項。
cmds
中的每個剩餘參數為下列其中之一:
-
command_line
:字串,以 shell 保留字或特殊內建函數開頭,或包含一個或多個元字元。 -
exe_path
:字串路徑,指向要呼叫的可執行檔。 -
包含
command_line
或exe_path
的陣列,以及命令的零個或多個字串參數。
請參閱 參數 command_line 或 exe_path。
# File lib/open3.rb, line 1334 def pipeline(*cmds) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end pipeline_run(cmds, opts, [], []) {|ts| ts.map(&:value) } end
基本上是 Process.spawn
的包裝器,它
-
透過呼叫
Process.spawn
為每個指定的cmds
建立一個子程序。 -
將每個子程序的
stdout
管線傳遞到下一個子程序的stdin
,或對於最後一個子程序,傳遞到呼叫者的stdout
。
此方法不會等待子程序結束,因此呼叫者必須這麼做。
如果沒有提供區塊,會傳回包含下列 2 個元素的陣列:
-
最後一個子程序的
stdout
串流。 -
所有子程序的等待執行緒陣列。
範例
last_stdout, wait_threads = Open3.pipeline_r('ls', 'grep R') # => [#<IO:fd 5>, [#<Process::Waiter:0x000055e8de2f9898 dead>, #<Process::Waiter:0x000055e8de2f94b0 sleep>]] puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end
輸出
Rakefile README.md
如果提供區塊,會使用最後一個子程序的 stdout
串流和等待程序陣列呼叫區塊。
Open3.pipeline_r('ls', 'grep R') do |last_stdout, wait_threads| puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end end
輸出
Rakefile README.md
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
如果第一個參數是雜湊,它會成為每個呼叫 Process.spawn
的主要參數 env
;請參閱 執行環境。
如果最後一個參數是雜湊,它會成為每個呼叫 Process.spawn
的尾端參數 options
;請參閱 執行選項。
cmds
中的每個剩餘參數為下列其中之一:
-
command_line
:字串,以 shell 保留字或特殊內建函數開頭,或包含一個或多個元字元。 -
exe_path
:字串路徑,指向要呼叫的可執行檔。 -
包含
command_line
或exe_path
的陣列,以及命令的零個或多個字串參數。
請參閱 參數 command_line 或 exe_path。
# File lib/open3.rb, line 1104 def pipeline_r(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [out_w], [out_r], &block) end
基本上是 Process.spawn
的包裝器,它
-
透過呼叫
Process.spawn
為每個指定的cmds
建立一個子程序。 -
將每個子程序的
stdout
管線傳遞到下一個子程序的stdin
,或對於第一個子程序,從呼叫者的stdin
,或對於最後一個子程序,傳遞到呼叫者的stdout
。
此方法不會等待子程序結束,因此呼叫者必須這麼做。
如果沒有提供區塊,會傳回包含下列 3 個元素的陣列:
-
第一個子程序的
stdin
串流。 -
最後一個子程序的
stdout
串流。 -
所有子程序的等待執行緒陣列。
範例
first_stdin, last_stdout, wait_threads = Open3.pipeline_rw('sort', 'cat -n') # => [#<IO:fd 20>, #<IO:fd 21>, [#<Process::Waiter:0x000055e8de29ab40 sleep>, #<Process::Waiter:0x000055e8de29a690 sleep>]] first_stdin.puts("foo\nbar\nbaz") first_stdin.close # Send EOF to sort. puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end
輸出
1 bar 2 baz 3 foo
給定一個區塊,使用第一個子程序的 stdin
串流、最後一個子程序的 stdout
串流,以及等待程序的陣列呼叫該區塊。
Open3.pipeline_rw('sort', 'cat -n') do |first_stdin, last_stdout, wait_threads| first_stdin.puts "foo\nbar\nbaz" first_stdin.close # send EOF to sort. puts last_stdout.read wait_threads.each do |wait_thread| wait_thread.join end end
輸出
1 bar 2 baz 3 foo
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
如果第一個參數是雜湊,它會成為每個呼叫 Process.spawn
的主要參數 env
;請參閱 執行環境。
如果最後一個參數是雜湊,它會成為每個呼叫 Process.spawn
的尾端參數 options
;請參閱 執行選項。
cmds
中的每個剩餘參數為下列其中之一:
-
command_line
:字串,以 shell 保留字或特殊內建函數開頭,或包含一個或多個元字元。 -
exe_path
:字串路徑,指向要呼叫的可執行檔。 -
包含
command_line
或exe_path
的陣列,以及命令的零個或多個字串參數。
請參閱 參數 command_line 或 exe_path。
# File lib/open3.rb, line 1014 def pipeline_rw(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w pipeline_run(cmds, opts, [in_r, out_w], [in_w, out_r], &block) end
基本上是 Process.spawn
的包裝器,它
-
透過呼叫
Process.spawn
為每個指定的cmds
建立一個子程序。 -
不等待子程序結束。
如果沒有給定區塊,則傳回所有子程序的等待執行緒陣列。
範例
wait_threads = Open3.pipeline_start('ls', 'grep R') # => [#<Process::Waiter:0x000055e8de9d2bb0 run>, #<Process::Waiter:0x000055e8de9d2890 run>] wait_threads.each do |wait_thread| wait_thread.join end
輸出
Rakefile README.md
給定一個區塊,使用等待程序的陣列呼叫該區塊。
Open3.pipeline_start('ls', 'grep R') do |wait_threads| wait_threads.each do |wait_thread| wait_thread.join end end
輸出
Rakefile README.md
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
如果第一個參數是雜湊,它會成為每個呼叫 Process.spawn
的主要參數 env
;請參閱 執行環境。
如果最後一個參數是雜湊,它會成為每個呼叫 Process.spawn
的尾端參數 options
;請參閱 執行選項。
cmds
中的每個剩餘參數為下列其中之一:
-
command_line
:字串,以 shell 保留字或特殊內建函數開頭,或包含一個或多個元字元。 -
exe_path
:字串路徑,指向要呼叫的可執行檔。 -
包含
command_line
或exe_path
的陣列,以及命令的零個或多個字串參數。
請參閱 參數 command_line 或 exe_path。
# File lib/open3.rb, line 1272 def pipeline_start(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end if block pipeline_run(cmds, opts, [], [], &block) else ts, = pipeline_run(cmds, opts, [], []) ts end end
基本上是 Process.spawn
的包裝器,它
-
透過呼叫
Process.spawn
為每個指定的cmds
建立一個子程序。 -
將每個子程序的
stdout
導管到下一個子程序的stdin
,或者,對於第一個子程序,將呼叫者的stdout
導管到子程序的stdin
。
此方法不會等待子程序結束,因此呼叫者必須這麼做。
如果沒有提供區塊,會傳回包含下列 2 個元素的陣列:
-
第一個子程序的
stdin
串流。 -
所有子程序的等待執行緒陣列。
範例
first_stdin, wait_threads = Open3.pipeline_w('sort', 'cat -n') # => [#<IO:fd 7>, [#<Process::Waiter:0x000055e8de928278 run>, #<Process::Waiter:0x000055e8de923e80 run>]] first_stdin.puts("foo\nbar\nbaz") first_stdin.close # Send EOF to sort. wait_threads.each do |wait_thread| wait_thread.join end
輸出
1 bar 2 baz 3 foo
給定一個區塊,使用第一個子程序的 stdin
串流,以及等待程序的陣列呼叫該區塊。
Open3.pipeline_w('sort', 'cat -n') do |first_stdin, wait_threads| first_stdin.puts("foo\nbar\nbaz") first_stdin.close # Send EOF to sort. wait_threads.each do |wait_thread| wait_thread.join end end
輸出
1 bar 2 baz 3 foo
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
如果第一個參數是雜湊,它會成為每個呼叫 Process.spawn
的主要參數 env
;請參閱 執行環境。
如果最後一個參數是雜湊,它會成為每個呼叫 Process.spawn
的尾端參數 options
;請參閱 執行選項。
cmds
中的每個剩餘參數為下列其中之一:
-
command_line
:字串,以 shell 保留字或特殊內建函數開頭,或包含一個或多個元字元。 -
exe_path
:字串路徑,指向要呼叫的可執行檔。 -
包含
command_line
或exe_path
的陣列,以及命令的零個或多個字串參數。
請參閱 參數 command_line 或 exe_path。
# File lib/open3.rb, line 1195 def pipeline_w(*cmds, &block) if Hash === cmds.last opts = cmds.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true pipeline_run(cmds, opts, [in_r], [in_w], &block) end
基本上是 Process.spawn
的包裝器,它
-
透過使用給定的引數呼叫
Process.spawn
來建立子程序。 -
建立串流
stdin
和stdout
,它們是子程序中的標準輸入和標準輸出串流。 -
建立執行緒
wait_thread
,等待子程序結束;該執行緒有方法pid
,它傳回子程序的程序識別碼。
如果沒有給定區塊,則傳回陣列 [stdin, stdout, wait_thread]
。呼叫者應關閉兩個傳回的串流。
stdin, stdout, wait_thread = Open3.popen2('echo') # => [#<IO:fd 6>, #<IO:fd 7>, #<Process::Waiter:0x00007f58d52dbe98 run>] stdin.close stdout.close wait_thread.pid # => 2263572 wait_thread.value # => #<Process::Status: pid 2263572 exit 0>
給定一個區塊,使用三個變數(兩個串流和等待執行緒)呼叫該區塊,並傳回區塊的傳回值。呼叫者不需要關閉串流。
Open3.popen2('echo') do |stdin, stdout, wait_thread| p stdin p stdout p wait_thread p wait_thread.pid p wait_thread.value end
輸出
#<IO:fd 6> #<IO:fd 7> #<Process::Waiter:0x00007f58d59a34b0 sleep> 2263636 #<Process::Status: pid 2263636 exit 0>
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會在呼叫 Process.spawn
時,變成領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會在呼叫 Process.spawn
時,變成尾隨引數 options
;請參閱 執行選項。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.popen2('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word. Open3.popen2('echo') {|*args| p args } # Built-in. Open3.popen2('date > date.tmp') {|*args| p args } # Contains meta character.
輸出(對於上述每個呼叫都類似)
# => [#<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f7577dfe410 dead>]
命令列也可能包含命令的引數和選項
Open3.popen2('echo "Foo"') { |i, o, t| o.gets } "Foo\n"
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.popen2('/usr/bin/date') { |i, o, t| o.gets } # => "Thu Sep 28 09:41:06 AM CDT 2023\n"
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.popen2('doesnt_exist') { |i, o, t| o.gets } # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.popen2('echo', 'C #') { |i, o, t| o.gets } # => "C #\n" Open3.popen2('echo', 'hello', 'world') { |i, o, t| o.gets } # => "hello world\n"
相關
-
Open3.popen2e
:使子處理程序的標準輸入和標準輸出與標準錯誤串流的合併可用於個別串流。 -
Open3.popen3
:使子處理程序的標準輸入、標準輸出和標準錯誤串流可用於個別串流。
# File lib/open3.rb, line 365 def popen2(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) end
基本上是 Process.spawn
的包裝器,它
-
透過使用給定的引數呼叫
Process.spawn
來建立子程序。 -
建立串流
stdin
、stdout_and_stderr
,它們是子處理程序中的標準輸入和標準輸出與標準錯誤串流的合併。 -
建立執行緒
wait_thread
,等待子程序結束;該執行緒有方法pid
,它傳回子程序的程序識別碼。
如果沒有給定區塊,則傳回陣列 [stdin, stdout_and_stderr, wait_thread]
。呼叫者應關閉兩個傳回的串流。
stdin, stdout_and_stderr, wait_thread = Open3.popen2e('echo') # => [#<IO:fd 6>, #<IO:fd 7>, #<Process::Waiter:0x00007f7577da4398 run>] stdin.close stdout_and_stderr.close wait_thread.pid # => 2274600 wait_thread.value # => #<Process::Status: pid 2274600 exit 0>
給定一個區塊,使用三個變數(兩個串流和等待執行緒)呼叫該區塊,並傳回區塊的傳回值。呼叫者不需要關閉串流。
Open3.popen2e('echo') do |stdin, stdout_and_stderr, wait_thread| p stdin p stdout_and_stderr p wait_thread p wait_thread.pid p wait_thread.value end
輸出
#<IO:fd 6> #<IO:fd 7> #<Process::Waiter:0x00007f75777578c8 sleep> 2274763 #<Process::Status: pid 2274763 exit 0>
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會在呼叫 Process.spawn
時,變成領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會在呼叫 Process.spawn
時,變成尾隨引數 options
;請參閱 執行選項。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.popen2e('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word. Open3.popen2e('echo') {|*args| p args } # Built-in. Open3.popen2e('date > date.tmp') {|*args| p args } # Contains meta character.
輸出(對於上述每個呼叫都類似)
# => [#<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f7577d8a1f0 dead>]
命令列也可能包含命令的引數和選項
Open3.popen2e('echo "Foo"') { |i, o_and_e, t| o_and_e.gets } "Foo\n"
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.popen2e('/usr/bin/date') { |i, o_and_e, t| o_and_e.gets } # => "Thu Sep 28 01:58:45 PM CDT 2023\n"
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.popen2e('doesnt_exist') { |i, o_and_e, t| o_and_e.gets } # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.popen2e('echo', 'C #') { |i, o_and_e, t| o_and_e.gets } # => "C #\n" Open3.popen2e('echo', 'hello', 'world') { |i, o_and_e, t| o_and_e.gets } # => "hello world\n"
相關
-
Open3.popen2
:使子處理程序的標準輸入和標準輸出串流可用於個別串流,但無法存取標準錯誤串流。 -
Open3.popen3
:使子處理程序的標準輸入、標準輸出和標準錯誤串流可用於個別串流。
# File lib/open3.rb, line 508 def popen2e(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[[:out, :err]] = out_w popen_run(cmd, opts, [in_r, out_w], [in_w, out_r], &block) ensure if block in_r.close in_w.close out_r.close out_w.close end end
基本上是 Process.spawn
的包裝器,它
-
透過使用給定的引數呼叫
Process.spawn
來建立子程序。 -
建立串流
stdin
、stdout
和stderr
,它們是子處理程序中的標準輸入、標準輸出和標準錯誤串流。 -
建立執行緒
wait_thread
,等待子程序結束;該執行緒有方法pid
,它傳回子程序的程序識別碼。
如果沒有給定區塊,則傳回陣列 [stdin, stdout, stderr, wait_thread]
。呼叫者應關閉三個傳回的串流。
stdin, stdout, stderr, wait_thread = Open3.popen3('echo') # => [#<IO:fd 8>, #<IO:fd 10>, #<IO:fd 12>, #<Process::Waiter:0x00007f58d5428f58 run>] stdin.close stdout.close stderr.close wait_thread.pid # => 2210481 wait_thread.value # => #<Process::Status: pid 2210481 exit 0>
如果給定區塊,則使用四個變數(三個串流和等待執行緒)呼叫區塊,並傳回區塊的傳回值。呼叫者不需要關閉串流
Open3.popen3('echo') do |stdin, stdout, stderr, wait_thread| p stdin p stdout p stderr p wait_thread p wait_thread.pid p wait_thread.value end
輸出
#<IO:fd 6> #<IO:fd 7> #<IO:fd 9> #<Process::Waiter:0x00007f58d53606e8 sleep> 2211047 #<Process::Status: pid 2211047 exit 0>
與 Process.spawn
類似,如果使用不受信任的輸入呼叫此方法,可能會產生安全漏洞;請參閱 命令注入。
與 Process.spawn
不同,此方法會等到子處理程序結束後才傳回,因此呼叫端不需要執行此動作。
如果第一個引數是雜湊,它會在呼叫 Process.spawn
時,變成領先引數 env
;請參閱 執行環境。
如果最後一個引數是雜湊,它會在呼叫 Process.spawn
時,變成尾隨引數 options
;請參閱 執行選項。
單一必需引數為下列其中之一
-
command_line
如果它是一個字串,且它以 shell 保留字或特殊內建函數開頭,或如果它包含一個或多個元字元。 -
exe_path
否則。
引數 command_line
字串引數 command_line
是要傳遞給 shell 的命令列;它必須以 shell 保留字開頭,以特殊內建函數開頭,或包含元字元
Open3.popen3('if true; then echo "Foo"; fi') {|*args| p args } # Shell reserved word. Open3.popen3('echo') {|*args| p args } # Built-in. Open3.popen3('date > date.tmp') {|*args| p args } # Contains meta character.
輸出(對於上述每個呼叫都類似)
[#<IO:(closed)>, #<IO:(closed)>, #<IO:(closed)>, #<Process::Waiter:0x00007f58d52f28c8 dead>]
命令列也可能包含命令的引數和選項
Open3.popen3('echo "Foo"') { |i, o, e, t| o.gets } "Foo\n"
引數 exe_path
引數 exe_path
是下列其中之一
-
要呼叫的可執行檔的字串路徑。
-
包含可執行檔路徑和用作執行處理程序名稱的字串的 2 元素陣列。
範例
Open3.popen3('/usr/bin/date') { |i, o, e, t| o.gets } # => "Wed Sep 27 02:56:44 PM CDT 2023\n"
Ruby 直接呼叫可執行檔,沒有 shell 和沒有 shell 展開
Open3.popen3('doesnt_exist') { |i, o, e, t| o.gets } # Raises Errno::ENOENT
如果給定一個或多個 args
,每個都是要傳遞給可執行檔的引數或選項
Open3.popen3('echo', 'C #') { |i, o, e, t| o.gets } # => "C #\n" Open3.popen3('echo', 'hello', 'world') { |i, o, e, t| o.gets } # => "hello world\n"
小心避免死結。輸出串流 stdout
和 stderr
有固定大小的緩衝區,所以大量讀取其中一個但未讀取另一個,當未讀取的緩衝區填滿時可能會造成死結。為避免這種情況,stdout
和 stderr
應同時讀取(使用執行緒或 IO.select
)。
相關
-
Open3.popen2
:使子處理程序的標準輸入和標準輸出串流可用於個別串流,但無法存取標準錯誤串流。 -
Open3.popen2e
:使子處理程序的標準輸入和標準輸出與標準錯誤串流的合併可用於個別串流。
# File lib/open3.rb, line 218 def popen3(*cmd, &block) if Hash === cmd.last opts = cmd.pop.dup else opts = {} end in_r, in_w = IO.pipe opts[:in] = in_r in_w.sync = true out_r, out_w = IO.pipe opts[:out] = out_w err_r, err_w = IO.pipe opts[:err] = err_w popen_run(cmd, opts, [in_r, out_w, err_w], [in_w, out_r, err_r], &block) end