• Important: We recently upgraded our forum software - please let us know if you run into any issues.

Clear steps to make an .sh file executable

Jamesd1

New Member
I've spent a half hour Googling about making an .sh executable but not found anything that works in my system. I'm trying to install/run/make executable the script at this link for saving/restoring desktop icon positions:

http://www.chateaumezcal.com/software/desktop_maven.htm

I'm to the part about double clicking after which I get the "Application Finder" menu but the instructions are not clear about what you pick for this; "terminal" did not work.

I'm using Linux Mint 19 Tara, Ubuntu & Gnome
__________________
I'm on: Desktop: MATE 1.20.1 Distro: Linux Mint 19.1 Tessa
 


Jamesd1

New Member
I tried to sudo chmod +x there was no error or feedback, so I tried to execute the .sh script. Result was a window came up titled "Application Finder" and a drop down arrow that list all programs installed.

Now what?
 

Peer

Active Member
1. Open your terminal

2. Type in your executables path

3. Hit enter

4. Now your script runs

:)
 

Jamesd1

New Member
I opened the terminal with the "Application Dialog" and it opened to the directory where my .sh file was. I tried these:

[email protected]:~/Portable Apps/SaveDesktop$ Desktop_Maven.sh
Desktop_Maven.sh: command not found
[email protected]:~/Portable Apps/SaveDesktop$ ^C
[email protected]:~/Portable Apps/SaveDesktop$ ~/Portable Apps/SaveDesktop$ Desktop_Maven.sh
bash: /home/james/Portable: No such file or directory
[email protected]:~/Portable Apps/SaveDesktop$ ls
Desktop_Maven.doc Desktop_Maven.png Desktop_Maven.sh languages.dta
[email protected]:~/Portable Apps/SaveDesktop$

Now what?
 

blackneos940

Active Member
I opened the terminal with the "Application Dialog" and it opened to the directory where my .sh file was. I tried these:

[email protected]:~/Portable Apps/SaveDesktop$ Desktop_Maven.sh
Desktop_Maven.sh: command not found
[email protected]:~/Portable Apps/SaveDesktop$ ^C
[email protected]:~/Portable Apps/SaveDesktop$ ~/Portable Apps/SaveDesktop$ Desktop_Maven.sh
bash: /home/james/Portable: No such file or directory
[email protected]:~/Portable Apps/SaveDesktop$ ls
Desktop_Maven.doc Desktop_Maven.png Desktop_Maven.sh languages.dta
[email protected]:~/Portable Apps/SaveDesktop$

Now what?
Like I said, try creating a Desktop Entry File, which is a File that, when pointed to the Directory where Desktop_Maven is, will then execute it..... :) Here, I did some searching, and found this: I did this with a C Program once I think..... :)

Code:
[Desktop Entry]
Version=1.0
Name=Test    
Comment=Test the terminal running a command inside it
Exec=bash -c 'echo hello;$SHELL'
Icon=utilities-terminal
Terminal=true
Type=Application
Categories=Application;
Edit the line with "Exec -c" and make it point to your Bash Script like so: ..... :)

Code:
Exec=bash -c './home/user/my_shell_script.sh;$SHELL
 

TechnoJunky

Active Member
A couple things. You can do as these guys suggest using the chmod +x or you can do it in the gui. I like going to my file manager, Dolphin (I use KDE), find the file, right click, go to Permissions, and check 'Is Executable'.
If you're still having trouble after doing the steps everyone outlined above, one extra thing I'd try is instead of typing out the path to the script, go to the directory itself, then as in Rob's video, just type ./Desktop_Maven.sh. You can even just type ./Desk and then hit TAB twice and it will autofill the name. All this helps to alleviate mistyping or not finding the script. If you can get it working this way then you just need to figure out why it didn't work when typing the full path. If it doesn't work this way, then there's something wrong with the content of the script and you'll need to troubleshoot that.
 
Last edited:

rado84

Active Member
Very easy

;)
Very easy when it's about just one file or two. But when it's about a lot more than that, the easiest way is to automatically chmod them. With that the system will simply ask you if you wanna execute them or run them in terminal.

Code:
UUID=d2c93a75-9d5f-4d0f-9a63-0b5fcce4d052 /               ext4    errors=remount-ro 0       1
UUID=88FCD635FCD61CEE  /media/rado/Drive_D               ntfs-3g defaults,auto,nofail,x-systemd.device-timeout=15,uid=1000,gid=1000,umask=002 0 0
UUID=2E9CB8569CB81A73  /media/rado/Drive_E               ntfs-3g defaults,auto,nofail,x-systemd.device-timeout=15,uid=1000,gid=1000,umask=002 0 0
UUID=D818649918647900  /media/rado/Drive_F               ntfs-3g defaults,auto,nofail,x-systemd.device-timeout=15,uid=1000,gid=1000,umask=002 0 0
 

wizardfromoz

Super Moderator
Staff member
Gold Supporter
G'day @Jamesd1 and welcome to linux.org :)

Can you tell us the output from the following?

Code:
ls -l /home/james/Portable Apps/SaveDesktop$ Desktop_Maven.sh
Cheers

Chris Turner
wizardfromoz

BTW I am moving this to Command Line, where it will attract more input
 

JasKinasis

Well-Known Member
OK, as everybody has said - using chmod +x will make the script executable.

After making it executable you can run it using an absolute path:
Code:
/path/to/myscript.sh
Where /path/to/ - is the fully qualified path to the executable and myscript.sh is the name of the script.

