How can I take STDIN and use it on the bash shell to set an environment variable?
Asked Answered
S

3

7

I'm trying to get better at one-liners here, this is what I have currently.

$ echo $PATH
/home/ubuntu/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

What I want to do is strip off that first chunk, so here's what I've figured out so far ---

$ echo $PATH | sed -e "s|^/[A-Za-z/]*:||"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

The last thing I want to do here is to put that back into PATH, like export PATH=[that result]

The way I've tried this was as follows, which I can't get to work ---

$ echo $PATH | sed -e "s|^/[A-Za-z/]*:||" | xargs export PATH=
xargs: export: No such file or directory

Also, BTW, separate issue that confused me was with the sed expression above, for some reason when I tried using + rather than *, it wouldn't catch the first bit. Look ---

$ echo $PATH | sed -e "s|^/[A-Za-z/]+:||" 
/home/ubuntu/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Its like the +, meaning "one or more" doesn't work as well as the "many" *.

Soffit answered 9/7, 2013 at 6:19 Comment(0)
A
12

I think the best solution for that particular problem is:

export PATH=${PATH#*:}

But that doesn't answer the question of how to use stdin to set an environment variable.

It's easy to use some process' stdout:

export PATH=$(make_new_path)

But that's not strictly speaking using stdin. The obvious solution:

make_new_path | export PATH=$(cat)

won't work because the commands to the right of the pipe are executed in a subshell, so variable settings won't stick. (If it had worked, it would have been an UUOC.)

As Gordon Davisson points out in a comment, you could simply use:

read -r PATH; export PATH

Also, it is actually not necessary to export PATH, since PATH comes pre-exported, but I left it in for the case where you want to use some other environment variable.

Ambros answered 9/7, 2013 at 7:7 Comment(5)
If he actually wanted to use STDIN of the script, rather than STDOUT of some command, the proper thing to use would be read PATH -- but that's not what's needed here at all.Townscape
@GordonDavisson: good point. I'll fix that. It's not what is needed here, but it is the title of the question.Ambros
If you wanted to be ridiculous (and incompatible with anything but bash), you could use process redirection: read PATH < <(make_new_path)Townscape
+1 I think he really meant STDOUT and wrote STDIN by mistake. You did right to answer the intent, not the question literally. It's also nice you added the read -r option.Scrope
Could also add "-s" to the read to suppress echoing.Trilogy
B
2
export PATH=$(echo "$PATH" | sed -e "s|^/[A-Za-z/]*:||")

export is a shell built-in; that's why you can't execute it directly via xargs (there isn't an executable for export). This runs your edit script and sets the value as the new value of $PATH. As written with double quotes around $PATH, it works even there are multiple adjacent spaces in an element of your PATH (fairly unlikely, but no harm in making sure it works properly).

Bennie answered 9/7, 2013 at 6:29 Comment(3)
echo $var and echo "$var" are the same. You don't need those quotes. Also, z=$(echo a b) is the same as z="$(echo a b)" and z="$(echo "a b")".Scrope
@janos, echo "$var" is very different from echo $var -- try it yourself with var='*', or more subtly with var="two spaces" (with 2 spaces between the words). bash allows you to omit the double quotes for variable assignment.Cromwell
@glennjackman Damn, you're right! I also overlooked the "multiple adjacent spaces" bit, my bad, and thanks for the note!Scrope
S
1

This is a bit more simple and accurate:

echo "$PATH" | sed -e s/[^:]*://

The regular expression there is more accurate, it will work even if the first segment has numbers or spaces in it.

Btw, you do NOT need to export, because PATH is already exported.

The implementation of regular expressions depends on the tool. As far as I know + does not work in sed, you can do this instead:

echo "$PATH" | sed -e 's/[^:]\{1,\}://'

It seems to me that regular expressions in sed work similar to vim and different from perl.

Scrope answered 9/7, 2013 at 6:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.