NAME
Sidef::Types::Glob::Pipe - Interface for creating and managing pipe handles
DESCRIPTION
The Pipe class provides an interface for working with Unix-style pipes in Sidef. Pipes allow communication between your Sidef program and an external command: data can flow from a command into your program (read mode) or from your program into a command (write mode).
A Pipe object is constructed from one or more strings:
Pipe("ls -la") # a single command string
Pipe("ls", "-la") # a command followed by its arguments
This distinction matters: when the Pipe wraps a single string, that string is handed to the shell for parsing (so shell metacharacters such as pipes, redirections and globs are interpreted). When the Pipe wraps multiple strings, the first is executed directly as a program with the rest as its arguments, bypassing the shell entirely (safer, and immune to shell-injection issues).
The command isn't actually executed until open, open_r, or open_w is called.
SYNOPSIS
# Single string: parsed and run through the shell
var pipe = Pipe("ps aux | grep sidef")
pipe.open_r(\var fh)
fh.each { |line|
say line
}
fh.close
# Multiple arguments: run directly, no shell involved
var pipe = Pipe("grep", "pattern", "file.txt")
pipe.open_r(\var fh)
fh.each { |line| say line }
fh.close
# Create a pipe for writing to a command
var pipe = Pipe("sort | uniq")
pipe.open_w(\var fh)
fh.say("banana")
fh.say("apple")
fh.say("banana")
fh.close
# Alternative: using open with an explicit mode
var pipe = Pipe("wc -l")
pipe.open('-|:utf8', \var in_fh) # read mode
# or
pipe.open('|-:utf8', \var out_fh) # write mode
INHERITS
Inherits methods from Sidef::Object::Object.
CONSTRUCTION
new
Pipe.new(command...)
Pipe(command...)
Creates a new Pipe object wrapping the given command. Accepts either a single command string (which will later be parsed by the shell) or a program name followed by its individual arguments (which will later be executed directly, without a shell).
var pipe1 = Pipe("grep 'error' /var/log/syslog")
var pipe2 = Pipe("grep", "error", "/var/log/syslog")
The command is not executed until open, open_r, or open_w is called.
Aliases: call
COMMAND INFORMATION
command
self.command
Returns the command wrapped by this Pipe object. If the Pipe was constructed from a single string, that string is returned. If it was constructed from multiple arguments, the full list of arguments is returned instead.
var pipe = Pipe("ls -la")
say pipe.command # prints: ls -la
var pipe2 = Pipe("ls", "-la", "/tmp")
say pipe2.command # prints: ls -la /tmp (as a list)
OPENING THE PIPE
open
self.open(mode)
self.open(mode, var_ref)
Opens the pipe using the given mode, executing the wrapped command as described in "DESCRIPTION". Valid modes are '-|' for read (command output flows into your program) and '|-' for write (your program's output flows into the command), optionally followed by a PerlIO layer such as ':utf8'.
If var_ref is given, the resulting Sidef::Types::Glob::FileHandle is stored into it, and open returns the process ID of the spawned command (or nil on failure). If var_ref is omitted, open returns the FileHandle directly instead (or nil on failure).
var pipe = Pipe("grep pattern file.txt")
# capture the PID, get the filehandle via var_ref
var pid = pipe.open('-|:utf8', \var fh)
fh.each { |line| say line }
fh.close
# or get the filehandle directly, ignoring the PID
var out_pipe = Pipe("sort")
var fh = out_pipe.open('|-:utf8')
fh.say("banana")
fh.close
open_r
self.open_r
self.open_r(var_ref)
Opens the pipe in read mode (equivalent to open('-|:utf8', var_ref)), allowing your program to read the command's output. As with open, passing var_ref makes this return the process ID (with the FileHandle stored into var_ref); omitting it returns the FileHandle directly.
var pipe = Pipe("ps aux | grep sidef")
pipe.open_r(\var fh)
fh.each { |line|
say "Process: #{line}"
}
fh.close
Aliases: open_read
open_w
self.open_w
self.open_w(var_ref)
Opens the pipe in write mode (equivalent to open('|-:utf8', var_ref)), allowing your program to send data to the command's standard input. As with open, passing var_ref makes this return the process ID (with the FileHandle stored into var_ref); omitting it returns the FileHandle directly.
var pipe = Pipe("mail -s 'Report' user@example.com")
pipe.open_w(\var fh)
fh.say("This is the report content.")
fh.close
Aliases: open_write
STRING REPRESENTATION
dump
self.dump
Returns a String representation of the Pipe object, showing each part of the wrapped command individually quoted, e.g. Pipe("grep", "pattern", "file.txt").
var pipe = Pipe("echo", "hello")
say pipe.dump # prints: Pipe("echo", "hello")
Aliases: to_s, to_str
LOW-LEVEL ACCESS
get_value
self.get_value
Returns the underlying command as a single space-joined string, regardless of how many arguments the Pipe was constructed with. This is a low-level accessor, mainly intended for internal use or interoperability rather than everyday scripting.
var pipe = Pipe("ls", "-la", "/tmp")
say pipe.get_value # prints: ls -la /tmp
EXAMPLES
Reading from a Pipe
# Execute a command and read its output line by line
var pipe = Pipe("find /etc -name '*.conf'")
pipe.open_r(\var fh)
var count = 0
fh.each { |line|
say line.trim
++count
}
fh.close
say "Found #{count} configuration files"
Writing to a Pipe
# Send data to a command for processing
var data = %w(zebra apple mango banana kiwi)
var pipe = Pipe("sort -r")
pipe.open_w(\var fh)
data.each { |item|
fh.say(item)
}
fh.close
Avoiding the Shell
# Pass arguments separately to skip shell parsing entirely
var pipe = Pipe("grep", "-n", "TODO", "main.sf")
pipe.open_r(\var fh)
fh.each { |line|
say line
}
fh.close
Getting the Filehandle Without a Var Reference
# open_r/open_w can return the filehandle directly
var fh = Pipe("uptime").open_r
say fh.read
fh.close
Error Handling
# Always check if pipe operations succeed
var pipe = Pipe("some-command")
try {
pipe.open_r(\var fh)
fh.each { |line| say line }
fh.close
} catch {
say "Error: #{_}"
}
SEE ALSO
Sidef::Types::Glob::File, Sidef::Types::Glob::FileHandle, Sidef::Types::Glob::Dir, Sidef::Sys::Sys
NOTES
Pipes should be closed when finished with, to avoid resource leaks and, for write pipes, to ensure buffered data is flushed to the command.
Whether shell metacharacters are interpreted depends entirely on how the Pipe was constructed: a single command string is parsed by the shell, while multiple arguments are executed directly without shell involvement.