Or you could use a relative path:
Code:
../../path/to/myscript.sh
NOTE: Above assumes that we are inside a sub-directory of a directory which is at the same level in the tree as the path/ directory.

Or you can use cd to navigate into the directory containing the script, and run it using a relative path like this:
Code:
cd /path/to/
./myscript.sh



So now that you have an executable script that you can run, but you always have to use a relative, or absolute path to it.... I know what you're thinking:

"How do I run my script as if it was a system command, from anywhere - without having to use a path?"
In order to run it from ANY directory, or sub-directory in the shell, without specifying a path to the script - you will need to put your executable script into a directory that is specified in $PATH. $PATH is an environment variable which holds a list of paths to directories containing executable files.
e.g.
Code:
/usr/local/bin/:/usr/bin/:/bin/
For user-created scripts, you should copy them (as root) to /usr/local/bin/ if you want them to be available to other users.
Code:
sudo cp /path/to/myscript.sh /usr/local/bin
Once your executable script has been put into /usr/local/bin/ - you will be able to run it from any directory, simply by typing it's name.
e.g.
Code:
myscript.sh
Alternatively - if you use a multi-user system and your script is something for your own personal use - that you don't want other users using - you could set up a personal bin directory in your home directory.
Code:
mkdir /home/yourusername/bin/
or
Code:
mkdir ~/bin/
~ is just a shortcut for /home/yourusername/

Then copy your script to your personal bin directory:
Code:
cp /path/to/myscript.sh ~/bin/
After creating your personal bin directory and copying some files, the next thing to do is to log out and log back in again. Then open a terminal and enter:
Code:
myscript.sh
Where myscript.sh is the name of the script your are trying to run. If your script is called davessillyscript.sh - then run that!

If your script runs - great - your distro already has some hooks set up in it's dot-files that check for the existence of a personal bin directory and have automatically added it to $PATH when you logged back in. Some distros are set up to support personal bin directories, others are not.

If your script didn't run - you need to add some code to one of the dotfiles that gets ran on login. I haven't got my Linux laptop handy ATM, but if memory serves - usually you'd open something like ~/.profile in a text editor and add:
Code:
# Add user's private bin to $PATH - if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi
Save your changes to ~/.profile and close your editor, then log-out and log back in again and you should be able to run your personal script from anywhere in the terminal - you should also be able to run it from any application launchers you might have. (similar to the M$ run dialog - where you hit a hot-key and enter the name of the application/script to run).

If it does not run, then .profile isn't getting loaded. In which case you'd need to do a bit of digging through your dotfiles to try to find out the best place to add the hook for a personal bin directory.

Once you have a personal bin directory set up and working, you can create scripts in there that will run as if they were installed programs.

Another related question I see a lot is:
"I've created a script called myscript.sh and I just want to run it by typing 'myscript', instead of 'myscript.sh'."
The simple answer there is to rename myscript.sh to myscript.
e.g.
Code:
mv myscript.sh myscript
Completely omit/remove the .sh part of the filename. Your script will still run.

Or alternatively - you could create a symbolic link to your script.
To create a symbolic link - open a terminal and navigate to wherever you've put your script (~/bin/, or /usr/local/bin/) and then use:
Code:
ln -sT myscript.sh myscript
Where myscript.sh is the name of the script and myscript is the link-name.

If you use a symbolic link, you will be able to run the script using the link:
Code:
myscript
or by using the scripts full file-name:
Code:
myscript.sh
IMPORTANT:
Whenever you start installing scripts to directories in your $PATH and want to run them as standalone commands in the shell - You need to ensure that the first line of each script always contains a shebang to tell the shell which interpreter should be used to run it.
e.g.
For a bash script:
Code:
#!/usr/bin/env bash
For a generic POSIX compliant shell-script that uses no shell-specific features/extensions.
Code:
#!/usr/bin/env sh
For a python3 script:
Code:
#!/usr/bin/env python3
etc. etc.

The shebang line must ALWAYS be the very first line in a script.
Shebang line first, then some comments describing the script, then the body of your script itself.

Also note, I have used /usr/bin/env {name_of_interpreter} in the above examples for a reason.

If you plan to distribute your scripts, or use them on multiple machines - instead of using a hard-coded path to an interpreter, it is wise to use /usr/bin/env {name_of_interpreter} - to allow env to resolve the correct path to the required interpreter.

Some distros install certain commands to different directories. e.g. sometimes bash (or one of the other common interpreters) is in /bin/, other times it might be in /usr/bin/.

And if the user helps to develop an interpreter (bash, ruby, python etc) - they may even have their personal environment set-up to use a custom version of it in ~/bin/, or on some other custom path.

So using /usr/bin/env to determine the correct path to an interpreter is a great way to make your script a little more portable.

The reason I do this is because I'm lazy. I like to write a script and make it as generic and useful as possible, without having to edit it whenever I copy it to a different machine. So env helps facilitate my laziness!

One last thing you might be asking:
"How do I run my script from the desktop/system-menu?"
If you want to run your script from the desktop and/or you want it to appear in the systems menu - you will need to create a .desktop file and put it with the rest of the .desktop files for applications that are installed on your system. I'm not going to go into that here, that's a little beyond the scope of this question.

But it is important to note, that if you run your script from a launcher, or the desktop - your script will just run in the background. So if your script requires any input, or if you want to see your script running in a new terminal window when ran from the desktop - you would either need to set up your .desktop file to run your script in a new terminal window, or you would need to create a wrapper script that would open your script in a new terminal window. Again - that goes a little beyond what I'm doing here! That's for another day!
 
Last edited:

Members online



Top