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
    Commented Sep 2, 2012 at 16:28
  • @Zchpyvr: added a few explanations & examples. Tell me if that doesn't clear it up.
    – Mat
    Commented 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
    Commented 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ś
    Commented Jul 6, 2020 at 16:20
  • 1
    @Dr_Zaszuś: no this won't add lines to the file
    – Mat
    Commented Jul 6, 2020 at 17:07

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.