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 fd,Stringto redirect to a file. Example:{ '>>' => '/tmp/log', err: 1 }translates to
'>>/tmp/log 2>&1' -
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 -
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 156 |
# File 'lib/net-ssh-open3.rb', line 146 def capture2(*args) stdout = StringIO.new stdin_data = args.last[:stdin_data] if Hash === args.last run_popen(*args, stdin: stdin_data, stdout: stdout, block_pipes: [stdout]) do |stdout, 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]
159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/net-ssh-open3.rb', line 159 def capture2e(*args) stdout = StringIO.new stdin_data = args.last[:stdin_data] if Hash === args.last run_popen(*args, stdin: stdin_data, stdout: stdout, stderr: stdout, block_pipes: [stdout]) do |stdout, 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]
173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/net-ssh-open3.rb', line 173 def capture3(*args) stdout, stderr = StringIO.new, StringIO.new stdin_data = args.last[:stdin_data] if Hash === args.last run_popen(*args, stdin: stdin_data, stdout: stdout, stderr: stderr, block_pipes: [stdout, stderr]) do |stdout, stderr, waiter_thread| [stdout.string, stderr.string, waiter_thread.value] end end |
#popen2(*args, &block) ⇒ Object
Yields stdin, stdout, waiter_thread into a block.
219 220 221 222 223 224 225 226 227 228 |
# File 'lib/net-ssh-open3.rb', line 219 def popen2(*args, &block) stdin_inner, stdin_outer = IO.pipe stdout_outer, stdout_inner = IO.pipe run_popen(*args, stdin: stdin_inner, stdout: stdout_inner, block_pipes: [stdin_outer, stdout_outer], &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 |
# File 'lib/net-ssh-open3.rb', line 206 def popen2e(*args, &block) stdin_inner, stdin_outer = IO.pipe stdout_outer, stdout_inner = IO.pipe run_popen(*args, stdin: stdin_inner, stdout: stdout_inner, stderr: stdout_inner, block_pipes: [stdin_outer, stdout_outer], &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.
192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/net-ssh-open3.rb', line 192 def popen3(*args, &block) stdin_inner, stdin_outer = IO.pipe stdout_outer, stdout_inner = IO.pipe stderr_outer, stderr_inner = IO.pipe run_popen(*args, stdin: stdin_inner, stdout: stdout_inner, stderr: stderr_inner, block_pipes: [stdin_outer, stdout_outer, stderr_outer], &block) end |