This tag is for questions about scripts written for the Bash command shell. For shell scripts with syntax or other errors, please check them at https://shellcheck.net before posting them here. Questions about the interactive use of Bash are more likely to be on-topic on Unix & Linux Stack Exchange or 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; it is available on most modern operating systems, and has been ported to Windows 10.
A note regarding versions
As of September 2022, the most recent version of bash
is 5.2, 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) only provides version 3.2 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 (it's been available for over 10 years). Questions tagged macos 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 |
5.1 | 2020-12-06 |
5.2 | 2022-09-26 |
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
even if your system's/bin/sh
is a symlink to/bin/bash
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
- Why do you need ./ (dot-slash) before executable or script name to run it in bash?
- What does it mean when shell command starts with a dot? aka
source
- What is the difference between "./somescript.sh" and ". ./somescript.sh"
- Running my program 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
- How to pass the value of a variable to the standard input of a command? - don't forget
echo
- What's the difference between echo and printf
- Execute command on all files in a directory
- 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 - How can I check if a program exists from a Bash script? -
which
vstype
vscommand
- 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
- Why variable values are lost after terminating the loop in bash? - variables in a pipe disappear
- 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? - How can I set an environment variable only for the duration of the script?
- 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 do I check if a directory exists or not 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
- How to read variables from file, with multiple variables per line?
- here-document gives 'unexpected end of file' error
- How to redirect and append both standard output and standard error to a file with Bash
- How can I use a file in a command and redirect output to the same file without truncating it?
- Difference between single and double quotes in Bash
- How do I use variables in single quoted strings? aka you can't have nested single quotes
- How to escape single quotes within single quoted strings
- When to wrap quotes around a shell variable?
- When do we need curly braces around shell variables?
- What is the meaning of the ${0##...} syntax with variable, braces and hash character in bash? - prefix truncation in parameter expansion
- What is the meaning of ${0%/*} in a bash script? - suffix truncation in parameter expansion
- Usage of :- (colon dash) in bash - colon in prefix/suffix parameter expansion
- sh read command eats backslashes in input?
- How can I compare two floating point numbers in Bash?
- How do I use floating-point arithmetic 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?
- 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[[
- Is there a 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
- What are the special dollar sign shell variables?
How Do I ...?
- How do you run multiple programs in parallel from a bash script? aka how do I background a job?
- ... 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 can I debug a Bash script?
- Make a Bash alias that takes a parameter?
- Check existence of input argument in a Bash shell script
- How to iterate over arguments in a Bash script
- How can I use long options with the Bash getopts builtin? - you can't,
getopts
doesn't support it; build your own option parser, or use a third-party option parser - 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 do I get the directory where a Bash script is located from within the script itself?
- How do I tell if a 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?
- How can I preserve quotes in printing a bash script's 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 aka
dirname
andbasename
- Test whether a glob has any matches in Bash aka check whether a wildcard matched any files
- How can I 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. - 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 can I 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.
- What is double dot(..) and single dot(.) in Linux?
- What's the magic of "-" (a dash) in command-line parameters? aka meaning of
-
(lone minus / lone dash) in command arguments - 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
- How to grep for contents after pattern?
- 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 can I do a recursive find/replace of a string with awk or sed?
- Pass commands as input to another command (su, ssh, sh, etc)
- How can I execute a group of commands as another user in Bash?
- Multiple commands on remote machine using shell script
- How can I split a large text file into smaller files with an equal number of lines?
- How to delete JPG files, but only if the matching RAW file exists?
- Have bash script answer interactive prompts
- 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
Bash beginner's mistakes (add
83.243.40.67 wiki.bash-hackers.org
to /etc/hosts file 20230508 du to abandoned domain name)Bash hackers (add
83.243.40.67 wiki.bash-hackers.org
to /etc/hosts file 20230508 du to abandoned domain name)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)
- https://explainshell.com/ can pick apart many command lines and explain what the elements mean (notice that you can sometimes click on a result to have it picked apart further)
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).