LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Simple PATH script (https://www.linuxquestions.org/questions/linux-newbie-8/simple-path-script-412202/)

Camino 02-06-2006 07:59 AM

Simple PATH script [solved]
 
Hi guys,

I really couldn't expect such amazing problems with making a simple script
that adds a path to, well.. PATH

PATH=$PATH:/addapathhere works in shell of course,
but if I want to make a script to do this, it always fails miserably.

I have also tried with:
export PATH
and whatnot in the script, but nothing seems to help.
echoing PATH in the script before shows that I can read all the PATH
variables within the script, and an echo afterwards shows that I have
added my path to PATH. However, this PATH variable seems to remain
"local" within the script, no matter what I do.

So.. what should I do? :/

also, I'd like to know what
#!/bin/bash
or
#!/bin/sh
means in the beginning of a script (what exactly is the purpose, that is..)

magic_ghost 02-06-2006 08:39 AM

to make an environment variable last even after the shell has been closed you need to edit the PATH string in the .bash-config file located in the home/<user> folder.

do a search on google for the correct name of the bash configuration file, I forget what its called.

muha 02-06-2006 08:48 AM

if you want to try it that way: look in .bash_profile
That will probably point you to .bashrc
To add a line with your path (dir = ~/tmp) command (from the commandline or a script)
Code:

echo "export PATH=$PATH:~/tmp" >> ~/.bashrc
To get konsole to reload the ~/.bashrc:
Code:

. ~/.bashrc
First time i tried this i it will not be the way to do it, but it works over here :)

Short script for it:
Code:

#!/bin/bash
# to add a directory to your path to load scripts from it

# see what's already in PATH
echo "------------------------------------------------"
echo $PATH
# see what's already in ~/.bashrc
echo "------------------------------------------------"
tail ~/.bashrc

# to do it to your profile (save a backup of ~/.bashrc first)
echo "export PATH=$PATH:~/tmp" >> ~/.bashrc

# get konsole to reload ~/.bashrc
. ~/.bashrc

# see if it worked
echo "------------------------------------------------"
tail ~/.bashrc
echo "------------------------------------------------"
echo $PATH


Camino 02-06-2006 09:21 AM

Magic_Ghost: I don't want to make the variable last after the shell has been closed.
I wouldn't write a script for that.

Also, Slackware does not use .bash-files (atleast not in the Home-dirs)

Hobbletoe 02-06-2006 10:06 AM

Try sourcing the file when you run it ...
 
Maybe you need to source the file to get it to run as you are expecting. To do that, you can

Code:

source run_file
or

Code:

. run_file
Doing so would append to your PATH just as you want, and keep it around, and not local.

And the #!/bin/bash tells the operating system what program everything is to go through. You might write a script for bash, but someone else might run under a different shell (ksh, csh, zsh, ...) and so some of the commands might not run as you would expect, causing problems. With the #!/bin/bash statement at the front, the script should work just as you would expect on any system, because everything would be done in bash regardless of the underlying shell that the script was run from ... assuming of course bash is installed on that system.

wpn146 02-06-2006 12:09 PM

Quote:

Originally Posted by Camino
Hi guys,

I really couldn't expect such amazing problems with making a simple script
that adds a path to, well.. PATH

PATH=$PATH:/addapathhere works in shell of course,
but if I want to make a script to do this, it always fails miserably.

I have also tried with:
export PATH
and whatnot in the script, but nothing seems to help.
echoing PATH in the script before shows that I can read all the PATH
variables within the script, and an echo afterwards shows that I have
added my path to PATH. However, this PATH variable seems to remain
"local" within the script, no matter what I do.

So.. what should I do? :/

