83 languages for you to master
Become fluent in your chosen programming languages by completing these tracks created by our awesome team of contributors
Bash is a Unix shell and command language written by Brian Fox for the GNU Project as a free software replacement for the Bourne shell. Released in 1989, it has been distributed widely as the shell for the GNU operating system and as a default shell on Linux and OS X.
In 2015 Prospect One, under the management of Dmitriy Akulov, was asked to design a new logo for Bash, after which 30,000 people voted for the best iteration. You can download the official bash logo below

Bats: Bash Automated Testing System
Bats is a TAP-compliant testing framework for Bash. It provides a simple way to verify that the UNIX programs you write behave as expected.
A Bats test file is a Bash script with special syntax for defining test cases. Under the hood, each test case is just a function with a description.
Bats is a TAP-compliant testing framework for Bash. It provides a simple way to verify that the UNIX programs you write behave as expected.
A Bats test file is a Bash script with special syntax for defining test cases. Under the hood, each test case is just a function with a description.
This wiki is intended to hold documentation of any kind about GNU Bash. The main motivation was to provide human-readable documentation and information so users aren't forced to read every bit of the Bash manpage - which can be difficult to understand. However, the docs here are not meant as a newbie tutorial.
This wiki and any programs found in this wiki are free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This wiki and its programs are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
What would YOU like to see here? (outdated and locked, please use the discussions)
Stranger! Feel free to register and comment or edit the contents. There is a Bash Hackers Wiki needs love page that lists some things to do. The registration is only there to prevent SPAM.
gron is a self-contained Go executable you can download from here on GitHub. In the UNIX tradition, gron does one thing well: it flattens JSON into a structure that's easily processed by shell tools, line by line.
Git for Windows focuses on offering a lightweight, native set of tools that bring the full feature set of the Git SCM to Windows while providing appropriate user interfaces for experienced Git users and novices alike.
The goals of ShellCheck are
- To point out and clarify typical beginner's syntax issues that cause a shell to give cryptic error messages.
- To point out and clarify typical intermediate level semantic problems that cause a shell to behave strangely and counter-intuitively.
- To point out subtle caveats, corner cases and pitfalls that may cause an advanced user's otherwise working script to fail under future circumstances.
See the gallery of bad code for examples of what ShellCheck can help you identify!
First, why bother? Well, while bash is the default /bin/sh shell on many rpm-based Linux distributions (so it’s also the default shell on the systems I’m developing with and thus referring to here), it’s often not the case on other Linux distributions like Debian or Alpine, and it’s certainly not the case on non-Linux systems like the various *BSD flavors or illumos based installations.
!/bin/bash
#
# (c) Frank Matthieß 2020
#
#
NAME=$(basename $0)
info() { echo "$*">&2; }
error() { info "ERROR: $*"; }
APIURL=https://api.opensensemap.org/boxes
TMPFILE=$(mktemp)
STIDFILE=$(mktemp)
trap 'rm -f ${TMPFILE} ${STIDFILE} ' INT EXIT
# At the map, click on an station icon and you get, for example, this url:
# https://opensensemap.org/explore/5b4d11485dc1ec001b5452c7
#
# Add the id tring at the end of the url with a proper name to the sensor id list
# Sensor id list
cat<<EOSTIDS>$STIDFILE
5c22ef44919bf8001a10acc7 Berlin Charlottenburg
5a9c2087bc2d4100191d6ff9 Stuttgart Unteraichen (A8)
5b4d11485dc1ec001b5452c7 München Fakultät Informatik
EOSTIDS
#
#
# Adjust the field length of the output
llen=0
while read stid location; do
l=$(wc -c <<< "$location")
if [ $llen -lt $l ]; then
llen=$l
fi
done < $STIDFILE
#
# .. and get the need values via opensensemap api
#
while read stid location; do
curl -sL ${APIURL}/${stid} > ${TMPFILE}
reallocation=$(jq .name < ${TMPFILE})
temperature=$(jq '.sensors[] | select(.title|test("Temperatur")) | .title, .lastMeasurement.value, .unit' < ${TMPFILE} | xargs )
humidity=$(jq '.sensors[] | select(.title|test("rel. Luftfeuchte")) | .title, .lastMeasurement.value, .unit' < ${TMPFILE} | xargs )
rawcoordinates=$(jq '.currentLocation.coordinates[]' < ${TMPFILE} | xargs )
coordinates=$(while read lon lat heigh; do echo "https://www.openstreetmap.org/?mlat=${lat}&mlon=${lon}#map=12/${lat}/$lon"; done <<< "${rawcoordinates}")
#
printf "%-${llen}s:\n\tStationsname : %s\n\t%s\n\t%s\n\tOpenstreetmap: %s\n" \
"${location}" \
"${reallocation//\"/}" \
"${temperature}" \
"${humidity}" \
"${coordinates}"
done < $STIDFILE
# vim:set ts=8 sts=8 sw=8 ft=sh ai tw=80:${parameter:-word}
Use Default Values. If parameter is unset or null, the expansion of word is substituted. Otherwise,
the value of parameter is substituted.
${parameter:=word}
Assign Default Values. If parameter is unset or null, the expansion of word is assigned to parameter.
The value of parameter is then substituted. Positional parameters and special parameters may not be
assigned to in this way.
${parameter:?word}
Display Error if Null or Unset. If parameter is null or unset, the expansion of word (or a message to
that effect if word is not present) is written to the standard error and the shell, if it is not inter‐
active, exits. Otherwise, the value of parameter is substituted.
${parameter:+word}
Use Alternate Value. If parameter is null or unset, nothing is substituted, otherwise the expansion of
word is substituted.
${parameter:offset}
${parameter:offset:length}
Substring Expansion. Expands to up to length characters of the value of parameter starting at the
character specified by offset. If parameter is @, an indexed array subscripted by @ or *, or an asso‐
ciative array name, the results differ as described below. If length is omitted, expands to the sub‐
string of the value of parameter starting at the character specified by offset and extending to the end
of the value. length and offset are arithmetic expressions (see ARITHMETIC EVALUATION below).
If offset evaluates to a number less than zero, the value is used as an offset in characters from the
end of the value of parameter. If length evaluates to a number less than zero, it is interpreted as an
offset in characters from the end of the value of parameter rather than a number of characters, and the
expansion is the characters between offset and that result. Note that a negative offset must be sepa‐
rated from the colon by at least one space to avoid being confused with the :- expansion.
If parameter is @, the result is length positional parameters beginning at offset. A negative offset
is taken relative to one greater than the greatest positional parameter, so an offset of -1 evaluates
to the last positional parameter. It is an expansion error if length evaluates to a number less than
zero.
If parameter is an indexed array name subscripted by @ or *, the result is the length members of the
array beginning with ${parameter[offset]}. A negative offset is taken relative to one greater than the
maximum index of the specified array. It is an expansion error if length evaluates to a number less
than zero.
Substring expansion applied to an associative array produces undefined results.
Substring indexing is zero-based unless the positional parameters are used, in which case the indexing
starts at 1 by default. If offset is 0, and the positional parameters are used, $0 is prefixed to the
list.
${!prefix*}
${!prefix@}
Names matching prefix. Expands to the names of variables whose names begin with prefix, separated by
the first character of the IFS special variable. When @ is used and the expansion appears within dou‐
ble quotes, each variable name expands to a separate word.
${!name[@]}
${!name[*]}
List of array keys. If name is an array variable, expands to the list of array indices (keys) assigned
in name. If name is not an array, expands to 0 if name is set and null otherwise. When @ is used and
the expansion appears within double quotes, each key expands to a separate word.
${#parameter}
Parameter length. The length in characters of the value of parameter is substituted. If parameter is
* or @, the value substituted is the number of positional parameters. If parameter is an array name
subscripted by * or @, the value substituted is the number of elements in the array. If parameter is
an indexed array name subscripted by a negative number, that number is interpreted as relative to one
greater than the maximum index of parameter, so negative indices count back from the end of the array,
and an index of -1 references the last element.
${parameter#word}
${parameter##word}
Remove matching prefix pattern. The word is expanded to produce a pattern just as in pathname expan‐
sion, and matched against the expanded value of parameter using the rules described under Pattern
Matching below. If the pattern matches the beginning of the value of parameter, then the result of the
expansion is the expanded value of parameter with the shortest matching pattern (the ``#'' case) or the
longest matching pattern (the ``##'' case) deleted. If parameter is @ or *, the pattern removal opera‐
tion is applied to each positional parameter in turn, and the expansion is the resultant list. If pa‐
rameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each
member of the array in turn, and the expansion is the resultant list.
${parameter%word}
${parameter%%word}
Remove matching suffix pattern. The word is expanded to produce a pattern just as in pathname expan‐
sion, and matched against the expanded value of parameter using the rules described under Pattern
Matching below. If the pattern matches a trailing portion of the expanded value of parameter, then the
result of the expansion is the expanded value of parameter with the shortest matching pattern (the
``%'' case) or the longest matching pattern (the ``%%'' case) deleted. If parameter is @ or *, the
pattern removal operation is applied to each positional parameter in turn, and the expansion is the re‐
sultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation
is applied to each member of the array in turn, and the expansion is the resultant list.
${parameter/pattern/string}
Pattern substitution. The pattern is expanded to produce a pattern just as in pathname expansion, Pa‐
rameter is expanded and the longest match of pattern against its value is replaced with string. The
match is performed using the rules described under Pattern Matching below. If pattern begins with /,
all matches of pattern are replaced with string. Normally only the first match is replaced. If pat‐
tern begins with #, it must match at the beginning of the expanded value of parameter. If pattern be‐
gins with %, it must match at the end of the expanded value of parameter. If string is null, matches
of pattern are deleted and the / following pattern may be omitted. If the nocasematch shell option is
enabled, the match is performed without regard to the case of alphabetic characters. If parameter is @
or *, the substitution operation is applied to each positional parameter in turn, and the expansion is
the resultant list. If parameter is an array variable subscripted with @ or *, the substitution opera‐
tion is applied to each member of the array in turn, and the expansion is the resultant list.
${parameter^pattern}
${parameter^^pattern}
${parameter,pattern}
${parameter,,pattern}
Case modification. This expansion modifies the case of alphabetic characters in parameter. The pat‐
tern is expanded to produce a pattern just as in pathname expansion. Each character in the expanded
value of parameter is tested against pattern, and, if it matches the pattern, its case is converted.
The pattern should not attempt to match more than one character. The ^ operator converts lowercase
letters matching pattern to uppercase; the , operator converts matching uppercase letters to lowercase.
The ^^ and ,, expansions convert each matched character in the expanded value; the ^ and , expansions
match and convert only the first character in the expanded value. If pattern is omitted, it is treated
like a ?, which matches every character. If parameter is @ or *, the case modification operation is
applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is
an array variable subscripted with @ or *, the case modification operation is applied to each member of
the array in turn, and the expansion is the resultant list.
${parameter@operator}
Parameter transformation. The expansion is either a transformation of the value of parameter or infor‐
mation about parameter itself, depending on the value of operator. Each operator is a single letter:
Q The expansion is a string that is the value of parameter quoted in a format that can be reused
as input.
E The expansion is a string that is the value of parameter with backslash escape sequences ex‐
panded as with the $'...' quoting mechanism.
P The expansion is a string that is the result of expanding the value of parameter as if it were a
prompt string (see PROMPTING below).
A The expansion is a string in the form of an assignment statement or declare command that, if
evaluated, will recreate parameter with its attributes and value.
a The expansion is a string consisting of flag values representing parameter's attributes.
If parameter is @ or *, the operation is applied to each positional parameter in turn, and the expan‐
sion is the resultant list. If parameter is an array variable subscripted with @ or *, the operation
is applied to each member of the array in turn, and the expansion is the resultant list.
The result of the expansion is subject to word splitting and pathname expansion as described below.Ausgabe des aktuellen timestamp mit bash printf ohne $(date +…):
printf "%(%FT%T%z)T\n"
… aber nicht ganz …
~$ printf "%(%FT%T%z)T msg: %s\n" "mjggjgjh"
bash: printf: mjggjgjh: invalid number
1970-01-01T01:00:00+0100 msg:
~$ printf "%(%FT%T%z)T\n" "123456"
1970-01-02T11:17:36+0100
~$ printf "%(%FT%T%z)T msg: %s\n" "$(date +%s)" "wrether the rztj rtzhj"
2020-10-19T07:46:27+0200 msg: wrether the rztj rtzhj
man bash:
printf [-v var] format [arguments]
Write the formatted arguments to the standard output under the control of the format. The -v option
causes the output to be assigned to the variable var rather than being printed to the standard output.
The format is a character string which contains three types of objects: plain characters, which are
simply copied to standard output, character escape sequences, which are converted and copied to the
standard output, and format specifications, each of which causes printing of the next successive argu‐
ment. In addition to the standard printf(1) format specifications, printf interprets the following ex‐
tensions:
%b causes printf to expand backslash escape sequences in the corresponding argument in the same way
as echo -e.
%q causes printf to output the corresponding argument in a format that can be reused as shell in‐
put.
%(datefmt)T
causes printf to output the date-time string resulting from using datefmt as a format string for
strftime(3). The corresponding argument is an integer representing the number of seconds since
the epoch. Two special argument values may be used: -1 represents the current time, and -2 rep‐
resents the time the shell was invoked. If no argument is specified, conversion behaves as if
-1 had been given. This is an exception to the usual printf behavior.
Arguments to non-string format specifiers are treated as C constants, except that a leading plus or mi‐
nus sign is allowed, and if the leading character is a single or double quote, the value is the ASCII
value of the following character.
The format is reused as necessary to consume all of the arguments. If the format requires more argu‐
ments than are supplied, the extra format specifications behave as if a zero value or null string, as
appropriate, had been supplied. The return value is zero on success, non-zero on failure.ShellCheck is...
- GPLv3: free as in freedom
- available on GitHub
- already packaged for your distro or package manager
- supported as an integrated linter in major editors
- available in CodeClimate, Codacy and CodeFactor to auto-check your GitHub repo
- written in Haskell, if you're into that sort of thing.
Jetzt ist es passiert: Ich muss eines meiner Android-Geräte zwecks Reparatur zum Service-Center einschicken. Das bedeutet natürlich einen „Factory-Reset“ vor dem Verpacken, was ein vorheriges (gutes) Backup impliziert. Zwar erstelle ich regelmäßig diverse Sicherungen (etwa automatisch mit Titanium Backup), aber habe ich wirklich an alles gedacht? Wird die Wiederherstellung ein „Kinderspiel”? Vielleicht sollte ich die Chance auch gleich zum „Aufräumen“ nutzen. Oh, und was ist mit der ganzen „Bloatware“, die ich mühselig ausfindig gemacht und deaktiviert habe, und den deaktivierten „Auto-Starts“? Wieviel Handarbeit kommt da auf mich zu, wenn ich mein Gerät wieder habe?
page is a compilation of common mistakes made by bash users. Each example is flawed in some way.
These are answers to frequently asked questions on channel #bash on the freenode IRC network. These answers are contributed by the regular members of the channel (originally heiner, and then others including greycat and r00t), and by users like you. If you find something inaccurate or simply misspelled, please feel free to correct it!
All the information here is presented without any warranty or guarantee of accuracy. Use it at your own risk. When in doubt, please consult the man pages or the GNU info pages as the authoritative references.
BASH is a BourneShell compatible shell, which adds many new features to its ancestor. Most of them are available in the KornShell, too. The answers given in this FAQ may be slanted toward Bash, or they may be slanted toward the lowest common denominator Bourne shell, depending on who wrote the answer. In most cases, an effort is made to provide both a portable (Bourne) and an efficient (Bash, where appropriate) answer. If a question is not strictly shell specific, but rather related to Unix, it may be in the UnixFaq.
This FAQ assumes a certain level of familiarity with basic shell script syntax. If you're completely new to Bash or to the Bourne family of shells, you may wish to start with the BashGuide.
More advanced users may wish to read BashPitfalls and BashProgramming.
If you want to help, you can add new questions with answers here, or try to answer one of the BashOpenQuestions.
Chet Ramey's official Bash FAQ contains many technical questions not covered here.
I recently worked on creating a bash completion script for one of my toy projects and I enjoyed it very much.
Password store template for teams
This repository contains a base template for a password store repository to be used by teams.
It contains:
A README.md to adapt to your team
A script to setup a unique alias based on the directory name.
A Makefile with some common toolsAuch an denjenigen, die schon über 20 Jahre mit der Bash arbeiten, sind Bash-Arrays bisher vielleicht vorbeigegangen. Dieser Artikel zeigt, wie man Arrays auch in der Bash verwenden kann, so wie von Perl und anderen Sprachen bekannt.
Arrays ermöglichen es, eine geordnete Folge von Werten eines bestimmten Typs zu speichern und zu bearbeiten. Allerdings erlaubt die Bash nur eindimensionale Arrays. Dabei werden zwei grundlegende Typen von Arrays unterschieden.
Indizierte Arrays verwenden positive Integer-Zahlen als Index. Sie sind meist sparse, die Indizes sind nicht unbedingt zusammenhängend. Wie in C und vielen anderen Sprachen beginnen die ganzzahligen Array-Indizes bei 0. Indizierte Arrays wurden zuerst bei der Bourne-ähnlichen Shell, der ksh eingeführt. Indizierte Arrays tragen immer das Attribut -a.
Assoziative Arrays (manchmal als Hash bezeichnet) verwenden beliebige nichtleere Zeichenketten als Index. Assoziative Arrays sind immer ungeordnet, sie assoziieren nur Index-Wert-Paare. Wenn Sie mehrere Werte aus dem Array abrufen, können Sie sich nicht darauf verlassen, dass diese in derselben Reihenfolge wiedergegeben werden, in der sie eingefügt wurden. Assoziative Arrays tragen immer das Attribut -A. Im Gegensatz zu indizierten Arrays müssen sie immer ausdrücklich deklariert werden.