3

I try to change Apache configuration with this:

sudo awk '/<Directory \/var\/www\/>/,/AllowOverride None/{sub("None", "All",$0)}{print}' /etc/apache2/apache2.conf | sudo tee /etc/apache2/apache2.conf > /dev/null

After this /etc/apache2/apache2.conf is empty. If I change the destination file to ~/apache2.conf for example, the output is correct.

Why?

MikkoP
  • 175
  • 2
  • 8
  • What does `awk '//,/AllowOverride None/{sub("None", "All",$0)}{print}' /etc/apache2/apache2.conf` output? You do not need sudo before `awk`. – Pilot6 Aug 20 '15 at 12:29
  • @Pilot6 It outputs the configuration file with the correct modification. – MikkoP Aug 20 '15 at 12:30
  • 5
    You are referencing the same file twice in the pipeline, `tee` will overwrite the file before `awk` gets to it. Either use a temporary file or use `sponge` from `moreutils`. If you are using a recent version of GNU awk, it has an [-i inplace argument](http://stackoverflow.com/questions/16529716/awk-save-modifications-inplace) – Thor Aug 20 '15 at 12:35
  • Thor is correct. Or use `sed -i` – Pilot6 Aug 20 '15 at 12:37
  • @Thor make it an answer please :) – Rinzwind Aug 20 '15 at 14:11
  • @Rinzwind: right :-) – Thor Aug 20 '15 at 16:51

2 Answers2

4

You are referencing the same file twice in the pipeline, tee will overwrite the file before awk gets to it. Either use a temporary file or use sponge from moreutils.

Recent versions of GNU awk, 4.1.1, have a -i inplace argument which simulates editing file in-place:

Thor
  • 3,513
  • 25
  • 27
  • Another (uglier) way to do this, in case someone can't use `sponge` for any reason is to redirect the processed file to `tee` using a command substitution: `<<<"$(sudo awk '//,/AllowOverride None/{sub("None", "All",$0)}{print}' /etc/apache2/apache2.conf) sudo tee /etc/apache2/apache2.conf > /dev/null"`. This way the file is read before getting truncated by `tee` (although a trailing newline in the original file will be "eat" by to the command substitution). – kos Aug 20 '15 at 19:03
1

That your awk/tee adventure does not work reliably, which has already been said here. ;)

You could try another way:

drum-roll

Use the power of perl!

again drum-roll

sudo perl -i.bak -0777pe 's/(<Directory \/var\/www\/>([^<].*\n)*.*AllowOverride\s)None/$1All/' /etc/apache2/apache2.conf
  • -i.bak

    in-place edit and create a backup /etc/apache2/apache2.conf.bak

  • -0777

    slurps the whole file at once


Example

Input file

cat foo

<Directory /var/www/>
    foo bar
    AllowOverride None
</Directory>


<Directory /var/www1/>
        AllowOverride None
</Directory>

The command

perl -i.bak -0777pe 's/(<Directory \/var\/www\/>([^<].*\n)*.*AllowOverride\s)None/$1All/' foo 

The content in the file after starting the command

cat foo

<Directory /var/www/>
    foo bar
    AllowOverride All
</Directory>


<Directory /var/www1/>
        AllowOverride None
</Directory>
A.B.
  • 89,123
  • 21
  • 245
  • 323