Scripts run my automation on every Linux box I maintain, and the first launch often stops on a message that looks fatal but isn’t. The execute bit is missing, or the shell can’t find the file, or the script expects a different interpreter. Each launch path below comes with tested commands and the exit code for its failure mode.
What a .sh File Actually Is
A .sh file is a plain text file holding shell commands, usually starting with a shebang line such as #!/bin/bash. That first line names the interpreter that should run the file: bash, sh, or zsh. When you launch a script directly, the OS reads the shebang and hands the file to that interpreter.
#!/bin/bash
echo "Hello from LinuxForDevices"
echo "The current user is $USER"
Scripts automate package installs, batch renames, cron jobs, and dozens of other chores. If shell syntax is new to you, start with our if-else in shell script guide.
Method 1: Give the File Execute Permission
The direct way to run a script is to type its path in a terminal, but the shell will only honor that when the file carries the execute permission. That bit is one part of the broader users, groups, and permissions model.
The chmod command sets the bit on any file. You can open it to every user with the a+x flag, or restrict it to the file’s owner with u+x.
chmod a+x /path/to/file.sh # every user can run it
chmod u+x /path/to/file.sh # only the owner can run it
Here is a full cycle on a test script, from adding the bit to running the file.

On my machine the run looks like this once the bit is set.

The ls -l output changed from plain read-write bits to rwxrwxr-x. Those three x flags are the execute permission for owner, group, and others. Drop them and the launch fails.
Method 2: Run It Through an Interpreter Directly
You can skip chmod entirely by naming the shell yourself. Running bash script.sh works on a file with no execute permission at all, because the interpreter reads it as text and executes it in a child shell.

Use sh script.sh when you need POSIX behavior or a minimal environment, and bash when the script leans on bash-only features like arrays and double-bracket tests. If you’re unsure which interpreter a script expects, the types of shells in Linux breakdown sorts out the sh-versus-bash question first.
| Command | Needs +x? | Runs in | Use when |
|---|---|---|---|
| ./script.sh | Yes | a new child shell | normal launch of your own script |
| bash script.sh | No | a new child shell | no chmod, or forcing bash on an odd interpreter line |
| sh script.sh | No | a new child shell (POSIX sh) | POSIX-only scripts, tiny environments |
| source script.sh | No | your current shell | loading variables or functions into the session |
Method 3: Source It Into Your Current Shell
Sourcing reads the script into the shell you’re already using instead of spawning a new one. Any variable the script sets survives after it finishes, the same mechanism your .bashrc and .bash_profile use to load your environment.
The command is source script.sh, or its POSIX abbreviation . script.sh.
I proved the difference on this server. After sourcing a small setter script, the variable FILE_VAR stayed set in my session, and after running the same script as a child it stayed empty.
A script you run hands results back through stdout and files. A script you source hands them back through the session itself.
The tradeoff
Source a buggy script and it can change directory, unset variables, or alias over commands in your live session. One quirk worth knowing: source is a bash builtin, and sh (dash) doesn’t even resolve it.
Why You Must Type ./ Before the Script Name
Type example.sh alone and the shell hunts for it in the directories listed in PATH, never in the current one. Your current directory isn’t in the search path by default, so the lookup fails with command not found. The ./ prefix is an explicit path, which redirects the lookup to the current folder.

Fixing “Permission denied” and “command not found”
Permission denied and command not found point at two different mistakes, and each one has a specific fix.
Permission denied (exit 126)
The file exists but carries no execute bit for you. Fix it with chmod, or run the script through an interpreter.

command not found (exit 127)
The shell couldn’t resolve the name at all, either because you dropped the ./ prefix or because the file is somewhere you didn’t expect. Re-run it with the full relative or absolute path.
| Failure | Exit code | Cause | Fix |
|---|---|---|---|
| Permission denied | 126 | execute bit missing | chmod a+x script.sh |
| command not found | 127 | no ./ prefix, file off PATH | run ./script.sh from its directory |
| cannot execute: required file not found | 127 | script edited on Windows (CRLF line endings) | convert the file’s line endings, then rerun |
That third row is the trap nobody expects. A script written on Windows carries invisible carriage returns before each newline, and the kernel chokes on the shebang. I reproduced the exact error, and the run died with this message even though the file was sitting right there.
Before You Run a Script You Just Downloaded
A script you download runs with your user’s privileges and installs whatever it wants. Read it before you run it.
If it’s short, cat script.sh tells you everything, and the old habit still holds: if you don’t understand it, don’t run it.
For longer scripts, let ShellCheck review the code before you execute it. It flags unquoted variables, unsafe cd calls, and hundreds of other issues from static analysis alone.

A short checklist before any first run.
- Read the script, or pass it through ShellCheck.
- Check the shebang matches the interpreter you intend to use.
- Trust the source: official project repos over random pastebins.
- Run it as a normal user first, not root.
Frequently Asked Questions
How do I run a .sh file in Linux?
Make the file executable with chmod a+x script.sh and launch it with ./script.sh, or run it through an interpreter with bash script.sh without chmod.
Why does ./script.sh give Permission denied?
The file has no execute bit for your user. Add it with chmod a+x script.sh, or run the file through bash instead.
Why does typing example.sh alone give command not found?
Unix shells search PATH for bare command names and the current directory is not in PATH by default. The ./ prefix forces the shell to look in the current directory.
What is the difference between running and sourcing a script?
Running starts a child shell, so variables it sets vanish when it exits. Sourcing executes the file in your current shell, so its variables and functions persist.
How do I run a shell script from any directory?
Give the interpreter the absolute path: bash /home/user/scripts/backup.sh. If the script is executable, add its directory to PATH and call it by name.
Your next .sh file needs one decision: does it adjust my session, or just run a task? Run task scripts with ./script.sh or through bash, and source the ones that must configure your shell. Get that distinction right and both error messages stop being surprises.
