Running scripts from another directory

129,930

Solution 1

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)

Solution 2

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

Solution 3

I usually do like you say

sh /path/to/script

And to run it as root/superuser

sudo sh /path/to/script

Your 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.

Solution 4

I 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/bin

If 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.

Share:
129,930

Related videos on Youtube

Desmond Hume
Author by

Desmond Hume

Updated on September 18, 2022

Comments

  • Desmond Hume
    Desmond Hume over 1 year

    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/script
    

    or

    sh /path/to/script
    

    and how to use sudo in such cases? This, for example, doesn't work:

    sudo . /path/to/script
    
  • gniourf_gniourf
    gniourf_gniourf over 11 years
    Typo: you mean .bashrc instead of .bachrc.
  • Sergio
    Sergio over 9 years
    Why?, it's a best practice or just taste?
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' almost 6 years
    (1) While this appears to be useful information, the question didn’t ask how to write scripts that use resources relative to their own location; it asked about running scripts. (2) I’m not sure how your second paragraph addresses the question.  Are you suggesting that, if I write a script and Desmond wants to run it, he should link it into his private bin directory?  That seems cumbersome.  (3) Also, it breaks location independence.  If /home/desmond/bin/foo is a link to my script, then BASH_SOURCE will be /home/desmond/bin/foo, and the script won’t be able to find its resources.
  • zxq9
    zxq9 almost 6 years
    @G-Man (1) The user didn't provide much context. Whenever this question has been asked of me over the last 30 years it has always been in the context a user (usually a new sysop or developer) running a mix of his own and other acquired scripts to automate trivial tasks, so I answered it that way. This does assume a bit of scripting knowledge on the part of the user asking. (2) System-wide scripts are usually installed in /bin or a known location in /opt. (3) Location independence is exactly what this preserves when writing an inter-dependent collection of personal scripts.
  • G-Man Says 'Reinstate Monica'
    G-Man Says 'Reinstate Monica' almost 6 years
    Do you mean (cd /wherever/ ; sh script.sh)?  Why do you have a $ in front?
  • scottlittle
    scottlittle about 4 years
    this seems like the most straightforward method. also, perl /path/to/script for perl scripts (since he mentioned perl).
  • mskfisher
    mskfisher over 3 years
    I'd guess the $ is intended to be the command prompt?
  • Ярослав Рахматуллин
    Ярослав Рахматуллин over 3 years
    The $ or # is a "common" convention to indicate the prompt. It's also a way to prevent lusers from copy-pasting something dumb, maybe.
  • James
    James over 2 years
    The $ to prevent users copy/pasting something dumb is more of an annoyance to the people trying to double click to get the command than it saves dumb people. They'll just remove the "$" anyway. Also, isn't giving them the command the whole point in the first place? Sure if the command is delete 10000 dirs etc