Getting started
Introduction
This is a quick reference khổng lồ getting started with Bash scripting.
Bạn đang xem: Shell scripting tutorial
Example
#!/usr/bin/env bashNAME="John"echo "Hello $NAME!"
Variables
NAME="John"echo $NAMEecho "$NAME"echo "$NAME!"String quotes
NAME="John"echo "Hi $NAME" #=> Hi Johnecho "Hi $NAME" #=> Hi $NAMEShell execution
echo "I"m in $(pwd)"echo "I"m in `pwd`"# SameSee Command substitutionConditional execution
git commit && git pushgit commit || echo "Commit failed"
Functions
get_name() echo "John"echo "You are $(get_name)"See: FunctionsConditionals
if << -z "$string" >>; then echo "String is empty"elif << -n "$string" >>; then echo "String is not empty"fiSee: Conditionals
Strict mode
set -euo pipefailIFS=$" "See: Unofficial bash strict mode
Brace expansion
echo A,B.js
A,B | Same as A B |
A,B.js | Same as A.js B.js |
1..5 | Same as 1 2 3 4 5 |
Parameter expansions
Basics
name="John"echo $nameecho $name/J/j #=> "john" (substitution)echo $name:0:2 #=> "Jo" (slicing)echo $name::2 #=> "Jo" (slicing)echo $name::-1 #=> "Joh" (slicing)echo $name:(-1) #=> "n" (slicing from right)echo $name:(-2):1 #=> "h" (slicing from right)echo $food:-Cake #=> $food or "Cake"length=2echo $name:0:length #=> "Jo"See: Parameter expansion
STR="/path/to/foo.cpp"echo $STR%.cpp # /path/to/fooecho $STR%.cpp.o # /path/to/foo.oecho $STR%/* # /path/toecho $STR##*. # cpp (extension)echo $STR##*/ # foo.cpp (basepath)echo $STR#*/ # path/to/foo.cppecho $STR##*/ # foo.cppecho $STR/foo/bar # /path/to/bar.cppSTR="Hello world"echo $STR:6:5 # "world"echo $STR: -5:5 # "world"SRC="/path/to/foo.cpp"BASE=$SRC##*/ #=> "foo.cpp" (basepath)DIR=$SRC%$BASE #=> "/path/to/" (dirpath)
Substitution
$FOO%suffix | Remove suffix |
$FOO#prefix | Remove prefix |
$FOO%%suffix | Remove long suffix |
$FOO##prefix | Remove long prefix |
$FOO/from/to | Replace first match |
$FOO//from/to | Replace all |
$FOO/%from/to | Replace suffix |
$FOO/#from/to | Replace prefix |
Comments
# Single line comment: "This is amulti linecomment"Substrings
$FOO:0:3 | Substring (position, length) |
$FOO:(-3):3 | Substring from the right |
Length
$#FOO | Length of $FOO |
Manipulation
STR="HELLO WORLD!"echo $STR, #=> "hELLO WORLD!" (lowercase 1st letter)echo $STR,, #=> "hello world!" (all lowercase)STR="hello world!"echo $STR^ #=> "Hello world!" (uppercase 1st letter)echo $STR^^ #=> "HELLO WORLD!" (all uppercase)Default values
$FOO:-val | $FOO, or val if unset (or null) |
$FOO:=val | Set $FOO to val if unset (or null) |
$FOO:+val | val if $FOO is set (and not null) |
$FOO:?message | Show error message & exit if $FOO is unset (or null) |
Loops
Basic for loop
for i in /etc/rc.*; bởi echo $idone
C-like for loop
for ((i = 0 ; iRanges
for i in 1..5; do echo "Welcome $i"doneWith step sizefor i in 5..50..5; bởi vì echo "Welcome $i"doneReading lines
cat file.txt | while read line; bởi vì echo $linedoneForever
while true; vì chưng ···doneFunctions
Defining functions
myfunc() echo "hello $1"# Same as above (alternate syntax)function myfunc() echo "hello $1"myfunc "John"Returning values
myfunc() local myresult="some value" echo $myresultresult="$(myfunc)"Raising errors
myfunc() return 1if myfunc; then echo "success"else echo "failure"fiArguments
$# | Number of arguments |
$* | All positional arguments (as a single word) |
$ | All positional arguments (as separate strings) |
$1 | First argument |
$_ | Last argument of the previous command |
và $* must be quoted in order to perform as described.Otherwise, they vì chưng exactly the same thing (arguments as separate strings).
See Special parameters.
Conditionals
Conditions
Note that << is actually a command/program that returns either 0 (true) or 1 (false). Any program that obeys the same logic (like all base utils, such as grep(1) or ping(1)) can be used as condition, see examples.
Xem thêm: Các Tướng Không Dùng Mana Trong Lmht Lol, Những Vị Không Cần Mana Trong Lol
<< -z STRING >> | Empty string |
<< -n STRING >> | Not empty string |
<< STRING == STRING >> | Equal |
<< STRING != STRING >> | Not Equal |
<< NUM -eq NUM >> | Equal |
<< NUM -ne NUM >> | Not equal |
<< NUM -lt NUM >> | Less than |
<< NUM -le NUM >> | Less than or equal |
<< NUM -gt NUM >> | Greater than |
<< NUM -ge NUM >> | Greater than or equal |
<< STRING =~ STRING >> | Regexp |
(( NUM | Numeric conditions |
<< -o noclobber >> | If OPTIONNAME is enabled |
<< ! EXPR >> | Not |
<< X && Y >> | And |
<< X || Y >> | Or |
File conditions
<< -e tệp tin >> | Exists |
<< -r tệp tin >> | Readable |
<< -h tệp tin >> | Symlink |
<< -d tệp tin >> | Directory |
<< -w tệp tin >> | Writable |
<< -s file >> | Size is > 0 bytes |
<< -f file >> | File |
<< -x file >> | Executable |
<< FILE1 -nt FILE2 >> | 1 is more recent than 2 |
<< FILE1 -ot FILE2 >> | 2 is more recent than 1 |
<< FILE1 -ef FILE2 >> | Same files |
Example
# Stringif << -z "$string" >>; then echo "String is empty"elif << -n "$string" >>; then echo "String is not empty"else echo "This never happens"fi# Combinationsif << X && Y >>; then ...fi# Equalif << "$A" == "$B" >># Regexif << "A" =~ . >>if (( $a if << -e "file.txt" >>; then echo "file exists"fi
Arrays
Defining arrays
Fruits=("Apple" "Banana" "Orange")Fruits<0>="Apple"Fruits<1>="Banana"Fruits<2>="Orange"Working with arrays
echo $Fruits<0> # Element #0echo $Fruits<-1> # Last elementecho $Fruits<> # Number of elementsecho $#Fruits # String length of the 1st elementecho $#Fruits<3> # String length of the Nth elementecho $Fruits<
>"; vì chưng echo $idone
Dictionaries
Defining
declare -A soundssoundsWorking with dictionaries
echo $sounds
> # Number of elementsunset soundsIteration
Iterate over valuesfor val in "$sounds<
>"; do echo $keydoneOptions
Options
set -o noclobber # Avoid overlay files (echo "hi" > foo)set -o errexit # Used khổng lồ exit upon error, avoiding cascading errorsset -o pipefail # Unveils hidden failuresset -o nounset # Exposes unset variablesGlob options
shopt -s nullglob # Non-matching globs are removed ("*.foo" => "")shopt -s failglob # Non-matching globs throw errorsshopt -s nocaseglob # Case insensitive globsshopt -s dotglob # Wildcards match dotfiles ("*.sh" => ".foo.sh")shopt -s globstar # Allow ** for recursive matches ("lib/**/*.rb" => "lib/a/b/c.rb")Set GLOBIGNORE as a colon-separated danh mục of patterns to lớn be removed from globmatches.
History
Commands
history | Show history |
shopt -s histverify | Don’t execute expanded result immediately |
Expansions
!$ | Expand last parameter of most recent command |
!* | Expand all parameters of most recent command |
!-n | Expand nth most recent command |
!n | Expand nth command in history |
! | Expand most recent invocation of command |
Operations
!! | Execute last command again |
!!:s/// | Replace first occurrence of lớn in most recent command |
!!:gs/// | Replace all occurrences of to in most recent command |
!$:t | Expand only basename from last parameter of most recent command |
!$:h | Expand only directory from last parameter of most recent command |
!! & !$ can be replaced with any valid expansion.
Slices
!!:n | Expand only nth token from most recent command (command is 0; first argument is 1) |
!^ | Expand first argument from most recent command |
!$ | Expand last token from most recent command |
!!:n-m | Expand range of tokens from most recent command |
!!:n-$ | Expand nth token to lớn last from most recent command |
!! can be replaced with any valid expansion i.e. !cat, !-2, !42, etc.
Miscellaneous
Numeric calculations
$((a + 200)) # showroom 200 to $a$(($RANDOM%200)) # Random number 0..199
Subshells
(cd somedir; echo "I"m now in $PWD")pwd # still in first directoryRedirection
python hello.py > output.txt # stdout to lớn (file)python hello.py >> output.txt # stdout to lớn (file), appendpython hello.py 2> error.log # stderr lớn (file)python hello.py 2>&1 # stderr to lớn stdoutpython hello.py 2>/dev/null # stderr to lớn (null)python hello.py &>/dev/null # stdout & stderr khổng lồ (null)python hello.pyInspecting commands
command -V cd#=> "cd is a function/alias/whatever"Trap errors
trap "echo Error at about $LINENO" ERRortraperr() echo "ERROR: $BASH_SOURCE<1> at about $BASH_LINENO<0>"set -o errtracetrap traperr ERR
Case/switch
case "$1" in start | up) vagrant up ;; *) echo "Usage: $0 ssh" ;;esacSource relative
source "$0%/*/../share/foo.sh"printf
printf "Hello %s, I"m %s" Sven Olga#=> "Hello Sven, I"m Olgaprintf "1 + 1 = %d" 2#=> "1 + 1 = 2"printf "This is how you print a float: %f" 2#=> "This is how you print a float: 2.000000"Directory of script
DIR="$0%/*"Getting options
while << "$1" =~ ^- && ! "$1" == "--" >>; vị case $1 in -V | --version ) echo $version exit ;; -s | --string ) shift; string=$1 ;; -f | --flag ) flag=1 ;;esac; shift; doneif << "$1" == "--" >>; then shift; fiHeredoc
catReading input
echo -n "Proceed?Special variables
$? | Exit status of last task |
$! | PID of last background task |
$$ | PID of shell |
$0 | Filename of the shell script |
$_ | Last argument of the previous command |