1
votes

I am writing a Makefile which is supposed to work on Linux and on MacOS systems. I make use of the sed program. It turns out that BSD sed and gnu sed differ in a small but crucial detail. I cite from the man pages:

BSD:
-i extension ...

GNU:
-i[SUFFIX], --in-place[=SUFFIX]

So on the Mac I have to call

sed -i '' -e 's/foo/bar/' file.tmp

where the empty string after -i is necesary, while on the Linux machine I call

sed -i 's/foo/bar/' file.tmp

Here is the question:

Is there a safe way to distinguish between the two OS's in the Makefile?

I can of course have the user call Makefile.mac or Makefile.linux, but I would rather avoid this.

2
Feature test the sed command? Run something like sed -i ext 's///' <<<input and see if it succeeds or errors? That should succeed with bsd sed and fail on GNU sed I believe.Etan Reisner

2 Answers

3
votes

The safe way is to not use the -i option of sed. This option is an unportable extension and is not part of POSIX.

2
votes

You can avoid using the -i at all by using code like this:

sed 's/foo/bar/' file > tmp && mv tmp file

It will then write data to a tmp file > tmp
If no error occurs && move tmp file back to original file

You will get a temp file for some short time.
I am not sure if this will be slower than the -i option.