Bug
The GNU e command — execute a shell command and send its output to the
pattern space or output stream — is not implemented. This is the standalone
command counterpart to the s///e substitute flag.
Reproduction
$ echo a | /usr/bin/sed 'e echo hi'
hi
a
$ echo a | ./target/release/sed 'e echo hi'
sed: <script argument 1>:1:1: error: invalid command code `e'
Pattern-space execution form:
$ echo 'echo hi' | /usr/bin/sed 'e'
hi
$ echo 'echo hi' | ./target/release/sed 'e'
sed: <script argument 1>:1:1: error: invalid command code `e'
Remember that, following the GNU documentation, the pattern space is only replaced with the bare e command.
$ echo a | /usr/bin/sed -e 'e echo hi' -e 's/hi/ho/'
hi
a
$ echo 'echo hi' | /usr/bin/sed -e e -e 's/hi/ho/'
ho
Regarding implementation, for e with arguments, rather than reading the shell command's input,
it's probably more efficient and desirable to flush the sed output and simply have the shell's output appear on the standard output.
Given the cost of invoking a shell, the cost of the flush is negligible, and, if the invoked command's output is large, the savings in CPU instructions and memory will be substantial.
Note however, that this is not how GNU sed works (notice the two write system calls):
$ echo a | strace -fe write /usr/bin/sed -e 'e echo hi' -e 's/hi/ho/' >/dev/null
strace: Process 3630943 attached
[pid 3630943] write(1, "hi\n", 3) = 3
[pid 3630943] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=3630943, si_uid=1001, si_status=0, si_utime=0, si_stime=0} ---
write(1, "hi\na\n", 5) = 5
+++ exited with 0 +++
What it should do
GNU sed manual:
e [COMMAND] This command allows one to pipe input from a shell command
into pattern space. Without parameters, the e command executes the command
that is found in pattern space and replaces the pattern space with the output;
a trailing newline is suppressed.
Behavior notes:
-
With an argument, execute that argument as a shell command and (this is the default) have stdout
appear on the output stream.
-
Without an argument, execute the current pattern space as a shell command,
replace pattern space with stdout, and suppress one trailing newline.
-
Accepts addresses like other commands.
-
Must be rejected under --sandbox.
-
Must be rejected under --posix.
Suspected place to add it
src/sed/compiler.rs — get_cmd_spec. Add an e entry with a handler
that parses the rest of the line as an optional shell command:
'e' => Ok(CommandSpec {
n_addr: 2,
handler: compile_execute_command,
}),
The execution side belongs in src/sed/processor.rs: spawn a shell
(/bin/sh -c on Unix), collect stdout, and either write it to
stdout for e COMMAND or replace pattern space for bare e.
Arrange to reuse the functionality added in b14272c.
Security note
The standalone e command is one of the commands disabled by --sandbox
along with r/w and s///e. Enforce this at compile time so the script
is rejected before any input is read.
Affected GNU testsuite tests
eval, sandbox.
Bug
The GNU
ecommand — execute a shell command and send its output to thepattern space or output stream — is not implemented. This is the standalone
command counterpart to the
s///esubstitute flag.Reproduction
Remember that, following the GNU documentation, the pattern space is only replaced with the bare
ecommand.Regarding implementation, for
ewith arguments, rather than reading the shell command's input,it's probably more efficient and desirable to flush the sed output and simply have the shell's output appear on the standard output.
Given the cost of invoking a shell, the cost of the flush is negligible, and, if the invoked command's output is large, the savings in CPU instructions and memory will be substantial.
Note however, that this is not how GNU sed works (notice the two write system calls):
What it should do
GNU sed manual:
Behavior notes:
With an argument, execute that argument as a shell command and (this is the default) have stdout
appear on the output stream.
Without an argument, execute the current pattern space as a shell command,
replace pattern space with stdout, and suppress one trailing newline.
Accepts addresses like other commands.
Must be rejected under --sandbox.
Must be rejected under --posix.
Suspected place to add it
src/sed/compiler.rs — get_cmd_spec. Add an e entry with a handler
that parses the rest of the line as an optional shell command:
'e' => Ok(CommandSpec {
n_addr: 2,
handler: compile_execute_command,
}),
The execution side belongs in src/sed/processor.rs: spawn a shell
(/bin/sh -c on Unix), collect stdout, and either write it to
stdout for e COMMAND or replace pattern space for bare e.
Arrange to reuse the functionality added in b14272c.
Security note
The standalone e command is one of the commands disabled by --sandbox
along with r/w and s///e. Enforce this at compile time so the script
is rejected before any input is read.
Affected GNU testsuite tests
eval, sandbox.