#! /bin/bash
chmod +x scriptname
./shello
#! /bin/bash # Greetings!
echo Shello world # literal output
echo Shello "$USER" # uses special variable
# Set and use a new variable
greetz=Shellutations
echo "$greetz world"
var=value
export var=value
unset var
$var
help declare
)PWD
– present working directoryUSER
– current user’s login nameHOME
– home directory, often abbreviated ~PATH
– colon-separated list of directories searched for executablesPS1
– primary prompt string (customizable)mkdir -p ~/bin
mv shello ~/bin
PATH=~/bin:$PATH
cd
) and simply type shello
to execute (shell finds it via new PATH)~/.bashrc
for interactive, non-login shells\u
– username\h
– hostname (up to first dot)\w
– current working directory (with ~ substitution)\e
– literal escape (used for colors)PS1="[\u@\h \w $?]$ "
(includes last exit status)#$*&^?!~'\
"{}[]<>()|;`'…'
– everything literal except closing '
"…"
– allow variable substitution & some escapes; best practice: quote variables as "$var"
\
– escapes next single characterecho Penn State is #1
→ #1
starts a comment, prints “Penn State is” onlyecho "Penn State is #1"
argc
, argv[]
; in shell:$#
– number of arguments (≈ argc
)$@
– all arguments as separate quoted words$1 … $9
– first nine individual arguments./script foo bar
IFS
variablebash -x script
– traces execution: prints each command after expansion, arguments quotedbash -xv
– additionally prints input lines as they are read (v = verbose)echo hello > world
echo hello >> world
tr h j < world
|
echo hello | tr h j | rev | hexdump -C | grep 06
main
returns an int
; same integer becomes process’s exit status$?
status.c
: #include <stdlib.h>
int main(int argc, char **argv) { return atoi(argv[1]); }
Usage: ./status 2 ; echo $?
prints 2.
$?
in PS1
to show last command’s status live$?
gets last command’s statusexit n
used explicitly! cmd
– logical NOT; succeeds (exit 0) when cmd
fails and vice-versa if list ; then
cmds
elif list2 ; then
cmds2
else
cmds3
fi
list
is executed; if it ends with status 0, the then
branch runstrue
– always returns 0false
– always returns 1test condition
or shorthand [[ condition ]]
test -e file
– file existstest -d dir
– directory existstest -z "$var"
– variable length 0 (empty)test -n "$var"
– variable non-emptytest str1 = str2
– strings equaltest num1 -gt num2
(greater than)-lt
, -ge
, -le
, -eq
, -ne
[[ … ]]
[[ $age -ge 16 ]] && echo can drive
! [[ … ]]
cmd1 ; cmd2
– run both regardless of statuscmd1 && cmd2
– stop if cmd1
failscmd1 || cmd2
– run cmd2
only if cmd1
failstrue && echo one
→ prints onetrue || echo two
→ prints nothingfalse && echo three
→ prints nothingfalse || echo four
→ prints fourtest -e Makefile && make
→ build only if Makefile exists while list ; do
cmds
done
while [[ "$x" -lt 99999 ]]; do
echo "$x"
x="1$x"
done
$(command)
(modern) or `command`
(legacy) with command’s stdout (minus trailing newline)file $(which ls)
– runs which ls
, inserts its output into file
command for var in word1 word2 … ; do
cmds
done
for i in $(seq 1 5); do echo $i; done
for i in {1..5}; do echo $i; done
(brace expansion)bash
for a in A B C hello 4; do echo "$a$a$a" ; done
bash
for ext in h c; do cat "hello.$ext" ; done
echo *.c
– list all .c filesecho hello.?
– hello.a, hello.b, etc. for f in hello.* ; do mv "$f" "$f.bak" ; done
touch foo
– create file if missing or update timestampsleep t
– pause for t secondsgrep -F string
– filter stdin for lines containing string (fixed string search)find . -name '*.c'
– recursively list .c files; many predicates (permissions, size, mtime, etc.)file foo
– identify file typewc
– count lines / words / bytesbc
– arbitrary-precision calculator (reads from stdin) while true ; do
echo foo
sleep 1
done
dir/
: find dir -name '*.png'
dir/
whose actual content is PNG: (check magic number) find dir -type f -exec file {} \; | grep 'PNG image'
bc
: echo '199*42' | bc
#! /bin/bash
printf '%s%s\n' "$1" "$1"
#! /bin/bash
for n in 1 2 3 4 ; do
eval arg=\${$n:-}
echo "[${arg}]"
done
man bash
– authoritative manual (options, built-ins, grammar, etc.)^C
on terminal.