Difference between revisions of "Bash"

From ArchWiki
Jump to navigation Jump to search
(定制标题)
(Default)
 
(260 intermediate revisions by 72 users not shown)
Line 1: Line 1:
[[Category:Command shells]]  
+
[[Category:Command shells]]
[[es:Bashrc]]
+
[[Category:GNU]]
 +
[[de:Bash]]
 +
[[es:Bash]]
 
[[it:Bash]]
 
[[it:Bash]]
[[nl:Bashrc]]
+
[[ja:Bash]]
[[zh-CN:Bash]]
+
[[ru:Bash]]
{{Article summary start}}
+
[[zh-hans:Bash]]
{{Article summary text|Discussing and improving Bash's capabilities.}}
+
{{Related articles start}}
{{Article summary heading|Related}}
+
{{Related|Bash/Functions}}
{{Article summary wiki|Readline}}
+
{{Related|Bash/Prompt customization}}
{{Article summary wiki|Environment Variables}}
+
{{Related|Environment variables}}
{{Article summary wiki|Color Bash Prompt}}
+
{{Related|Readline}}
{{Article summary end}}
+
{{Related|Fortune}}
'''Bash''' (Bourne-again Shell) is a [[Command shell|shell]]/programming language by the [[GNU Project]]. Its name is a homaging reference to its predecessor: the long-deprecated Bourne shell. Bash can be run on most UNIX-like operating systems, including GNU/Linux.
+
{{Related|Pkgfile}}
 +
{{Related|Command-line shell}}
 +
{{Related articles end}}
 +
[https://www.gnu.org/software/bash/ Bash] (Bourne-again Shell) is a [[command-line shell]]/programming language by the [[GNU Project]]. Its name is a homaging reference to its predecessor, the long-deprecated Bourne shell. Bash can be run on most UNIX-like operating systems, including GNU/Linux.
  
==Invocation==
+
Bash is the default command-line shell on Arch Linux.
Bash behaviour can be altered depending on how it is invoked. Some descriptions of different modes follow.
 
===Login shell===
 
If Bash is spawned by {{ic|login}} in a tty, by an [[SSH]] daemon, or similar means, it is considered a login shell. This mode can also be engaged using the {{Ic|-l}} or {{Ic|--login}} command line options.
 
  
===Interactive shell===
+
== Invocation ==
Bash is considered an interactive shell if it is started neither with the {{Ic|-c}} option nor any non-option arguments, and whose standard input and error are connected to terminals.
 
  
===POSIX compliance===
+
Bash behaviour can be altered depending on how it is invoked. Some descriptions of different modes follow.
Bash can be run with enhanced POSIX compliance by starting Bash with the {{Ic|--posix}} command-line option or executing ‘{{Ic|set -o posix}}’ while Bash is running.
 
  
===Legacy mode===
+
If Bash is spawned by {{ic|login}} in a TTY, by an [[SSH]] daemon, or similar means, it is considered a '''login shell'''. This mode can also be engaged using the {{ic|-l}}/{{ic|--login}} command line option.
In Arch {{ic|/bin/sh}} (which used to be the Bourne shell executable) is symlinked to {{ic|/bin/bash}}.
 
  
If Bash is invoked with the name {{Ic|sh}}, it tries to mimic the startup behavior of historical versions of {{Ic|sh}}.
+
Bash is considered an '''interactive shell''' when its standard input and error are connected to a terminal (for example, when run in a terminal emulator), and it is not started with the {{ic|-c}} option or  [http://unix.stackexchange.com/a/96805 non-option] arguments (for example, {{ic|bash '''script'''}}). All interactive shells source {{ic|/etc/bash.bashrc}} and {{ic|~/.bashrc}}, while interactive ''login'' shells also source {{ic|/etc/profile}} and {{ic|~/.bash_profile}}.
  
==Configuration==
+
{{Note|In Arch {{ic|/bin/sh}} (which used to be the Bourne shell executable) is symlinked to {{ic|/bin/bash}}. If Bash is invoked with the name {{ic|sh}}, it tries to mimic the startup behavior of historical versions of {{ic|sh}}, including POSIX compability.}}
{{poor writing}}
 
===Configuration file overview===
 
* {{ic|/etc/profile}}
 
* {{ic|~/.bash_profile}}
 
* {{ic|~/.bash_login}}
 
* {{ic|~/.profile}}
 
* {{ic|/etc/bash.bashrc}} (''Non-standard'': only some distros, Arch included)
 
* {{ic|~/.bashrc}}
 
* {{ic|~/.bash_logout}}
 
An overview of the commonly used configuration files:
 
====/etc/profile====
 
{{ic|/etc/profile}} is sourced by all Bourne-compatible shells upon login. It sets up an environment upon login and loads application-specific ({{ic|/etc/profile.d/*.sh}}) settings.
 
  
====.profile====
+
=== Configuration files ===
This file is read and sourced by bash when an interactive login shell is started.
 
  
====.bashrc====
+
See section "6.2 Bash Startup Files" in {{ic|/usr/share/doc/bash/bashref.html}} ([https://www.gnu.org/software/bash/manual/bash.html#Bash-Startup-Files online link]) and [[GregsWiki:DotFiles]] for a complete description.
The file {{ic|~/.bashrc}} is read and sourced by bash when a non-login interactive shell is started, for example, when you open a virtual console from the desktop environment. This file is useful for setting up a user-specific shell environment.
 
  
===Configuration file sourcing order at startup===
+
{| class="wikitable"
These files are sourced by bash in different circumstances.  
+
! File
* if interactive + login shell → {{ic|/etc/profile}} then the first readable of {{ic|~/.bash_profile}}, {{ic|~/.bash_login}}, and {{ic|~/.profile}}
+
! Description
**Bash will source {{ic|~/.bash_logout}} upon exit.  
+
! Login shells <sup>(see note)</sup>
* if interactive + non-login shell → {{ic|/etc/bash.bashrc}} then {{ic|~/.bashrc}}
+
! Interactive, ''non-login'' shells
* if login shell + legacy mode → {{ic|/etc/profile}} then {{ic|~/.profile}}
+
|-
 +
| {{ic|/etc/profile}}
 +
| [[Source]]s application settings in {{ic|/etc/profile.d/*.sh}} and {{ic|/etc/bash.bashrc}}.
 +
| {{Yes}}
 +
| {{No}}
 +
|-
 +
| {{ic|~/.bash_profile}}
 +
| Per-user, after {{ic|/etc/profile}}. If this file does not exist, {{ic|~/.bash_login}} and {{ic|~/.profile}} are checked in that order. The skeleton file {{ic|/etc/skel/.bash_profile}} also sources {{ic|~/.bashrc}}.
 +
| {{Yes}}
 +
| {{No}}
 +
|-
 +
| {{ic|~/.bash_logout}}
 +
| After exit of a login shell.
 +
| {{Yes}}
 +
| {{No}}
 +
|-
 +
| {{ic|/etc/bash.bashrc}}
 +
| Depends on the {{ic|1=-DSYS_BASHRC="/etc/bash.bashrc"}} compilation flag. Sources {{ic|/usr/share/bash-completion/bash_completion}}.
 +
| {{No}}
 +
| {{Yes}}
 +
|-
 +
| {{ic|~/.bashrc}}
 +
| Per-user, after {{ic|/etc/bash.bashrc}}.
 +
| {{No}}
 +
| {{Yes}}
 +
|}
  
But, in Arch, by default:
+
{{Note|
* {{ic|/etc/profile}} (indirectly) sources {{ic|/etc/bash.bashrc}}
+
* Login shells can be non-interactive when called with the {{ic|--login}} argument.
* {{ic|/etc/skel/.bash_profile}} which users are encouraged to copy to {{ic|~/.bash_profile}}, sources {{ic|~/.bashrc}}
+
* While interactive, ''non-login'' shells do '''not''' source {{ic|~/.bash_profile}}, they still inherit the environment from their parent process (which may be a login shell). See [[GregsWiki:ProcessManagement#On processes, environments and inheritance]] for details.
which means that {{ic|/etc/bash.bashrc}} and {{ic|~/.bashrc}} will be executed for all interactive shells, whether they are login shells or not.
+
}}
  
Examples of the user dotfiles can be found in {{ic|/etc/skel/}}.
+
=== Shell and environment variables ===
  
{{Note|legacy mode is when invoked with the name {{Ic|sh}}}}
+
The behavior of Bash and programs run by it can be influenced by a number of environment variables. [[Environment variables]] are used to store useful values such as command search directories, or which browser to use. When a new shell or script is launched it inherits its parent's variables, thus starting with an internal set of shell variables[http://www.kingcomputerservices.com/unix_101/understanding_unix_shells_and_environment_variables.htm ].
  
===Shell and environment variables===
+
These shell variables in Bash can be exported in order to become environment variables:
The behavior of bash and programs run by it can be influenced by a number of environment variable. Environment variables are used to store useful values such as command search directories, or which browser to use. When a new shell or script is launched it inherits its parent's variables, thus starting with an internal set of shell variables[http://www.kingcomputerservices.com/unix_101/understanding_unix_shells_and_environment_variables.htm ].
 
  
These shell variables in bash can be exported in order to become environment variables:
 
 
  VARIABLE=content
 
  VARIABLE=content
 
  export VARIABLE
 
  export VARIABLE
 +
 
or with a shortcut
 
or with a shortcut
 +
 
  export VARIABLE=content
 
  export VARIABLE=content
  
Environment variables are conventionally placed in {{ic|~/.profile}} or {{ic|/etc/profile}} so that all bourne-compatible shells can use them.
+
Environment variables are conventionally placed in {{ic|~/.profile}} or {{ic|/etc/profile}} so that other Bourne-compatible shells can use them.
 +
 
 +
See [[Environment variables]] for more general information.
 +
 
 +
== Command line ==
 +
 
 +
Bash command line is managed by the separate library called [[Readline]]. Readline provides [[emacs]] and [[vi]] styles of shortcuts for interacting with the command line, i.e. moving back and forth on the word basis, deleting words etc. It is also Readline's responsibility to manage [[Readline#History|history]] of input commands. Last, but not least, it allows you to create [[Readline#Macros|macros]].
 +
 
 +
=== Tab completion ===
 +
 
 +
[[Wikipedia:Command-line_completion|Tab completion]] is the option to auto-complete typed commands by pressing {{ic|Tab}} (enabled by default).
 +
 
 +
==== Single-tab ====
 +
 
 +
It may require up to three tab-presses to show all possible completions for a command. To reduce the needed number of tab-presses, see [[Readline#Faster completion]].
 +
 
 +
==== Common programs and options ====
 +
 
 +
By default, Bash only tab-completes commands, filenames, and variables.  The package {{Pkg|bash-completion}} extends this by adding more specialized tab completions for common commands and their options, which can be enabled by sourcing {{ic|/usr/share/bash-completion/bash_completion}}. With {{Pkg|bash-completion}}, normal completions (such as {{ic|$ ls file.*<tab><tab>}}) will behave differently; however, they can be re-enabled with {{ic|$ compopt -o bashdefault ''program''}} (see [https://bbs.archlinux.org/viewtopic.php?id=128471] and [https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html] for more detail).
 +
 
 +
==== Customize per-command ====
 +
 
 +
{{Note|Using the {{ic|complete}} builtin may cause conflicts with {{Pkg|bash-completion}}.}}
 +
 
 +
By default Bash only tab-completes file names following a command. You can change it to complete command names using {{ic|complete -c}}:
 +
{{hc|~/.bashrc|
 +
complete -c man which
 +
}}
 +
or complete command names and file names with {{ic|-cf}}:
 +
{{bc|complete -cf sudo}}
 +
See the Bash man page for more completion options.
 +
 
 +
=== History ===
 +
 
 +
==== History completion ====
 +
 
 +
You can bind the up and down arrow keys to search through Bash's history (see: [[Readline#History]] and [https://www.gnu.org/software/bash/manual/html_node/Readline-Init-File-Syntax.html Readline Init File Syntax]):
  
See [[Environment Variables]] for more general information.
+
{{hc|~/.bashrc|
 +
bind '"\e[A": history-search-backward'
 +
bind '"\e[B": history-search-forward'
 +
}}
  
==Command line==
+
or to affect all readline programs:
Bash command line is managed by the separate library called [[Readline]]. Readline provides a lot of shortcuts for interacting with the command line i.e. moving back and forth on the word basis, deleting words etc. It is also Readline's responsibility to manage [[Readline#History|history]] of input commands. Last, but not least, it allows you to create [[Readline#Macros|macros]].
 
  
==Aliases==
+
{{hc|~/.inputrc|
[[Wikipedia:alias|alias]] is a command, which enables a replacement of a word with another string. It is often used for abbreviating a system command, or for adding default arguments to a regularly used command.
+
"\e[A": history-search-backward
 +
"\e[B": history-search-forward
 +
}}
  
Personal aliases are preferably stored in {{ic|~/.bashrc}}, and system-wide aliases (which affect all users) belong in {{ic|/etc/bash.bashrc}}.
+
==== Shorter history ====
  
An example excerpt from {{ic|~/.bashrc}} covering several time-saving aliases:
+
The {{ic|HISTCONTROL}} variable can prevent certain commands from being logged to the history. For example, to stop logging of repeated identical commands
{{hc|~/.bashrc
+
{{hc|~/.bashrc|2=export HISTCONTROL=ignoredups}}
|2=<nowiki>
+
or set it to {{ic|erasedups}} to ensure that Bash's history will only contain one copy of each command (regardless of order). See the Bash man page for more options.
# modified commands
 
alias diff='colordiff'              # requires colordiff package
 
alias grep='grep --color=auto'
 
alias more='less'
 
alias df='df -h'
 
alias du='du -c -h'
 
alias mkdir='mkdir -p -v'
 
alias nano='nano -w'
 
alias ping='ping -c 5'
 
alias ..='cd ..'
 
  
# new commands
+
==== Disable history ====
alias da='date "+%A, %B %d, %Y [%T]"'
 
alias du1='du --max-depth=1'
 
alias hist='history | grep $1'      # requires an argument
 
alias openports='netstat --all --numeric --programs --inet --inet6'
 
alias pg='ps -Af | grep $1'        # requires an argument (note: /usr/bin/pg is installed by the util-linux package; maybe a different alias name should be used)
 
  
# privileged access
+
To disable the bash history only temporarily:
if [ $UID -ne 0 ]; then
 
    alias sudo='sudo '
 
    alias scat='sudo cat'
 
    alias svim='sudo vim'
 
    alias root='sudo su'
 
    alias reboot='sudo reboot'
 
    alias halt='sudo halt'
 
    alias update='sudo pacman -Su'
 
    alias netcfg='sudo netcfg2'
 
fi
 
  
# ls
+
set +o history
alias ls='ls -hF --color=auto'
 
alias lr='ls -R'                    # recursive ls
 
alias ll='ls -l'
 
alias la='ll -A'
 
alias lx='ll -BX'                  # sort by extension
 
alias lz='ll -rS'                  # sort by size
 
alias lt='ll -rt'                  # sort by date
 
alias lm='la | more'
 
  
# safety features
+
The commands entered now are not logged to the {{ic|$HISTFILE}}.
alias cp='cp -i'
 
alias mv='mv -i'
 
alias rm='rm -I'                    # 'rm -i' prompts for every file
 
alias ln='ln -i'
 
alias chown='chown --preserve-root'
 
alias chmod='chmod --preserve-root'
 
alias chgrp='chgrp --preserve-root'
 
  
# pacman aliases (if applicable, replace 'pacman' with your favorite AUR helper)
+
For example, now you can hash passwords with {{ic|<nowiki>printf secret | sha256sum</nowiki>}}, or hide GPG usage like {{ic|gpg -eaF secret-pubkey.asc}}
alias pac="pacman -S"      # default action    - install one or more packages
+
and your secret is not written to disk.
alias pacu="pacman -Syu"  # '[u]pdate'        - upgrade all packages to their newest version
 
alias pacs="pacman -Ss"    # '[s]earch'        - search for a package using one or more keywords
 
alias paci="pacman -Si"    # '[i]nfo'          - show information about a package
 
alias pacr="pacman -R"    # '[r]emove'        - uninstall one or more packages
 
alias pacl="pacman -Sl"    # '[l]ist'          - list all packages of a repository
 
alias pacll="pacman -Qqm"  # '[l]ist [l]ocal'  - list all packages which were locally installed (e.g. AUR packages)
 
alias paclo="pacman -Qdt"  # '[l]ist [o]rphans' - list all packages which are orphaned
 
alias paco="pacman -Qo"    # '[o]wner'          - determine which package owns a given file
 
alias pacf="pacman -Ql"    # '[f]iles'          - list all files installed by a given package
 
alias pacc="pacman -Sc"    # '[c]lean cache'    - delete all not currently installed package files
 
alias pacm="makepkg -fci"  # '[m]ake'          - make package from PKGBUILD file in current directory
 
</nowiki>}}
 
  
==Functions==
+
To enable history:
Bash also support functions. The following function will extract a wide range of compressed file types. Add the function to {{ic|~/.bashrc}} and use it with the syntax {{Ic|extract <file1> <file2> ...}}
 
  
{{hc|~/.bashrc
+
set -o history
|2=<nowiki>
 
extract() {
 
    local c e i
 
  
    (($#)) || return
+
{{Tip|If the {{ic|HISTCONTROL}} variable contains {{ic|ignorespace}}, commands starting with a space will not be saved into the history file. See {{man|1|bash|Shell Variables}} for details.}}
  
    for i; do
+
To disable all bash history:
        c=''
 
        e=1
 
  
        if [[ ! -r $i ]]; then
+
{{hc|~/.bashrc or /etc/profile|
            echo "$0: file is unreadable: \`$i'" >&2
+
<nowiki>export HISTSIZE=0</nowiki>
            continue
+
}}
        fi
 
  
        case $i in
+
... and just to make sure:
        *.t@(gz|lz|xz|b@(2|z?(2))|a@(z|r?(.@(Z|bz?(2)|gz|lzma|xz)))))
 
              c='bsdtar xvf';;
 
        *.7z)  c='7z x';;
 
        *.Z)  c='uncompress';;
 
        *.bz2) c='bunzip2';;
 
        *.exe) c='cabextract';;
 
        *.gz)  c='gunzip';;
 
        *.rar) c='unrar x';;
 
        *.xz)  c='unxz';;
 
        *.zip) c='unzip';;
 
        *)    echo "$0: unrecognized file extension: \`$i'" >&2
 
              continue;;
 
        esac
 
  
        command $c "$i"
+
# warning. this will destroy your old histfile forever
        e=$?
+
wipe -i -l2 -x4 -p4 "$HISTFILE"
    done
+
ln -sv /dev/null "$HISTFILE"
  
    return $e
+
=== Mimic Zsh run-help ability ===
}
 
</nowiki>}}
 
  
{{note|[[Bash]] users should make sure extglob is enabled: {{Ic|shopt -s extglob}}, for example by adding it to the {{ic|.bashrc}}. It is enabled by default if using [[Bash#Advanced completion|Bash completion]]. [[Zsh]] users should do: {{Ic|setopt kshglob}} instead.}}
+
[[Zsh]] can invoke the manual for the command preceding the cursor by pressing {{ic|Alt+h}}.
Another way to do this is to install the {{AUR|unp}} package from aur which contains a perl script.
+
A similar behaviour is obtained in Bash using this [[Readline]] bind:
 +
{{hc|~/.bashrc|
 +
bind '"\eh": "\C-a\eb\ed\C-y\e#man \C-y\C-m\C-p\C-p\C-a\C-d\C-e"'
 +
}}
 +
This assumes are you using the (default) Emacs [[Readline#Editing mode|editing mode]].
  
Very often changing to a directory is followed by the 'ls' command to list its contents. Therefore it is helpful to have a second function doing both at once.
+
== Aliases ==
In this example we will name it 'cl' and show an error message if the specified directory does not exist.
 
{{hc|~/.bashrc
 
|2=<nowiki>
 
cl()
 
{
 
if [ -d $1 ]; then
 
cd $1
 
ls
 
else
 
echo "bash: cl: $1: Directory not found"
 
fi
 
}
 
</nowiki>}}
 
Of course the ls command can be altered to fit your needs, for example 'ls -hall --color=auto'.
 
  
More bash function examples can be found [https://bbs.archlinux.org/viewtopic.php?id=30155 here.]
+
[[Wikipedia:Alias_(command)|alias]] is a command, which enables a replacement of a word with another string. It is often used for abbreviating a system command, or for adding default arguments to a regularly used command.  
  
==Tips and tricks==
+
Personal aliases are preferably stored in {{ic|~/.bashrc}}, and system-wide aliases (which affect all users) belong in {{ic|/etc/bash.bashrc}}. See [https://gist.github.com/anonymous/a9055e30f97bd19645c2] for example aliases.
===Prompt customization===
 
The bash prompt is governed by the variable {{Ic|$PS1}}. To colorize the bash prompt, first comment out the default {{Ic|$PS1}}:
 
#PS1='[\u@\h \W]\$ '
 
Then add the following line:
 
PS1='\[\e[0;31m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[0;31m\]\$ \[\e[m\]\[\e[0;32m\] '
 
This {{Ic|$PS1}} is useful for a root bash prompt, with red designation and green console text. For details on customizing your bash prompt, see [[Color Bash Prompt]].
 
  
===Auto-completion===
+
For functions, see [[Bash/Functions]].
It is useful to have the auto-complete feature (pressing {{Keypress|Tab}} key twice on the keyboard) after you type some command like sudo.
 
  
To do this add a line in this format to your {{ic|~/.bashrc}} file:
+
== Tips and tricks ==
complete -cf your_command
 
  
For example, to enable auto-complete after sudo and man:
+
=== Prompt customization ===
complete -cf sudo
 
complete -cf man
 
  
====Advanced completion====
+
See [[Bash/Prompt customization]].
Despite Bash's native support for basic file name, command, and variable auto-completion, there are ways of improving and extending its reach.
 
  
The {{Pkg|bash-completion}} package extends functionality by adding auto-completion to a wide range of commands and their options. Enabling advanced bash completion is quite simple, just install the following package:
+
=== Command not found ===
# pacman -S bash-completion
 
Start a new shell and it will be automatically enabled thanks to {{ic|/etc/bash.bashrc}}.
 
{{Note|If you added any lines similar to "complete -cf sudo" as mentioned in the previous settings and have problems with bash-completion, try removing those lines.}}
 
  
{{Note|1=The normal expansions that you are used to like "$ ls file.*<tab><tab>" will not work unless you "$ compopt -o bashdefault <prog>" for all programs you want to fallback to the normal glob expansions. See https://bbs.archlinux.org/viewtopic.php?id=128471 and https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html}}
+
[[pkgfile]] includes a "command not found" hook that will automatically search the official repositories, when entering an unrecognized command.
  
====Faster completion====
+
You need to [[source]] the hook to enable it, for example:
By appending the following into the readline initialization file ({{ic|~/.inputrc}} or {{ic|/etc/inputrc}} by default):
 
set show-all-if-ambiguous on
 
it is no longer necessary to hit {{Keypress|Tab}} (default binding) twice to produce a list of all possible completions (both when a partial completion is possible and when no completion is possible), as a single key-press will suffice. Alternatively, to produce such a list only when no completion is possible (i.e., not when a partial completion is possible), append the following command in lieu of the previous one:
 
set show-all-if-unmodified on
 
  
=== The "command not found" hook ===
+
{{hc|~/.bashrc|
The [[pkgfile]] package includes a "command not found" hook that will automatically search the [[official repositories]] when you enter an unrecognized command. Then it will display something like this:
+
source /usr/share/doc/pkgfile/command-not-found.bash}}
<div style="font-family: monospace; white-space: pre; overflow: auto; margin: 1em 3em; padding: 1em; border: 3px solid #bcd; background-color: black; color: #aaa;"><span style="color: #0a0">chiri</span> <span style="color: #00f">~/docs</span> <span style="color: #0f0">$</span> abiword<nowiki>
+
 
 +
Then attempting to run an unavailable command will show the following info:
 +
 
 +
{{hc|$ abiword|
 
abiword may be found in the following packages:
 
abiword may be found in the following packages:
   extra/abiword 2.8.6-7 usr/bin/abiword
+
   extra/abiword 3.0.1-2 /usr/bin/abiword
</nowiki><span style="color: #0a0">chiri</span> <span style="color: #00f">~/docs</span> <span style="color: #0f0">$</span> <span style="text-decoration: blink;">_</span></div>
+
}}
 +
 
 +
{{Note|The pkgfile database may need to be updated before this will work.  See [[pkgfile#Installation]] for details.}}
 +
 
 +
An alternative "command not found" hook is provided by {{AUR|command-not-found}}, which looks like this:
  
An alternative "command not found" hook is also provided by the AUR package [https://aur.archlinux.org/packages.php?ID=52305 command-not-found], which will generate an output like the following:
+
{{hc|$ abiword|
 +
The command 'abiword' is provided by the following packages:
 +
'''abiword''' (2.8.6-7) from extra
 +
[ abiword ]
 +
'''abiword''' (2.8.6-7) from staging
 +
[ abiword ]
 +
'''abiword''' (2.8.6-7) from testing
 +
[ abiword ]
 +
}}
  
<div style="font-family: monospace; white-space: pre; overflow: auto; margin: 1em 3em; padding: 1em; border: 3px solid #bcd; background-color: black; color: #aaa;"><span style="color: #0a0">chiri</span> <span style="color: #00f">~/docs</span> <span style="color: #0f0">$</span> abiword
+
=== Disable Ctrl+z in terminal ===
The command 'abiword' is been provided by the following packages:
+
 
<span style="font-weight: bold">abiword</span> (2.8.6-7) from extra<nowiki>
+
You can disable the {{ic|Ctrl+z}} feature (pauses/closes your application) by wrapping your command like this:
</nowiki>[ <span style="color: #bb0000">abiword</span> ]
 
<span style="font-weight: bold">abiword</span> (2.8.6-7) from staging<nowiki>
 
</nowiki>[ <span style="color: #bb0000">abiword</span> ]
 
<span style="font-weight: bold">abiword</span> (2.8.6-7) from testing<nowiki>
 
</nowiki>[ <span style="color: #bb0000">abiword</span> ]
 
<span style="color: #0a0">chiri</span> <span style="color: #00f">~/docs</span> <span style="color: #0f0">$</span> <span style="text-decoration: blink;">_</span></div>
 
  
=== Disable Ctrl+z in terminal===
 
You can disable {{Keypress|Ctrl+z}} (pauses/closes your CLI application) feature for you CLI by wrapping your command in this script
 
 
  #!/bin/bash
 
  #!/bin/bash
 
  trap "" 20
 
  trap "" 20
  /path_to_your_application/
+
  ''adom''
example:
+
 
#!/bin/bash
+
Now when you accidentally press {{ic|Ctrl+z}} in {{AUR|adom}} instead of {{ic|Shift+z}} nothing will happen because {{ic|Ctrl+z}} will be ignored.
trap "" 20
+
 
/usr/bin/adom
+
=== Clear the screen after logging out ===
  
With this example script, when you accidentally press {{Keypress|Ctrl+z}} instead of {{Keypress|Shift+z}} or some other key combination while playing Adom(game) your game will not end. Nothing will happen because {{Keypress|Ctrl+z}} will be ignored.
+
To clear the screen after logging out on a virtual terminal:
 +
{{hc|~/.bash_logout|
 +
clear
 +
reset
 +
}}
  
===Clear the screen after logging out===
+
=== Auto "cd" when entering just a path ===
To clear the screen after logging out on a virtual terminal, append the following lines to {{ic|~/.bash_logout}}:
 
clear
 
reset
 
  
===ASCII art, fortunes and cowsay===
+
Bash can automatically prepend {{ic|cd }} when entering just a path in the shell. For example:
Along with colors, system info and ASCII symbols, Bash can be made to display a piece of ASCII art on login.  ASCII images can be found online and pasted into a text file, or generated from scratch.  To set the image to display in a terminal on login, place the string
+
{{hc|$ /etc|
cat /path/to/text/file
+
bash: /etc: Is a directory
at the top of {{ic|~/.bashrc}}.
+
}}
  
Random poignant, inspirational, silly or snide phrases can also be shown.  To see an example, install the {{Pkg|fortune-mod}} package from the {{Ic|extra}} repository.
+
But after adding one line into {{ic|.bashrc}} file:
 +
{{hc|~/.bashrc|
 +
...
 +
shopt -s autocd
 +
...
 +
}}
  
{{bc|1=
+
You get:
'''<font color=red>(</font><font color=green>user@host</font><font color=red>)-(</font><font color=green>10:10 AM Wed Dec 22</font><font color=red>)'''
+
[user@host ~]$ /etc
--(</font><font color=green>~</font><font color=red>)---> </font> fortune
+
cd /etc
<br/>
+
[user@host etc]$
It is Texas law that when two trains meet each other at a railroad crossing,
 
each shall come to a full stop, and neither shall proceed until the other has gone.}}
 
  
To have a random  phrase displayed when logging into a terminal, just set
+
=== Autojump ===
command fortune
 
as the top line in {{ic|~/.bashrc}}.
 
  
{{Note|By default, {{Ic|fortune}} displays quotes and phrases that are rather inoccuous. However, the package does contain a set of comments some will find offensive, located in {{ic|/usr/share/fortune/off}}. See the man page for more info on these.}}
+
{{Pkg|autojump}} allows navigating the file system by searching for strings in a database with the user's most-visited paths.
  
These two features can be combined, using the program {{Pkg|cowsay}}. Modify the line at the top of {{ic|~/.bashrc}} to read
+
After installation, {{ic|/etc/profile.d/autojump.bash}} must be [[source]]d in order to start using the application.
command cowsay $(fortune)
 
  
or
+
=== Prevent overwrite of files ===
command cowthink $(fortune)
 
  
+
For the current session, to disallow existing regular files to be overwritten by redirection of shell output:
The earth is like a tiny grain of sand,
 
only much, much heavier.               
 
-----------------------------------------
 
        \  ^__^
 
        \  (oo)\_______
 
            (__)\      )\/\
 
                ||----w |
 
                ||    ||
 
  
The ASCII images are generated by {{ic|.cow}} text files located in {{ic|/usr/share/cows}}, and all themes can be listed with the command {{Ic|cowsay -l}} These files can be edited to the user's liking; custom images can also be created from scratch or found on the net. The easiest way create a custom cow file from an image found online would be to open an existing {{ic|.cow}} file in a text editor, copy-and-paste the image from a browser and save the file as a different name.  Test the custom file using
+
  $ set -o noclobber
  
# cowsay -f {{ic|cowfile}} $(fortune)
+
This is identical to {{ic|set -C}}.
  
This can produce some nice eye candy, and the commands used can be more complex.  For a specialized example, take a look [http://bambambambam.wordpress.com/2009/07/04/futurama-ascii-with-slashdot-header-quotes-in-your-terminal/ here.]  Another example, to use a random cow, random facial expression, and nicely wrap the text of long fortunes.
+
To make the changes persistent for your user:
  
fortune -a | fmt -80 -s | cowsay -$(shuf -n 1 -e b d g p s t w y) -f $(shuf -n 1 -e $(cowsay -l | tail -n +2)) -n
+
{{hc|~/.bashrc|output=...
 +
set -o noclobber}}
  
  ________________________________________
+
To manually overwrite a file while {{ic|noclobber}} is set:
( Fry: I must be a robot. Why else would )
 
( human women refuse to date me?        )
 
----------------------------------------
 
        o
 
          o
 
            o 
 
              ,'``.._  ,'``.
 
              :,--._:)\,:,._,.:
 
              :`--,''@@@:`...';\       
 
              `,'@@@@@@@`---'@@`.   
 
              /@@@@@@@@@@@@@@@@@:
 
              /@@@@@@@@@@@@@@@@@@@\
 
            ,'@@@@@@@@@@@@@@@@@@@@@:\.___,-.
 
          `...,---'``````-..._@@@@|:@@@@@@@\
 
            (                )@@@;:@@@@)@@@\  _,-.
 
              `.              (@@@//@@@@@@@@@@`'@@@@\
 
              :              `.//@@)@@@@@@)@@@@@,@;
 
              |`.            _,'/@@@@@@@)@@@@)@,'@,'
 
              :`.`-..____..=:.-':@@@@@.@@@@@_,@@,'
 
              ,'\ ``--....-)='    `._,@@\    )@@@'``._
 
            /@_@`.      (@)      /@@@@@)  ; / \ \`-.'
 
            (@@@`-:`.    `' ___..'@@_,-'  |/  `.)
 
            `-. `.`.``-----``--,@@.'
 
              |/`.\`'        ,',');
 
                  `        (/  (/
 
'''<font color=red>(</font><font color=green>user@host</font><font color=red>)-(</font><font color=green>10:10 AM Wed Dec 22</font><font color=red>)'''--(</font><font color=green>~</font>)<font color=red>)---></font>
 
  
{{Note|If you want a full colored cowsay-like art, the best option is {{Pkg|ponysay}}, this show full colored ponies (more than 220 at version 1.1) in you terminal (inside X11 or in TTY you have full 256 colored ponies) runing 'ponysay "command or fortune command"', the complete list of ponies are showed usind 'ponysay -l'.
+
$ echo "output" >| file.txt
Exist in AUR a tool for creating more ponies (or other stuff) called {{aur|util-say-git}}, and these news archives need to be stored in $HOME/.local/share/ponysay/ponies and $HOME/.local/share/ponysay/ttyponies for desktop and TTY respectibely}}
 
  
===ASCII Historical Calendar===
+
== Troubleshooting ==
To install [http://www.openbsd.org/cgi-bin/man.cgi?query=calendar&sektion=1 calendar] files in your {{ic|~/.calendar}} directory you will need the {{Pkg|rpmextract}} package installed. Then from your home directory, run the following:
 
$ mkdir -p ~/.calendar
 
$ curl -o calendar.rpm http://download.fedora.redhat.com/pub/epel/5/x86_64/calendar-1.25-4.el5.x86_64.rpm
 
$ rpm2cpio calendar.rpm | bsdtar -C ~/.calendar --strip-components=4 -xf - ./usr/share/c*
 
  
This will then print out the calendar items
+
=== Line wrap on window resize ===
$ sed -n "/$(date +%m\\/%d\\\|%b\*\ %d)/p" $(find ~/.calendar /usr/share/calendar -maxdepth 1 -type f -name 'c*' 2>/dev/null);
 
  
===Customise Title===
+
When resizing a [[terminal emulator]], Bash may not receive the resize signal. This will cause typed text to not wrap correctly and overlap the prompt. The {{ic|checkwinsize}} shell option checks the window size after each command and, if necessary, updates the values of {{ic|LINES}} and {{ic|COLUMNS}}.
  
The {{ic|$PROMPT_COMMAND}} variable allows you to execute a command before the prompt. For example, this will change the title to your full current working directory:
+
{{hc|~/.bashrc|
 +
shopt -s checkwinsize
 +
}}
  
export PROMPT_COMMAND='echo -ne "\033]0;$PWD\007"'
+
=== Shell exits even if ignoreeof set ===
  
This will change your title to the last command run, and make sure your history file is always up-to-date:
+
If you have set the {{ic|ignoreeof}} option and you find that repeatedly hitting {{ic|ctrl-d}} causes the shell to exit, it is because this option only allows 10 consecutive invocations of this keybinding (or 10 consecutive EOF characters, to be precise), before exiting the shell.
export HISTCONTROL=ignoreboth
 
export HISTIGNORE='history*'
 
export PROMPT_COMMAND='history -a;echo -en "\e]2;";history 1|sed "s/^[ \t]*[0-9]\{1,\}  //g";echo -en "\e\\";
 
  
===Fix line wrap on window resize===
+
To allow higher values, you have to use the IGNOREEOF variable.
  
When you resize your xterm in vi for example, Bash will not get the resize signal, and the text you type will not wrap correctly, overlapping the prompt.
+
For example:
 +
export IGNOREEOF=100
  
Use the following in your {{ic|/etc/bash.bashrc}} (from Debian) :
+
== See also ==
# check the window size after each command and, if necessary,
 
# update the values of LINES and COLUMNS.
 
shopt -s checkwinsize
 
  
===Bash history completion===
+
* [[Wikipedia:Bash (Unix shell)]]
Bash history completion bound to arrow keys (down, up):
+
* [https://www.gnu.org/software/bash/manual/bashref.html Bash Reference Manual], or {{ic|/usr/share/doc/bash/bashref.html}}
# ~/.bashrc
+
* [https://www.gnu.org/software/bash/manual/html_node/Readline-Init-File-Syntax.html Readline Init File Syntax]
bind '"\e[A": history-search-backward'
+
* [http://www.aosabook.org/en/bash.html The Bourne-Again Shell] - The third chapter of ''The Architecture of Open Source Applications''
bind '"\e[B": history-search-forward'
+
* [http://shellcheck.net Shellcheck] - Check bash scripts for common errors (based on [https://github.com/koalaman/shellcheck shellcheck])
or equivalently in {{ic|~/.inputrc}}:
+
* [http://bashrcgenerator.com/ PS1 generator] - generate your .bashrc/PS1 bash prompt with a drag and drop interface
# ~/.inputrc
+
* [https://serverfault.com/questions/3743/what-useful-things-can-one-add-to-ones-bashrc Even more useful .bashrc commands]  
"\e[A": history-search-backward
+
=== Tutorials ===
"\e[B": history-search-forward
 
More info at [[Readline#History]] and [https://www.gnu.org/software/bash/manual/html_node/Readline-Init-File-Syntax.html]
 
  
==See also==
+
* [[GregsWiki:|Greg's Wiki]]
* [http://tldp.org/LDP/abs/html/ Advanced Bash Scripting Guide] - Very good resource regarding shell scripting using bash
+
* [[GregsWiki:BashGuide]]
* [http://www.gnu.org/software/bash/manual/bashref.html Bash Reference Manual] - Official reference (654K)
+
* [[GregsWiki:BashFAQ]]
* [http://wiki.bash-hackers.org/doku.php Bash Hackers Wiki] - Excellent Bash Wiki
+
* [http://wiki.bash-hackers.org/doku.php Bash Hackers Wiki]
* [http://bashscripts.org Bashscripts.org] - Forum for bash coders.
+
* [http://wiki.bash-hackers.org/scripting/tutoriallist Bash Hackers Wiki: List of Bash online tutorials]
* [http://www.ibm.com/developerworks/linux/library/l-bash.html Bash Scripting by Example]
 
* [http://www.caliban.org/bash Completion Guide]
 
* [http://wooledge.org/mywiki/BashFaq Greg's Wiki] - Highly recommended
 
* [http://www.gnu.org/software/bash/manual/bash.html man page]
 
 
* [http://www.grymoire.com/Unix/Quote.html Quote Tutorial]
 
* [http://www.grymoire.com/Unix/Quote.html Quote Tutorial]
* irc://irc.freenode.net#bash - Active and friendly Internet Relay Chat channel for Bash.
+
 
* http://chakra-project.org/wiki/index.php/Startup_files
+
=== Community ===
* [http://www.aosabook.org/en/bash.html The Bourne-Again Shell] - The third chapter of ''The Architecture of Open Source Applications''
+
 
 +
* [ircs://chat.freenode.net#bash An active and friendly IRC channel for Bash]
 +
 
 +
=== Examples ===
 +
 
 
* [http://tldp.org/HOWTO/Xterm-Title-4.html How to change the title of an xterm]
 
* [http://tldp.org/HOWTO/Xterm-Title-4.html How to change the title of an xterm]
* [http://wiki.gotux.net/bash:arc Create and Extract Various Archives]
 
* [http://www.gnu.org/software/bash/manual/html_node/Readline-Init-File-Syntax.html Readline Init File Syntax ]
 

Latest revision as of 17:09, 18 April 2019

Bash (Bourne-again Shell) is a command-line shell/programming language by the GNU Project. Its name is a homaging reference to its predecessor, the long-deprecated Bourne shell. Bash can be run on most UNIX-like operating systems, including GNU/Linux.

Bash is the default command-line shell on Arch Linux.

Invocation

Bash behaviour can be altered depending on how it is invoked. Some descriptions of different modes follow.

If Bash is spawned by login in a TTY, by an SSH daemon, or similar means, it is considered a login shell. This mode can also be engaged using the -l/--login command line option.

Bash is considered an interactive shell when its standard input and error are connected to a terminal (for example, when run in a terminal emulator), and it is not started with the -c option or non-option arguments (for example, bash script). All interactive shells source /etc/bash.bashrc and ~/.bashrc, while interactive login shells also source /etc/profile and ~/.bash_profile.

Note: In Arch /bin/sh (which used to be the Bourne shell executable) is symlinked to /bin/bash. If Bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh, including POSIX compability.

Configuration files

See section "6.2 Bash Startup Files" in /usr/share/doc/bash/bashref.html (online link) and GregsWiki:DotFiles for a complete description.

File Description Login shells (see note) Interactive, non-login shells
/etc/profile Sources application settings in /etc/profile.d/*.sh and /etc/bash.bashrc. Yes No
~/.bash_profile Per-user, after /etc/profile. If this file does not exist, ~/.bash_login and ~/.profile are checked in that order. The skeleton file /etc/skel/.bash_profile also sources ~/.bashrc. Yes No
~/.bash_logout After exit of a login shell. Yes No
/etc/bash.bashrc Depends on the -DSYS_BASHRC="/etc/bash.bashrc" compilation flag. Sources /usr/share/bash-completion/bash_completion. No Yes
~/.bashrc Per-user, after /etc/bash.bashrc. No Yes
Note:

Shell and environment variables

The behavior of Bash and programs run by it can be influenced by a number of environment variables. Environment variables are used to store useful values such as command search directories, or which browser to use. When a new shell or script is launched it inherits its parent's variables, thus starting with an internal set of shell variables[1].

These shell variables in Bash can be exported in order to become environment variables:

VARIABLE=content
export VARIABLE

or with a shortcut

export VARIABLE=content

Environment variables are conventionally placed in ~/.profile or /etc/profile so that other Bourne-compatible shells can use them.

See Environment variables for more general information.

Command line

Bash command line is managed by the separate library called Readline. Readline provides emacs and vi styles of shortcuts for interacting with the command line, i.e. moving back and forth on the word basis, deleting words etc. It is also Readline's responsibility to manage history of input commands. Last, but not least, it allows you to create macros.

Tab completion

Tab completion is the option to auto-complete typed commands by pressing Tab (enabled by default).

Single-tab

It may require up to three tab-presses to show all possible completions for a command. To reduce the needed number of tab-presses, see Readline#Faster completion.

Common programs and options

By default, Bash only tab-completes commands, filenames, and variables. The package bash-completion extends this by adding more specialized tab completions for common commands and their options, which can be enabled by sourcing /usr/share/bash-completion/bash_completion. With bash-completion, normal completions (such as $ ls file.*<tab><tab>) will behave differently; however, they can be re-enabled with $ compopt -o bashdefault program (see [2] and [3] for more detail).

Customize per-command

Note: Using the complete builtin may cause conflicts with bash-completion.

By default Bash only tab-completes file names following a command. You can change it to complete command names using complete -c:

~/.bashrc
complete -c man which

or complete command names and file names with -cf:

complete -cf sudo

See the Bash man page for more completion options.

History

History completion

You can bind the up and down arrow keys to search through Bash's history (see: Readline#History and Readline Init File Syntax):

~/.bashrc
 bind '"\e[A": history-search-backward'
 bind '"\e[B": history-search-forward'

or to affect all readline programs:

~/.inputrc
"\e[A": history-search-backward
"\e[B": history-search-forward

Shorter history

The HISTCONTROL variable can prevent certain commands from being logged to the history. For example, to stop logging of repeated identical commands

~/.bashrc
export HISTCONTROL=ignoredups

or set it to erasedups to ensure that Bash's history will only contain one copy of each command (regardless of order). See the Bash man page for more options.

Disable history

To disable the bash history only temporarily:

set +o history

The commands entered now are not logged to the $HISTFILE.

For example, now you can hash passwords with printf secret | sha256sum, or hide GPG usage like gpg -eaF secret-pubkey.asc and your secret is not written to disk.

To enable history:

set -o history
Tip: If the HISTCONTROL variable contains ignorespace, commands starting with a space will not be saved into the history file. See bash(1) for details.

To disable all bash history:

~/.bashrc or /etc/profile
export HISTSIZE=0

... and just to make sure:

# warning. this will destroy your old histfile forever
wipe -i -l2 -x4 -p4 "$HISTFILE"
ln -sv /dev/null "$HISTFILE"

Mimic Zsh run-help ability

Zsh can invoke the manual for the command preceding the cursor by pressing Alt+h. A similar behaviour is obtained in Bash using this Readline bind:

~/.bashrc
bind '"\eh": "\C-a\eb\ed\C-y\e#man \C-y\C-m\C-p\C-p\C-a\C-d\C-e"'

This assumes are you using the (default) Emacs editing mode.

Aliases

alias is a command, which enables a replacement of a word with another string. It is often used for abbreviating a system command, or for adding default arguments to a regularly used command.

Personal aliases are preferably stored in ~/.bashrc, and system-wide aliases (which affect all users) belong in /etc/bash.bashrc. See [4] for example aliases.

For functions, see Bash/Functions.

Tips and tricks

Prompt customization

See Bash/Prompt customization.

Command not found

pkgfile includes a "command not found" hook that will automatically search the official repositories, when entering an unrecognized command.

You need to source the hook to enable it, for example:

~/.bashrc
source /usr/share/doc/pkgfile/command-not-found.bash

Then attempting to run an unavailable command will show the following info:

$ abiword
abiword may be found in the following packages:
  extra/abiword 3.0.1-2	/usr/bin/abiword
Note: The pkgfile database may need to be updated before this will work. See pkgfile#Installation for details.

An alternative "command not found" hook is provided by command-not-foundAUR, which looks like this:

$ abiword
The command 'abiword' is provided by the following packages:
abiword (2.8.6-7) from extra
	[ abiword ]
abiword (2.8.6-7) from staging
	[ abiword ]
abiword (2.8.6-7) from testing
	[ abiword ]

Disable Ctrl+z in terminal

You can disable the Ctrl+z feature (pauses/closes your application) by wrapping your command like this:

#!/bin/bash
trap "" 20
adom

Now when you accidentally press Ctrl+z in adomAUR instead of Shift+z nothing will happen because Ctrl+z will be ignored.

Clear the screen after logging out

To clear the screen after logging out on a virtual terminal:

~/.bash_logout
clear
reset

Auto "cd" when entering just a path

Bash can automatically prepend cd when entering just a path in the shell. For example:

$ /etc
bash: /etc: Is a directory

But after adding one line into .bashrc file:

~/.bashrc
...
shopt -s autocd
...

You get:

[user@host ~]$ /etc
cd /etc
[user@host etc]$

Autojump

autojump allows navigating the file system by searching for strings in a database with the user's most-visited paths.

After installation, /etc/profile.d/autojump.bash must be sourced in order to start using the application.

Prevent overwrite of files

For the current session, to disallow existing regular files to be overwritten by redirection of shell output:

$ set -o noclobber

This is identical to set -C.

To make the changes persistent for your user:

~/.bashrc
...
set -o noclobber

To manually overwrite a file while noclobber is set:

$ echo "output" >| file.txt

Troubleshooting

Line wrap on window resize

When resizing a terminal emulator, Bash may not receive the resize signal. This will cause typed text to not wrap correctly and overlap the prompt. The checkwinsize shell option checks the window size after each command and, if necessary, updates the values of LINES and COLUMNS.

~/.bashrc
shopt -s checkwinsize

Shell exits even if ignoreeof set

If you have set the ignoreeof option and you find that repeatedly hitting ctrl-d causes the shell to exit, it is because this option only allows 10 consecutive invocations of this keybinding (or 10 consecutive EOF characters, to be precise), before exiting the shell.

To allow higher values, you have to use the IGNOREEOF variable.

For example:

export IGNOREEOF=100

See also

Tutorials

Community

Examples