Module: Net::SSH::Open3
- Included in:
- Connection::Session
- Defined in:
- lib/net-ssh-open3.rb
Overview
Net::SSH Open3 extensions. All methods have the same argument list.
optional env: custom environment variables Hash. Note that SSH server typically restricts changeable variables to a very small set, e.g. for OpenSSH see AcceptEnv in /etc/ssh/sshd_config (AcceptEnv LANG LC_*)
command: a single shell command (like in sh -c), or an executable program.
optional arg1, arg2, ...: arguments to an executable mentioned above.
optional options: options hash, keys:
-
redirects: Hash of redirections which will be appended to a command line (you can’t transfer a pipe to a remote system). Key: one of:in,:out,:error aString, value:Integerto redirect to remote fd,Stringto redirect to a file. If a key is a Symbol, localIOmay be specified as a value. In this case, block receivesnilfor the corresponding IO. Example:{ '>>' => '/tmp/log', err: 1 }translates to
'>>/tmp/log 2>&1'Another example:
{ in: $stdin, out: $stdout, err: $stderr } -
channel_retries:Integernumber of retries in case of channel open failure (ssh server usually limits a session to 10 channels), or an array of [retries,delay] -
stdin_data: forcapture*only, specifies data to be immediately sent tostdinof a remote process. stdin is immediately closed then. -
logger: an object which responds todebug/info/warn/errorand optionallyinit/stdin/stdout/stderrto log debug information and data exchange stream. -
fetch_pid: prepend command with ‘echo $$’ and capture first line of the output as PID. Defaults to true. -
pty: true or aHashof PTY settings to request a pseudo-TTY, see Net::SSH documentation for more information. A note about sending TERM/QUIT: use modes, e.g.:Net::SSH.start('localhost', ENV['USER']).capture2e('cat', pty: { modes: { Net::SSH::Connection::Term::VINTR => 0x01020304, # INT on this 4-byte-sequence Net::SSH::Connection::Term::VQUIT => 0xdeadbeef, # QUIT on this 4-byte sequence Net::SSH::Connection::Term::VEOF => 0xfacefeed, # EOF sequence Net::SSH::Connection::Term::ECHO => 0, # disable echoing Net::SSH::Connection::Term::ISIG => 1 # enable sending signals } }, stdin_data: [0xDEADBEEF].pack('L'), logger: Class.new { alias method_missing puts; def respond_to?(_); true end }.new) # log skipped ... # => ["", #<Net::SSH::Process::Status: pid 1744 QUIT (signal 3) core true>]Note that just closing stdin is not enough for PTY. You should explicitly send VEOF as a first char of a line, see termios(3).
Instance Method Summary collapse
-
#capture2(*args) ⇒ Object
Captures stdout only.
-
#capture2e(*args) ⇒ Object
Captures stdout and stderr into one string.
-
#capture3(*args) ⇒ Object
Captures stdout and stderr into separate strings.
-
#popen2(*args, &block) ⇒ Object
Yields
stdin,stdout,waiter_threadinto a block. -
#popen2e(*args, &block) ⇒ Object
Yields
stdin,stdout-stderr,waiter_threadinto a block. -
#popen3(*args, &block) ⇒ Object
Opens pipes to a remote process.
Instance Method Details
#capture2(*args) ⇒ Object
Captures stdout only. Returns [String, Net::SSH::Process::Status]
146 147 148 149 150 151 152 153 154 155 |
# File 'lib/net-ssh-open3.rb', line 146 def capture2(*args) stdout = StringIO.new stdin_data = (args)[:stdin_data] run_popen(*args, stdin: stdin_data, stdout: stdout) do |waiter_thread| [stdout.string, waiter_thread.value] end end |
#capture2e(*args) ⇒ Object
Captures stdout and stderr into one string. Returns [String, Net::SSH::Process::Status]
158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/net-ssh-open3.rb', line 158 def capture2e(*args) stdout = StringIO.new stdin_data = (args)[:stdin_data] run_popen(*args, stdin: stdin_data, stdout: stdout, stderr: stdout) do |waiter_thread| [stdout.string, waiter_thread.value] end end |
#capture3(*args) ⇒ Object
Captures stdout and stderr into separate strings. Returns [String, String, Net::SSH::Process::Status]
171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/net-ssh-open3.rb', line 171 def capture3(*args) stdout, stderr = StringIO.new, StringIO.new stdin_data = (args)[:stdin_data] run_popen(*args, stdin: stdin_data, stdout: stdout, stderr: stderr) do |waiter_thread| [stdout.string, stderr.string, waiter_thread.value] end end |
#popen2(*args, &block) ⇒ Object
Yields stdin, stdout, waiter_thread into a block.
222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/net-ssh-open3.rb', line 222 def popen2(*args, &block) redirects = (args)[:redirects] local_pipes = [] stdin_inner, stdin_outer = open3_ios_for(:in, redirects, local_pipes) stdout_outer, stdout_inner = open3_ios_for(:out, redirects, local_pipes) run_popen(*args, stdin: stdin_inner, stdout: stdout_inner, block_pipes: [stdin_outer, stdout_outer], local_pipes: local_pipes, &block) end |
#popen2e(*args, &block) ⇒ Object
Yields stdin, stdout-stderr, waiter_thread into a block.
206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/net-ssh-open3.rb', line 206 def popen2e(*args, &block) redirects = (args)[:redirects] local_pipes = [] stdin_inner, stdin_outer = open3_ios_for(:in, redirects, local_pipes) stdout_outer, stdout_inner = open3_ios_for(:out, redirects, local_pipes) run_popen(*args, stdin: stdin_inner, stdout: stdout_inner, stderr: stdout_inner, block_pipes: [stdin_outer, stdout_outer], local_pipes: local_pipes, &block) end |
#popen3(*args, &block) ⇒ Object
Opens pipes to a remote process. Yields stdin, stdout, stderr, waiter_thread into a block. Will wait for a process to finish. Joining (or getting a value of) waither_thread inside a block will wait for a process right there. ‘status’ Thread-Attribute of waiter_thread holds an instance of Net::SSH::Process::Status for a remote process. Careful: don’t forget to read stderr, otherwise if your process generates too much stderr output the pipe may overload and ssh loop will get stuck writing to it.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/net-ssh-open3.rb', line 189 def popen3(*args, &block) redirects = (args)[:redirects] local_pipes = [] stdin_inner, stdin_outer = open3_ios_for(:in, redirects, local_pipes) stdout_outer, stdout_inner = open3_ios_for(:out, redirects, local_pipes) stderr_outer, stderr_inner = open3_ios_for(:err, redirects, local_pipes) run_popen(*args, stdin: stdin_inner, stdout: stdout_inner, stderr: stderr_inner, block_pipes: [stdin_outer, stdout_outer, stderr_outer], local_pipes: local_pipes, &block) end |