I have some functional scripts and I want to copy to /usr/bin
I want to use them as normal terminal commands. Is it a good practice to use them with the .sh
extension or can I save them without extension?
4 Answers
No, it is not a good practice, you should keep your scripts without extension. Note, that scripts being part of packages doesn't have a .sh extension, i.e. update-grub, not update-grub.sh. If you are still not convinced, then be advised, that Google Shell Style Guide says:
Executables should have no extension (strongly preferred) or a .sh extension. Libraries must have a .sh extension and should not be executable.
PS You don't have to put your script into /bin
. You can create directory ~/bin
and put your script there. Directory ~/bin
is included in $PATH
by default, so scripts put there can be run as any other shell command.
-
5"Directory ~/bin is included in
$PATH
by default" - Since when? Anyway,~/.local/bin
is probably a better choice as it's a standard. Jul 27, 2014 at 11:07 -
7@KeithWolters first, not me, but Google. Second, .sh, not .so, we are talking about shell scripts, not binaries.– user280493Jul 27, 2014 at 14:00
-
5The Google style guide is very specific to Google. For example, "Bash is the only shell scripting language permitted for executables." Clearly an internal rule rather than best practices. Dec 8, 2014 at 8:33
-
2@nyuszika7h check out ~/.profile... it inserts $HOME/bin into your path if the directory exists Feb 24, 2016 at 1:31
-
2@BobStein See talisman.org/~erlkonig/documents/…, and the history of freenode #bash channel factoids on the topic at wooledge.org/~greybot/meta/.sh Mar 26, 2020 at 1:26
I second the recommendation to use ~/bin
which gets automatically added to your $PATH
,as Sergey said. Or /usr/local/bin
, which may already be on the PATH
.
However:
- You are doing this for yourself. Use whatever you feel comfortable with. Indeed, I'd say keep the extension so that you'll be reminded it's your script you are running, since -
Extensions are uncommon in
/usr/bin
. In my system, I can find only two:$ dpkg -S `ls /usr/bin/*.sh` mtools: /usr/bin/amuFormat.sh gettext-base: /usr/bin/gettext.sh
So if you are packaging, definitely leave out the extension.
-
2
~/bin
is added to the$PATH
automatically if it exists, no need to add it manually. Just create the directory, log out and log back in.– SergeyJul 29, 2014 at 21:03
Just put following line at top of file:
#!/bin/bash
So-that file will be automatically type : Shell Script without any extension!
Remember to give execution permission to file.
For putting script so-that can be run by direct command, visit: Where should I put my script so that I can run it by a direct command?
-
2
-
-
1@MaxCoplan, when started under the name
sh
, bash turns off many of its features. They're thus not identical even when linked. Mar 26, 2020 at 1:30 -
@CharlesDuffy that is definitely true. I was but a young and naive fool when I wrote this :) Mar 26, 2020 at 13:18
Your scripts and the commands that run them don't need to have the same name
I agree with the opinions and advice in other answers here, in that typed commands shouldn't have an extension (mycmd
, not mycmd.sh
), and that editors should be able to identify the file contents from the shebang line (e.g. #!/bin/bash
).
However, if the scripts are part of a larger project, I find it useful to have file name extensions on them to remind myself whether the files in the repo are editable (e.g. scripts, source code), or compiled binary files.
To achieve both aims, you can symlink your scripts from the directory on your PATH. E.g. if ~/.local/bin
is on your PATH:
cd ~/.local/bin
ln -s ../../path/to/code/project/src/mycmd.sh mycmd
# now mycmd is on the PATH, and calling mycmd runs the script mycmd.sh
cd somewhere/else
mycmd
This also allows you to do version control from ~/path/to/code/project/
, without then having to copy the files into a directory on your PATH when you do a "release".
/usr/local/bin
may be a better choice./usr/bin
and/usr/local/bin
should both be available to all users, but/usr/local/bin
is better for executables that are not part of packages.#!/usr/bin/env bash
or#!/bin/bash
.