First, if this is just a simple matter of setting up a path, use the suggestions made earlier. If you really have the need to do more complex work inside of a script, there is a trick to doing this. Write the script in such a way that after the correct PATH is determined, it prints to standard output the image of the command which sets this path. Then to use this script, execute it either with backticks around it, or inside of the parentheses of a "$( ... )" command. Here is a trivial example. (If your need is this easy, you don't need to do it this way!!!)

The script (let's say it is named setMyPath.sh):
Code:

#!/bin/bash
echo "export PATH=/usr/local/bin;/bin;/usr/bin;$HOME/bin;/usr/local/some_strange_application/bin"

Execute:
Code:

`setMyPath.sh`
  --or--
$(setMyPath.sh)

Quote:

also, I'd like to know what
#!/bin/bash
or
#!/bin/sh
means in the beginning of a script (what exactly is the purpose, that is..)
This is called a "bang line". When you execute a script (it must have execute permission -- see "chmod") this specifies exactly WHAT executes the script.

By the way, '#!/bin/bash' is pronounced "hash bang slash bin slash bash'. Sounds very violent. Don't yell it in an airport.

Camino 02-07-2006 03:13 AM

Quote:

Originally Posted by wpn146
First, if this is just a simple matter of setting up a path, use the suggestions made earlier. If you really have the need to do more complex work inside of a script, there is a trick to doing this.

I do need this, as I quickly need to set up different environments depending on my development needs. There's a bunch of different enviromental variables that I need to set. PATH is just a part of it and as an example.

Quote:

Write the script in such a way that after the correct PATH is determined, it prints to standard output the image of the command which sets this path. Then to use this script, execute it either with backticks around it, or inside of the parentheses of a "$( ... )" command. Here is a trivial example. (If your need is this easy, you don't need to do it this way!!!)

The script (let's say it is named setMyPath.sh):
Code:

#!/bin/bash
echo "export PATH=/usr/local/bin;/bin;/usr/bin;$HOME/bin;/usr/local/some_strange_application/bin"


Shouldn't all those be colons?
Anyway, I've tried to following:
Code:

echo $PATH
PATH=$PATH:/whatever/bin
echo $PATH
export PATH

And the result is that the first echo tells that I sure have the PATH (but probably local).
Second line adds the path, second echo confirms it..
Then exporting the PATH.
But reading the PATH after running the script, the addition to the PATH does not exist.
I didn't really understand the `blah.sh` and $(blah.sh).. Running those in the shell just prints out the PATH and "No such file or directory". Even if my blah.sh is in, say /usr/bin/ , with mode set to executable..

Also, I tried your
Code:

#!/bin/bash
echo "export PATH=$PATH:/some_strange_application/bin"

And the result was exactly the same.

This is starting to get really really ridiculous :(

timmeke 02-07-2006 05:41 AM

Indeed, elements in $PATH are separated with colons (:), not semicolons (;).
Semicolons terminate a command, so executing
export PATH=/some/path;/some/other/path;/third/path;
will actually run the 3 following commands:
export PATH=/some/path; #this effectively changes $PATH
/some/other/path
/third/path
If the latter 2 are directories (not executable programs), then you'll get shell errors about unknown commands or alike.

Secondly, I'd like to explain a bit of what is going on internally. Each program, when it is started, inherits the environement variables (including $PATH) of the shell/program that it was launched from (called the parent). In your case, you want to run a shell script, so your shell script will inherid $PATH from the shell you call it from - in your case, your command line (terminal). The program can then proceed to use, change or disregard the environment, in any way it likes, but the bottom line is that the environment is "stored" in a memory structure for each program that runs (called a "process"). When a program "inherits" the environment from it's parent shell/program, the environment information from the parent's memory structure is simply copied to that of the program itself. So, when the program stops, it's memory structures get cleaned up, so any changes it has done to it's own environment are thrown away.
Hence, if your script changes $PATH, it does so in it's own environment, which can only impact your script itself and any programs launched from that script. When your script finishes or stops, it's environment is thrown away, so the parent will never get to see the changes to the environment that were done by the script.

To make a long story short:
your command line (terminal) shell => has it's own copy of $PATH
you call your script => $PATH is copied to the script's environment (in memory)
your script modifies it's own copy of $PATH and can execute any programs/commands that will all see this modified $PATH
when your script is finished, it's memory structures are thrown away, so the modified $PATH is lost
your command line shell is still left with it's own, unaltered copy of $PATH

So, if you want to write a script that you can call to change $PATH, you can't. The only way you can perform this, is by "sourcing" the script instead of calling it.
Think of "sourcing" as including the script's contents in yours (like a #include statement in C, if you know that).

So, let's assume that you have this script:
addPath.sh
which contains:
#!/bin/bash
export PATH=$PATH:/some/added/path

Instead of simply calling
addPath.sh
which would have no effect on your $PATH, since only addPath.sh's $PATH would get changed,
you'll need to "source" addPath.sh, either via
source addPath.sh
or
. addPath.sh
This works as if it copied the "export" command from addPath.sh into your script, so it will actually execute the "export" as if it was written in your script. The only advantage here is that you can "source" the addPath.sh script in as many of your scripts as you want (it's re-usable).

If you don't want this hassle, but instead want to always add a certain path to your $PATH, you could put it in /home/you/.bashrc, /home/you/.kshrc, /home/you/.cshrc (depending on the shell you're using), or in /home/you/.profile (applies to all shells).
Or, if you want to apply it for all users (not just you), you could even put it in
/etc/profile (all shells)
/etc/bashrc (only bash)
/etc/kshrc (only ksh)
etc.
Note that in some cases, underscores can be used in the names of these files.
Note also that you probably need to have root user access in order for you to change the files in /etc.

Camino 02-07-2006 06:03 AM

Timmeke:
Ah, thank you very much. Finally it works :)

Yes, you could have spared a lot of trouble explaining the local variables, as I infact did point out that I thought 'export' would actually export the local variable to "global"..
I mainly wrote the example so that the people who are unsure what I'm talking about, could see my problem.

Anyway, 'sourcing' works exactly as I'd like it to, so I'm a happy camper :)

Many thanks to you!

/Camino


All times are GMT -5. The time now is 08:51 PM.