3

I have a bin folder with a bunch of sh files. For example "server-run.sh", "server-stop.sh", "server-do-something.sh". And I want to run file "server-stop.sh" from anywhere. I could add this bin folder to path but "run" and "do-something" files also will be available and I don't want to pollute my console. Also I don't want to add this file to /bin folder, because it could change. Maybe link. Can I somehow add only "server-stop.sh" to path?

2
  • It's worth noting that if you want to be able to run them without the .sh, just omit the .sh from the name. Extensions are meaningless to the Linux kernel, it's the hashbang (#!) that determines the program to call. Executable scripts do not usually have an extension in Linux, unlike libraries. And .sh is misleading if it's in fact a bash script. Apr 21, 2014 at 17:19
  • (However, if you want to run your scripts from a graphical file manager, they will probably not recognize extensionless scripts.) Apr 21, 2014 at 17:30

4 Answers 4

6

The best way is to add a symbolic link to this file in the /usr/local/bin directory:

cd /usr/local/bin
ln -s server-stop.sh /path/to/your/folder/server-stop.sh

In this case, you are adding a link to the original file, so you can always change the original file and you command will always be working.

1
  • 3
    You should not use /usr/bin or /bin for locally compiled programs or your own scripts, those are reserved for packages. If you want to make it globally available, use /usr/local/bin, else just use ~/.local/bin or similar. Apr 21, 2014 at 17:20
4

Creating links in /usr/bin works, but unless you want the scripts to be available for all users, I would prefer to create the links in ~/bin, with the same result, but not touching the global system. Furthermore, OP has not mentioned where the scripts are stored. creating a link globally while the scripts are stored locally is bad practice, so alltogether I would suggest:

  • Create a local directory ~/bin.
  • Remove the language extension from the scripts (unless they invoke each other), make them executable (see further below).
  • Create links to the scripts from ~/bin (ln -sf).
  • Log out and back in.

Either with or without language extension, the script would work perfectly well. However, there are some arguments to use the script without language extension:

  • For reasons of clarity, it might be preferable to name the link to the script similar to the script itself. keeping the language extension would then be less convenient when invoking the script.
  • Although a bit overdone in cases of user-written scripts, according to lintian conventions, scripts (or links to scripts) in default searchpaths should not have a language extension. -
8
  • Why are you recommending that the extensions be removed?
    – terdon
    Apr 21, 2014 at 13:34
  • @terdon for reasons of clarity; I would want to name the link similar to the script. invoking with extension would then be inconvenient, and a bit "ugly". Apr 21, 2014 at 15:47
  • OK, I like having extensions as it tells me what the script is. This is just personal preference but I prefer my scripts with extensions.
    – terdon
    Apr 21, 2014 at 15:48
  • @terdon That is of course true! It is just a script of course, and keeping the idea might be overdone, but isn't it unconventional to add language extensions in default searchpaths? Apr 21, 2014 at 15:55
  • Not at all, quite the contrary actually. The convention is to have shell scripts with .sh extension and perl scripts with .pl, python with py etc. This is often not done for tools in /usr/bin but is usually the case for user-written files.
    – terdon
    Apr 21, 2014 at 16:01
3

I would use the bash built-in command hash to remember the location of the server-stop.sh script:

hash -p /path/to/folder/server-stop.sh server-stop

Just add the above line to your .bashrc file. You can now use server-stop everywhere in your bash shell/scripts.

See help hash:

hash: hash [-lr] [-p pathname] [-dt] [name ...]
Remember or display program locations.

Determine and remember the full pathname of each command NAME.  If
no arguments are given, information about remembered commands is displayed.

Options:
  -d        forget the remembered location of each NAME
  -l        display in a format that may be reused as input
  -p pathname   use PATHNAME is the full pathname of NAME
  -r        forget all remembered locations
  -t        print the remembered location of each NAME, preceding
        each location with the corresponding NAME if multiple
        NAMEs are given
Arguments:
  NAME      Each NAME is searched for in $PATH and added to the list
        of remembered commands.
2

Perhaps an alias is what you are looking for. Open your ~/.bash_aliases file and add the following to the end of the file(the file may be empty depending upon whether you have added an alias previously):

alias server-stop.sh='/path/to/your/server-stop.sh`

Pros:

  • This will only add server-stop.sh as you intend to

  • This won't change your $PATH variable

  • Other users of your system are unaffected

Cons:

  • You will have to change the alias once you change the path where server-stop.sh is located(I don't think that will be required very frequently)

  • This will work only for bash shell, you will have to see what other shells use for alias.

1
  • Also good approach. Thanx.
    – Moses
    Apr 21, 2014 at 8:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .