sed argument processing b0rked?

Matthew Pounsett matt at conundrum.com
Tue Jun 21 15:16:58 UTC 2011


I'm running into a weird problem with sed.  I believe what I'm trying to do should work fine, but seem to be stymied by weirdness in sed's argument processing.  This is on 8.2-RELEASE-p2.

> which sed
/usr/bin/sed

According to years of experience and re-reading the man page five times today this should work, however sed is treating the second -e as a file name:

> sed -i'' -e 's/^\(REVOKE ALL ON SCHEMA public FROM \)postgres/\1pgsql/' \
?          -e 's/^\(GRANT ALL ON SCHEMA public TO \)postgres/\1pgsql/'    \
?          /tmp/pgdump
sed: -e: No such file or directory

If I drop the second -e it seems to work (the permission denied is expected):

> sed -i'' -e 's/^\(REVOKE ALL ON SCHEMA public FROM \)postgres/\1pgsql/' \
?          /tmp/pgdump
sed: /tmp/pgdump: Permission denied

This is contrary to the sed man page:

     A single command may be specified as the first argument to sed.  Multiple
     commands may be specified by using the -e or -f options.  All commands
     are applied to the input in the order they are specified regardless of
     their origin.

I thought maybe it was an argument order problem, since -i is listed after -e in the syntax synopsis (sometimes that matters) but that is actually even weirder:

sed -e 's/^\(REVOKE ALL ON SCHEMA public FROM \)postgres/\1pgsql/' \
    -e 's/^\(GRANT ALL ON SCHEMA public TO \)postgres/\1pgsql/'    \    
    -i'' /tmp/pgdump
sed: -I or -i may not be used with stdin

Fiddling around some more, I found that -e can't be supplied for the first command if there are multiple commands to be given.. but it does work if there's only one.  That doesn't seem right.

sed -i'' 's/^\(REVOKE ALL ON SCHEMA public FROM \)postgres/\1pgsql/' \
         -e 's/^\(GRANT ALL ON SCHEMA public TO \)postgres/\1pgsql/'    \
         /tmp/pgdump
sed: /tmp/pgdump: Permission denied

However, that breaks again if -i is moved:

> sed 's/^\(REVOKE ALL ON SCHEMA public FROM \)postgres/\1pgsql/' \
       -e 's/^\(GRANT ALL ON SCHEMA public TO \)postgres/\1pgsql/' \
       -i'' /tmp/pgdump
sed: -e: No such file or directory
sed: s/^\(GRANT ALL ON SCHEMA public TO \)postgres/\1pgsql/: No such file or directory
sed: -i: No such file or directory
sed: /tmp/pgdump: Permission denied

I'm fairly certain this has worked the way I'm expecting it to in the past.  After all, I wrote it this way out of habit.  Either way, it seems to me that argument processing in the current sed distributed with the OS is broken with respect to the way it's documented.  Or am I missing something?




More information about the freebsd-questions mailing list