Quite often, the script I want to execute is not located in my current working directory and I don't really want to leave it.
Is it a good practice to run scripts (BASH, Perl etc.) from another directory? Will they usually find all the stuff they need to run properly?
If so, what is the best way to run a "distant" script? Is it
. /path/to/scriptor
sh /path/to/scriptand how to use sudo in such cases? This, for example, doesn't work:
sudo . /path/to/script 1 10 Answers
sh /path/to/script will spawn a new shell and run she script independent of your current shell. The source (.) command will call all the commands in the script in the current shell. If the script happens to call exit for example, then you'll lose the current shell. Because of this it is usually safer to call scripts in a separate shell with sh or to execute them as binaries using either the full (starting with /) or relative path (./). If called as binaries, they will be executed with the specified interpreter (#!/bin/bash, for example).
As for knowing whether or not a script will find the files it needs, there is no good answer, other than looking at the script to see what it does. As an option, you could always go to the script's folder in a sub-process without leaving your current folder:
(cd /wherever/ ; sh script.sh) 4 You can definitely do that (with the adjustments the others mentioned like sudo sh /pathto/script.sh or ./script.sh). However, I do one of a few things to run them system wide to not worry about dirs and save me useless extra typing.
1) Symlink to /usr/bin
ln -s /home/username/Scripts/name.sh /usr/bin/name(be sure there is no overlapping name there, because you would obviously override it.) This also lets me keep them in my development folders so I can adjust as necessary.
2) Add the Scripts dir to your path (using .bash_profile - or whatever.profile you have on your shell)
PATH=/path/to/scripts/:$PATH
3) Create Alias's in the .bash_profile in ~/.bash_profile add something like:
alias l="ls -l"As you can tell, the syntax is just alias, digits you want to act as a command, the command. So typing "l" anywhere in the terminal would result in ls -l If you want sudo, just alias sl="sudo ls -l" to note to yourself l vs sl (as a useless example).
Either way, you can just type sudo nameofscript and be on your way. No need to mess with ./ or . or sh, etc. Just mark them as executable first :D
I usually do like you say
sh /path/to/scriptAnd to run it as root/superuser
sudo sh /path/to/scriptYour current directory only matters if the scripts assumes you are in the same folder as it. I would assume most scripts don't do this and you are save to run it like above.
2I usually keep my scripts in /usr/local/bin or /usr/local/sbin/ (if the script needs root privileges) where, according to the Filesystem Hierarchy Standard (FHS), they belong.
All you have to do is to make sure these two directories are added to your PATH. You can do this by editing your $HOME/.bashrc file and adding this line:
export PATH=$PATH:/usr/local/sbin:/usr/local/binIf you want to be able to execute a script as root via sudo, you have to add these directories to the variable secure_path in your /etc/sudoers.
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"Editing this file is done by running visudo which ensures you don't have any mistakes.
I'm not sure it works like this in linux, assuming it doesn't if no-ones suggested it. But instead of using ././ to go back directories. Can you use quotes to give it an absolute path? Maybe it doesn't give you access to the whole drive to even be able to do that actually come to think of it.
If you have scripts lying around that you need to run often, and they depend on their location for finding resources you can easily do this by just combining commands in an alias like this.
alias run-script="cd /home/user/path/to/script/ && bash script.sh"This way you don't have to alter anything else to make it work.
Not sure why no one has suggested this one, but it's super easy! I've Googled a few times and couldn't find this exact answer I'm giving so I'd thought I'd share. IMO, this but the best solution, also the easiest one, for me anyway, however others may feel and do things differently.
# Place this somewhere in your .bashrc/.bash_profile/etc and edit as you see fit
YOURCOMMAND () { cd /path/to/directory/containing/your/script/ && ./YOURSCRIPT
}First the 'cd' command telling it the directory of the scripts location. Then '&&' so that you can tie it after excuting the next command. Finally open your script just as you would would execute it within terminal! Saved your in your BASH file and takes 5 seconds to setup.
Hope this helped someone.
Say you want to run ./script and the path is /home/test/stuff/
But the path you're currently in is /home/test/public_html/a/
Then you would need to do ../../stuff/./script
Which goes back 2 folders, then into into the folder there and run the script.
It's better to modify your script to use its absolute path before addressing any relative files.
Of course for scripts we can do it conveniently and flexibly by keeping the dirname of the script in a variable before-hand.
For example, change:
cat needed_fileto:
SCRIPT_PATH=$(dirname "$0")
cat "${SCRIPT_PATH}/needed_file" Ancient question, but a timeless one.
The solution I've consistently seen is to have a $HOME/bin directory and put it first in $PATH (via ~/.bashrc if it isn't already there; on some systems ~/bin is first in $PATH by default). Dropping scripts in there for execution or symlinks to scripts/executables elsewhere is the simple way to deal with path issues that shouldn't affect the system or other users.
If a script requires additional resources that can be found relative to its own location (not uncommon) then the envvar $BASH_SOURCE is used. $BASH_SOURCE always contains the absolute path to the currently running script itself, regardless the value of $PWD.
Consider the following:
ceverett@burrito:~$ echo $PATH
/home/ceverett/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/gamesSo we can see that $HOME/bin is first in $PATH, so whatever I put in ~/bin will run. I have a demonstration script called ~/bin/findme:
#!/bin/bash
echo "Running from $BASH_SOURCE"This can be used to get the absolute path to the running script's location.
ceverett@burrito:~$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~$ cd foo
ceverett@burrito:~/foo$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~/foo$ cd /
ceverett@burrito:/$ findme
Running from /home/ceverett/bin/findme 2