busybox sed, 'r' command

Michael Conrad mconrad at intellitree.com
Wed Mar 23 16:25:03 UTC 2016


On 3/23/2016 12:12 PM, Ralf Friedl wrote:
> Cristian Ionescu-Idbohrn wrote:
>> sed (GNU sed) 4.2.2 can do this:
>>
>>     $ printf 'foo
>>     bar
>>     baz' | sed r -
>>     foo
>>     bar
>>     baz
>>
>> or, after storing the text in a file:
>>
>>     $ printf 'foo
>>     bar
>>     baz' >/tmp/bar
>>
>>     $ sed r /tmp/bar
>>     foo
>>     bar
>>     baz
>>
>> But busybox sed can't:
>>
>>     $ printf 'foo
>>     bar
>>     baz' | busybox sed r -
>>     sed: empty filename
>>
>>     $ busybox sed r /tmp/bar
>>     sed: empty filename
>>
>>     $ printf '' | busybox sed 'r /tmp/bar'
>>     <no output, although /tmp/bar size is 11 bytes>
>>
>>     $ busybox sed 'r /tmp/bar'
>>     <waiting for stdin; ^D; no output>
>>
>> The 'r' command is documented by GNU sed as a GNU extension. Still,
>> busybox sed documents the 'r' command as supported:
>>
>>     r [address]r file
>>            Read contents of file and append after the contents of the
>>            pattern space. Exactly one space must be put between r and 
>> the
>>            filename.
>>
>> Am I misinterpreting the documentation?
> From the documentation:
> >   The full format for invoking `sed' is:
> >     sed OPTIONS... [SCRIPT] [INPUTFILE...]
> So in your example you invoce sed with the script "r" and the input 
> file "-" or "/tmp/bar". The content is not printed because it is the 
> argument to the "r" command, but because it is the main input file to 
> sed. You can avoid that by using quotes around the command and the 
> file name, or by omitting the space between the command and the filename.
> You should also try the last two examples, where you invoke busybox 
> sed with quotes, with GNU sed. The behaviour is the same.
>
> You should note that in your example when reading from a file, sed 
> didn't read from stdin, at least you don't mention it, although your 
> interpretation would mean that the filename is the argument to the "r" 
> command, therefor no argument is given to sed, and sed should read stdin.
>
> You should also not that invoking the "r" command with the filename 
> causes the content of this file to be inserted after every line. When 
> reading from a pipe, the pipe is empty after the first line.
>
> My documentation to GNU sed 4.2.2 says:
> > `r FILENAME'
> >      As a GNU extension, this command accepts two addresses.
> >
> >      Queue the contents of FILENAME to be read and inserted into the
> >      output stream at the end of the current cycle, or when the next
> >      input line is read.  Note that if FILENAME cannot be read, it is
> >      treated as if it were an empty file, without any error indication.
> >
> >      As a GNU `sed' extension, the special value `/dev/stdin' is
> >      supported for the file name, which reads the contents of the
> >      standard input.
>
> So the main difference seems to be that GNU sed doesn't give an error 
> message if the file can't be read. I'm not sure why that would be a 
> good idea.
> Also not that there is no mention of using "r -" for stdin, instead 
> /dev/stdin is mentioned.
>
> On the other hand, I don't know why busybox sed needs exactly one 
> space between command and filename. GNU sed works with zero or more 
> spaces.

It looks to me that what actually happens when running "sed r" is that 
it appends *no lines* to the end of each line read from stdin.

$ printf 'foo
bar
baz' | sed

Does not add a final newline

$ printf 'foo
bar
baz' | sed r

Does add a final newline

$ printf 'foo
bar
baz' | sed 'r /dev/null'

Does add a final newline

echo "blah" > -
$ printf 'foo
bar
baz' | sed 'r -'

results in

foo
blah
bar
blah
baz
blah

So it is not a special case for the filename.

I personally don't see much value in preserving the behavior of 
appending nothing for a file which doesn't exist.  Tools should give 
errors if they can't do what you ask them to.

-Mike C.


More information about the busybox mailing list