4

I've been trying to update my PATH variable permanently by putting it in my .bashrc file. However, I don't want to just append it to the file, but rather replace the current PATH=........ with the PATH variable I have for the session. Here's what I have so far:

sed 's/^PATH=.*/${PATH=$PATH}/' .bashrc > .bashrc

This is a hodpodge of commands I've seen on the web, and when I run this, the .bashrc PATH line is overwritten with nothing. I would appreciate a solution using sed, because I want to add to the knowledge of sed I've gained in the last hour, rather than abadoning my efforts to awk or something else.

1 Answer 1

4

First thing: don't write to a file you're reading from, you're likely to end up erasing it. Use the inplace-edit feature (-i) instead.

Next, inside hard quotes ('), variable substitution doesn't operate, so you'll need to do something else to get the expanded $PATH substituted in there.

Lastly, $PATH is very likely to contain / characters, which would break the substitution syntax for sed, so you'll need to use another separator.

Assuming your paths never contain ;s, try (after having backed-up your current file of course):

sed -i 's;^PATH=.*;PATH='"$PATH"';' .bashrc

The match part of the substitution means: match a string that starts with (^) the string PATH= and followed by any character (.) any number of times (*). I.e. it will match lines that start with PATH= completely, but not lines that have PATH= somewhere in the middle. The .* is important because you want to replace the whole line (try without it to see what happens).

The quoting to get $PATH substituted inside the replacement is necessary to account for cases where $PATH would contain whitespace characters.

Demo:

$ foo=bar
$ echo hello | sed -e 's/hello/$foo/'
$foo

Env. vars are not substituted inside hard quotes. So you get a literal $foo there. Now let the shell expand it by bringing it out of the hard quotes:

$ foo=bar
$ echo hello | sed -e 's/hello/'$foo'/'
bar

Ok! But this isn't safe:

$ foo="bar baz"
$ echo hello | sed -e 's/hello/'$foo'/'
sed: -e expression #1, char 11: unterminated `s' command

sed received two arguments after -e above: s/hello/bar and baz/, separately. Not good. To fix that, you need a bit more quotes:

$ foo="bar baz"
$ echo hello | sed -e 's/hello/'"$foo"'/'
bar baz

Putting an environment variable inside " quotes is something you should pretty much always do when you're passing it as an argument to something else, otherwise (assuming $IFS hasn't been changed) it will get split on whitespace.

6
  • Thank you! This worked exactly like it was planned! If you don't mind, I have some questions about the syntax: 1. Why is the ^ necessary? 2. Why must there be ' and " around $PATH?
    – Zchpyvr
    Sep 2, 2012 at 16:28
  • @Zchpyvr: added a few explanations & examples. Tell me if that doesn't clear it up.
    – Mat
    Sep 2, 2012 at 16:46
  • That was really helpful, I understand the need for that syntax now! Your edit is a great explanation, and I want to thank you for taking time to explain it to me :)
    – Zchpyvr
    Sep 2, 2012 at 16:52
  • Does this treat the case when the environment variable (e.g. ` $PYTHONPATH` ) is not present in ` .bachrc` , but should be defined?
    – Dr_Zaszuś
    Jul 6, 2020 at 16:20
  • 1
    @Dr_Zaszuś: no this won't add lines to the file
    – Mat
    Jul 6, 2020 at 17:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .