sed -i empty argument compatibility issue

Kyle Evans kevans at freebsd.org
Sat Mar 6 05:43:05 UTC 2021


Ie On Fri, Mar 5, 2021 at 11:30 PM Gary Aitken <freebsd at dreamchaser.org> wrote:
>
> On 3/5/21 10:15 PM, Kyle Evans wrote:
> > On Fri, Mar 5, 2021 at 11:12 PM Gary Aitken <freebsd at dreamchaser.org> wrote:
> >>
> >> On 3/5/21 9:39 PM, Kyle Evans wrote:
> >>> On Fri, Mar 5, 2021 at 3:03 PM Gary Aitken <freebsd at dreamchaser.org> wrote:
> >>>>
> >>>> I'm trying to come up with a fix for a script in a port which invokes sed.
> >>>> The port comes from a linux environment, and the offending line looks like this:
> >>>> (This is in a cMake file.)
> >>>>
> >>>> COMMAND sed -i "/^# /d" "${outfile}"
> >>>>
> >>>> The issue is that linux sed expects the -I or -i extension modifier to
> >>>> immediately follow the -i.  In the above line, the extension is deliberately
> >>>> missing to provide in-place editing.
> >>>>
> >>>> fbsd expects the extension to be separated from the -i by whitespace, or
> >>>> doesn't work properly when it is empty or immediately follows the -i:
> >>>>
> >>>> $ !ls
> >>>> ls -lt temp.tmp*
> >>>> -rw-------  1 garya  garya  86 Mar  5 13:15 temp.tmp
> >>>> -rw-------  1 garya  garya  86 Mar  5 13:15 temp.tmp_org
> >>>> $ sed -ifoo "/^# /d" temp.tmp  (works on both fbsd & linux))
> >>>> $ !ls
> >>>> ls -lt temp.tmp*
> >>>> -rw-------  1 garya  garya  30 Mar  5 13:48 temp.tmp
> >>>> -rw-------  1 garya  garya  86 Mar  5 13:15 temp.tmp_org
> >>>> -rw-------  1 garya  garya  86 Mar  5 13:15 temp.tmpfoo
> >>>> $ cp -p temp.tmp_org temp.tmp
> >>>> $ sed -i"" "/^# /d" temp.tmp   (works on linux but not fbsd)
> >>>> sed: 1: "temp.tmp": undefined label 'emp.tmp'
> >>>> $ sed -i "" "/^# /d" temp.tmp  (works on fbsd but not linux)
> >>>> $ !ls
> >>>> ls -lt temp.tmp*
> >>>> -rw-------  1 garya  garya  30 Mar  5 13:49 temp.tmp
> >>>> -rw-------  1 garya  garya  86 Mar  5 13:15 temp.tmp_org
> >>>> -rw-------  1 garya  garya  86 Mar  5 13:15 temp.tmpfoo
> >>>>
> >>>> So fbsd works with '-i ""' but linux requires '-i""'
> >>>>
> >>>> Does anyone know a work-around for this problem?
> >>>>
> >>>
> >>> My personal favorite trick to bridge the gap here was, as I recall:
> >>>
> >>> sed -i'' '' 's/../.../' ${file}
> >>>
> >>> IIRC those sed's with an optional backup suffix (Linux, OpenBSD) will
> >>> accept the immediately following empty string and accept the next
> >>> empty word as an empty command, while our getopt will effectively
> >>> ignore the rest of the -i word and use the following optarg as usual.
> >>
> >> Unfortunately, times appear to have changed, at least on ubuntu-18.04:
> >>
> >> $ sed -i'' '' "/^# /d" temp.tmp
> >> sed: can't read /^# /d: No such file or directory
> >>
> >
> > Oh, sorry. Try slapping with an -e:
> >
> > $ sed -i'' '' -e "/^# /d" temp.tmp
>
> nope:
>
> $ sed -i'' '' -e "/^# /d" temp.tmp
> sed: can't read : No such file or directory
> $ !ls
> ls -lt temp.tmp*
> -rw-rw-r-- 1 garya garya 86 Mar  6 05:29 temp.tmp
> -rw-rw-r-- 1 garya garya 86 Mar  5 20:45 temp.tmp_org
>
> Gary

Bah, ok, sorry for the noise- I thought I remembered there being some
odd invocation that can be done to make it work out, but I clearly
don't recall what that is now and trying to search my inbox for 'sed'
is a total disaster.

Is this used only at build-time, or at runtime? The former can just
pull in gsed as a BUILD_DEPENDS and use a BINARY_ALIAS to stash it
first. Autoconfig takes some more work;
ac_cv_path_SED=${LOCALBASE}/bin/gsed instead, maybe. At runtime, your
best option is to patch the script to use gsed and slap a RUN_DEPENDS
on that bad boy.

I've wanted to make our -i arg optional for a long time to match
OpenBSD/Linux, but that's a POLA violation too far even for me to
pursue.

Thanks,

Kyle Evans


More information about the freebsd-questions mailing list