For questions about scripts written for the Bash command shell. For shell scripts with errors/syntax errors, please check them with the shellcheck program (or in the web shellcheck server at https://shellcheck.net) before posting here. Questions about interactive use of Bash are more likely to be on-topic on Super User than on Stack Overflow.
About Bash
There are a variety of interpreters that receive commands either interactively or as a sequence of commands from a file. The Bourne-again shell (Bash) is one such interpreter. Bash implements the standard Bourne Shell (sh), and offers numerous additions.
From the Free Software Foundation's Bash page:
Bash is an
sh
-compatible shell that incorporates useful features from the KornShell (ksh) and C shell (csh
). It is intended to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard. It offers functional improvements over sh for both programming and interactive use. In addition, most sh scripts can be run by Bash without modification.
Read the Bash manual for technical details.
Bash was written by Brian Fox and first released in 1989. It is the default shell in many Linux distributions and on MacOS; it is available on most modern operating systems, and has been ported to Windows 10.
A note regarding versions
As of January 2019, the most recent version of bash
is 5.0, although you may be using an older version depending on your operating system and
which updates to bash
have been installed. Most Linux installations should be using something in the 4.x family. macOS (formerly Mac OS X) uses version 3.2 by default due to licensing issues.
Be sure to note in your question what version of bash
you are using. This will alert potential answerers to what features are available to you, as well as which bugs may need to be worked around.
You can determine which version of bash
you are using by running bash --version
or checking the value of the BASH_VERSION
shell variable.
Without an explicit version, an answerer may well assume you are using at least version 4.2. Questions tagged osx
imply version 3.2 unless otherwise stated.
A Brief Release History
Based on downloads available from http://ftp.gnu.org/gnu/bash/
Version | Release Date |
---|---|
3.2 | 2006-10-11 |
4.0 | 2009-02-20 |
4.1 | 2009-12-31 |
4.2 | 2011-02-13 |
4.3 | 2014-02-26 |
4.4 | 2016-09-15 |
5.0 | 2019-01-07 |
Additionally, all versions for bash
from 2.0 and later received an important patch-level release to address the Shellshock vulnerability in September 2014.
Before asking about problematic code
To help the kind people who assist you, to ensure that future readers can benefit from your question, and to help ensure your question is voted up as useful for that lovely karma, please make your question as simple and universal as possible:
Check whether your script or data has DOS style end-of-line characters
Use
cat -v yourfile
orecho "$yourvariable" | cat -v
.DOS carriage returns will show up as
^M
after each line.If you find them, delete them using
dos2unix
(a.k.a.fromdos
) ortr -d '\r'
Make sure you run the script with
bash
, notsh
The first line in the script must be
#!/bin/bash
or#!/usr/bin/env bash
.It must not be
#!/bin/sh
Run the script with
./yourscript
orbash yourscript
.Do not run it with
sh yourscript
.This applies even when
sh
is a symlink tobash
.
Find a small, self-contained example.
- Don't include sections and commands unrelated to your problem.
- Avoid complex commands that just serve to produce a value (include the value directly).
- Avoid relying on external files. Create the files on the fly, include the data directly, or post a small example of a file in your question.
Test your example. Make sure it runs and still shows the problem. Do not brush this off.
- Reformatting for clarity often sidesteps pitfalls related to spacing and naming.
- Refactoring for simplicity often sidesteps pitfalls related to subshells.
- Mocking out files and data often sidesteps problems related to special characters.
- Hours spent trying multiple things often leads to posting code from one version and errors from another.
Check the example for common problems
- Run your example through
shellcheck
or the online shellcheck service to automatically check for common mistakes. - Browse Bash pitfalls and Bash beginner's mistakes as well as the Popular Questions section below for checklists of common issues.
- Check your data for special characters, using
cat -v yourfile
orcat -v <<< "$yourvar"
. Be especially careful with carriage returns (shown as^M
).
- Run your example through
Please avoid tagging questions that are solely about external commands. The
bash
tag should be reserved for Bash-related problems, not any CLI problem you might have.
How to turn a bad script into a good question
For example, let's say you have a script for alerting you when a server is idle, but it keeps alerting even when the machine is not idle:
# Avoid code like this when asking about a problem
# It has irrelevant code and external dependencies, and is hard to read and run
while true
do
load=$(wget -O - "http://$1/load.php" | grep "^load:" | cut -d: -f 2)
if [[ $load=="0" ]]
then
mailx -s "System is idle" user@example.com <<< "The server is idle"
break
else
echo "Waiting..."
sleep 60
fi
done
- The problem still occurs without the loop: Remove the loop from your question.
- The problem still occurs if you skip asking the server: Hard code the response (e.g.
load=42
) - The problem still occurs without emailing: Use
echo "Why does this run?"
- The problem still occurs when removing the else branch. Shorten it
We're now left with this small, self-contained example:
# Prefer code like this when asking about a problem
# It's small, simple and self contained, making it easy to read and run.
load=42
if [[ $load=="0" ]]
then
echo "Why does this run?"
fi
Thanks for making your question simple and useful! Enjoy your upvotes!
(However, note that this example is simple to compare against the relevant entry in Bash pitfalls and the error is automatically caught by shellcheck
, so now you don't actually need to ask!)
Popular Questions
Some frequently asked Bash questions include the following.
Basic Syntax and Common Newbie Problems
Some fundamentals of Bash are surprising even to veterans from other programming languages.
- Run text file as commands in Bash
- Difference between sh and bash
- What is the difference between "./somescript.sh" and ". ./somescript.sh"
- Ubuntu says "bash: ./program Permission denied"
- Are shell scripts sensitive to encoding and line endings? -- resounding yes, use a real editor, avoid editing script files on Windows, and/or use
dos2unix
- Bash: Syntax error: redirection unexpected and other errors caused by running
sh
ordash
instead ofbash
- Bash script prints "Command Not Found" on empty lines and Shell script not running, command not found are grab bags of common newbie problems which result in the
command not found
message - why in an 'if' statement 'then' has to be in the next line in bash?
- Getting "command not found" error in bash script - don't call your own variable
PATH
- Correct Bash and shell script variable capitalization
- Global environment variables in a shell script aka Unix processes cannot change their parent's environment
- How to append output to the end of a text file
- Command not found error in Bash variable assignment aka can't have spaces around
=
in variable assignment - Assignment of variables with space after the (=) sign? corollary to the previous - what does it mean if you have spaces around
=
in an assignment? - Defining a variable with or without export
- Shell equality operators (=, ==, -eq) aka numeric vs string equality
- How do I compare two string variables in an 'if' statement in Bash?
- Meaning of "[: too many arguments" error from if [] (square brackets) aka
[ -f many things ]
doesn't work - Checking the success of a command in a bash `if [ .. ]` statement aka you think
[
is part of theif
statement's syntax but it isn't - Why doesn't my if statement with backticks work properly?
- How can I check if a directory exists in a Bash shell script?
- Length of string in bash
- How to check if a string contains a substring in Bash
- Simple logical operators in Bash
- How do I set a variable to the output of a command in Bash?
- Read a file line by line assigning the value to a variable
- here-document gives 'unexpected end of file' error
- How to redirect and append both stdout and stderr to a file with Bash?
- Difference between single and double quotes in Bash
- How do I use variables in single quoted strings?
- When to wrap quotes around a shell variable?
- When do we need curly braces around shell variables?
- sh read command eats backslashes in input?
- How to compare two floating point numbers in Bash?
- How do I use floating-point division in bash? aka Bash doesn't have floating-point arithmetic; you need to use an external utility which does
- What does the line "#!/bin/sh" mean in a UNIX shell script?
- What's the difference between .bashrc, .bash_profile, and .environment?
- What does the 2> mean on the Unix command-line?
- In the shell, what does " 2>&1 " mean?
- What is the difference between $(command) and `command` in shell programming?
- Difference between single and double square brackets in Bash aka
[
vs[[
- List of 'if' switches anywhere? - actually
[
optionsoperators- at an interactive bash prompt, enter
help test
to see them.
- at an interactive bash prompt, enter
- "syntax error near unexpected token `('" error with process substitution
How Do I ...?
- How do you run multiple programs in parallel from a bash script?
- ... but limit the number of parallel processes? Bash script processing limited number of commands in parallel
- How to permanently set $PATH on Linux/Unix?
- How to debug a bash script?
- Make a Bash alias that takes a parameter?
- Check existence of input argument in a Bash shell script
- How do I iterate over a range of numbers defined by variables in Bash? aka using variables in brace expansions
- How do I remove the file suffix and path portion from a path string in Bash?
- How do I rename the extension for a bunch of files?
- Rename multiple files based on pattern in Unix
- Looping over pairs of values in bash -- when you want to
mv
orffmpeg
orawk
a bunch of pairs of files - How to pass command output as multiple arguments to another command
- How can I get the source directory of a Bash script from within the script itself?
- How do I tell if a regular file does not exist in Bash?
- How to concatenate string variables in Bash
- How do I split a string on a delimiter in Bash?
- How can I have a newline in a string in sh?
- How do I preserve newlines in a quoted string in Bash?
- Preserve Quotes in bash arguments aka "How can I get back the command line before wildcards were expanded" (TL;DR: you can't)
- How do I use shell variables in an awk script?
- Using variables inside a bash heredoc and also wildcards in here documents
- Extract filename and extension in Bash
- Test whether a glob has any matches in bash aka check whether a wildcard matched any files
- How to create nonexistent subdirectories recursively using Bash?
- How do I prompt for Yes/No/Cancel input in a Linux shell script?
- Passing arguments to an interactive program non-interactively
- Stop shell wildcard character expansion?
- Quick-and-dirty way to ensure only one instance of a shell script is running at a time
- How to get pid given the process name
- Check if command error contains a substring
- Split one file into multiple files based on delimiter
- How do I pass on script arguments that contain quotes/spaces? (i.e. why quote
"$@"
)? - How do I pass arbitrary arguments to a command executed over SSH?
Why Does ...?
- Security implications of forgetting to quote a variable in bash/POSIX shells
- Why does /bin/sh behave differently to /bin/bash even if one points to the other?
- Why should there be spaces around '[' and ']' in Bash? and related Why equal to operator does not work if it is not surrounded by space?
- Why is testing "$?" to see if a command succeeded or not, an anti-pattern?
- Bash regex match not working - escaping all special characters aka don't put quotes around your regular expression in
if [[ string =~ $regex ]]
- Bash Regular Expression -- Can't seem to match any of \s \S \d \D \w \W etc aka Bash's regex dialect is not PCRE
- Why can't I change directories using "cd" in a script?
- While loop stops reading after the first line in Bash
- A variable modified inside a while loop is not remembered
- I just assigned a variable, but echo $variable shows something else
- Script fails with spaces in directory names -- TL;DR: don't read lines with
for
- Why does shell ignore quoting characters in arguments passed to it through variables? aka I'm trying to put a command in a variable, but the complex cases always fail
- Why should eval be avoided in Bash, and what should I use instead?
- How to use a variable's value as another variable's name in bash aka Dynamic variable names in Bash
- Error message on Terminal launch - you screwed up your
.bashrc
or.profile
or similar. - How do I pass on script arguments that contain quotes/spaces?
- Why does my bash code fail when I run it with sh?
- Why isn't tilde (~) expanding inside double quotes?
- Expanding a bash array only gives the first element
- How to assign a value to an array in bash?
- Shell variable is available on command line but not in script
- What does set -e mean in a bash script?
- Why does my script suddenly exit after a command? (
set -e
/errexit
)
Common Tasks
These questions are not really specific to Bash, but frequent enough in this tag that they deserve to be included here.
- Argument list too long error for rm, cp, mv commands
- Editing/Replacing content in multiple files in Unix AIX without opening it aka scripting search/replace so you don't have to manually open a file and edit it
- Fast way of finding lines in one file that are not in another?
- Delete specific line number(s) from a text file using sed?
- How to delete duplicate lines in a file without sorting it in Unix?
- Inner join on two text files
- Replace a field with values specified in another file
- Replace a string in shell script using a variable
- Check number of running scripts using ps
- Get string after character
- Extract one word after a specific word on the same line
- How to get the part of a file after the first line that matches a regular expression?
- Extract lines between 2 tokens in a text file using bash
- Parsing JSON with Unix tools
- Filter log file entries based on date range
- How to do a recursive find/replace of a string with awk or sed?
- Pass commands as input to another command (su, ssh, sh, etc)
- How to execute a group of commands as another user in Bash?
- Multiple commands on remote machine using shell script
- How to split a large text file into smaller files with equal number of lines?
- CronJob not running the Stack Overflow
crontab
tag wiki also has a good set of notes for troubleshootingcron
problems.
Meta
Books and Resources
Additional reading materials include:
Bash FAQ by the current primary maintainer, Chet Ramey.
Bash FAQ by Lhunath
Bash Guide by Lhunath
The Command Line Crash Course (also a Powershell reference)
Tools
shellcheck
- a static analysis tool that detects common mistakes- on-line ShellCheck, a web server providing shellcheck (useful if you've not yet installed the program)
Chat
The Stack Overflow bash
chat is useful for coordinating work within this tag, and perhaps occasionally for getting quick help (though no guarantees can be made; attendance is spotty).