Bash cheatsheet: Difference between revisions
m (Text replacement - "<source " to "<syntaxhighlight ") |
|||
Line 6: | Line 6: | ||
=bash prompt= | =bash prompt= | ||
Put this in your ~/.bash_profile | Put this in your ~/.bash_profile | ||
< | <syntaxhighlight lang=bash> | ||
typeset +x PS1="\[\e]0;\u@\h: \w\a\]\u@\h:\w# " | typeset +x PS1="\[\e]0;\u@\h: \w\a\]\u@\h:\w# " | ||
</source> | </source> | ||
Line 13: | Line 13: | ||
==split== | ==split== | ||
For example split an ip: | For example split an ip: | ||
< | <syntaxhighlight lang=bash> | ||
$ delimiter="." | $ delimiter="." | ||
$ ip="10.1.2.3" | $ ip="10.1.2.3" | ||
Line 22: | Line 22: | ||
==dirname== | ==dirname== | ||
< | <syntaxhighlight lang=bash> | ||
$ myself=/usr/bin/blafasel ; echo ${myself%/*} | $ myself=/usr/bin/blafasel ; echo ${myself%/*} | ||
/usr/bin | /usr/bin | ||
</source> | </source> | ||
==basename== | ==basename== | ||
< | <syntaxhighlight lang=bash> | ||
$ myself=/usr/bin/blafasel ; echo ${myself##*/} | $ myself=/usr/bin/blafasel ; echo ${myself##*/} | ||
blafasel | blafasel | ||
</source> | </source> | ||
==Path name resolving function== | ==Path name resolving function== | ||
< | <syntaxhighlight lang=bash> | ||
# dir_resolve originally from http://stackoverflow.com/a/20901614/5887626 | # dir_resolve originally from http://stackoverflow.com/a/20901614/5887626 | ||
# modified at https://lars.timmann.de/wiki/index.php/Bash_cheatsheet | # modified at https://lars.timmann.de/wiki/index.php/Bash_cheatsheet | ||
Line 50: | Line 50: | ||
==Reverse the order of elements== | ==Reverse the order of elements== | ||
An example for services in normal and reverse order for start/stop | An example for services in normal and reverse order for start/stop | ||
< | <syntaxhighlight lang=bash> | ||
declare -a SERVICES_STOP=(service1 service2 service3 service4) | declare -a SERVICES_STOP=(service1 service2 service3 service4) | ||
declare -a SERVICES_START | declare -a SERVICES_START | ||
Line 59: | Line 59: | ||
</source> | </source> | ||
This results in: | This results in: | ||
< | <syntaxhighlight lang=bash> | ||
$ echo ${SERVICES_STOP[*]} ; echo ${SERVICES_START[*]} | $ echo ${SERVICES_STOP[*]} ; echo ${SERVICES_START[*]} | ||
service1 service2 service3 service4 | service1 service2 service3 service4 | ||
Line 79: | Line 79: | ||
Just put your code between <i>while</i> and <i>do</i> and use <i>continue</i> alias : in the loop. | Just put your code between <i>while</i> and <i>do</i> and use <i>continue</i> alias : in the loop. | ||
< | <syntaxhighlight lang=bash> | ||
#!/bin/bash | #!/bin/bash | ||
while | while | ||
Line 90: | Line 90: | ||
For example: | For example: | ||
< | <syntaxhighlight lang=bash> | ||
#!/bin/bash | #!/bin/bash | ||
Line 104: | Line 104: | ||
=Functions= | =Functions= | ||
==Log with timestamp== | ==Log with timestamp== | ||
< | <syntaxhighlight lang=bash> | ||
function printlog () { | function printlog () { | ||
# Function: | # Function: | ||
Line 134: | Line 134: | ||
</source> | </source> | ||
< | <syntaxhighlight lang=bash> | ||
$ printf "test\n\ntoast\n" | printlog /dev/stdout | $ printf "test\n\ntoast\n" | printlog /dev/stdout | ||
20190603 12:48:13 test | 20190603 12:48:13 test | ||
Line 147: | Line 147: | ||
=Calculations= | =Calculations= | ||
< | <syntaxhighlight lang=bash> | ||
$ echo $[ 3 + 4 ] | $ echo $[ 3 + 4 ] | ||
7 | 7 | ||
Line 156: | Line 156: | ||
=init scripts= | =init scripts= | ||
==A basic skeleton== | ==A basic skeleton== | ||
< | <syntaxhighlight lang=bash> | ||
#!/bin/bash | #!/bin/bash | ||
Line 211: | Line 211: | ||
= Logging and output in your scripts = | = Logging and output in your scripts = | ||
== Add a timestamp to all output == | == Add a timestamp to all output == | ||
< | <syntaxhighlight lang=bash> | ||
#!/bin/bash | #!/bin/bash | ||
Line 240: | Line 240: | ||
== Add a timestamp to all output and send to file== | == Add a timestamp to all output and send to file== | ||
< | <syntaxhighlight lang=bash> | ||
#!/bin/bash | #!/bin/bash | ||
Line 273: | Line 273: | ||
In progress... no time... | In progress... no time... | ||
< | <syntaxhighlight lang=bash> | ||
while [ $# -gt 0 ] | while [ $# -gt 0 ] | ||
do | do |
Revision as of 23:39, 25 November 2021
bash history per user
See Logging the SSH fingerprint
bash prompt
Put this in your ~/.bash_profile <syntaxhighlight lang=bash> typeset +x PS1="\[\e]0;\u@\h: \w\a\]\u@\h:\w# " </source>
Useful variable substitutions
split
For example split an ip: <syntaxhighlight lang=bash> $ delimiter="." $ ip="10.1.2.3" $ declare -a octets=( ${ip//${delimiter}/ } ) $ echo "${#octets[@]} octets -> ${octets[@]}" 4 octets -> 10 1 2 3 </source>
dirname
<syntaxhighlight lang=bash> $ myself=/usr/bin/blafasel ; echo ${myself%/*} /usr/bin </source>
basename
<syntaxhighlight lang=bash> $ myself=/usr/bin/blafasel ; echo ${myself##*/} blafasel </source>
Path name resolving function
<syntaxhighlight lang=bash>
- dir_resolve originally from http://stackoverflow.com/a/20901614/5887626
- modified at https://lars.timmann.de/wiki/index.php/Bash_cheatsheet
dir_resolve() {
local dir=${1%/*} local file=${1##*/} # if the name does not contain a / leave file blank or the name will be name/name [ "_${1/\//}_" == "_${1}_" -a -d ${1} ] && file="" [ "_${1/\//}_" == "_${1}_" -a -f ${1} ] && dir="" pushd "$dir" &>/dev/null || return $? # On error, return error code echo ${PWD}${file:+"/"${file}} # output full path with filename popd &> /dev/null
} </source>
Arrays
Reverse the order of elements
An example for services in normal and reverse order for start/stop <syntaxhighlight lang=bash> declare -a SERVICES_STOP=(service1 service2 service3 service4) declare -a SERVICES_START for(( i=$[ ${#SERVICES_STOP[*]} - 1 ] ; i>=0 ; i-- )) do
SERVICES_START+=(${SERVICES_STOP[$i]})
done </source> This results in: <syntaxhighlight lang=bash> $ echo ${SERVICES_STOP[*]} ; echo ${SERVICES_START[*]} service1 service2 service3 service4 service4 service3 service2 service1 </source>
Loops
Numbers
$ for i in {0..9} ; do echo $i ; done
or
$ for ((i=0;i<=9;i++)); do echo $i; done
so gehen natürlich auch andere Sprünge, z.B. immer 3 weiter:
$ for ((i=0;i<=9;i+=3)); do echo $i; done
or or or
$ for ((i=0,j=1;i<=9;i+=3,j++)); do echo "$i $j"; done
Exit controlled loop
Just put your code between while and do and use continue alias : in the loop.
<syntaxhighlight lang=bash>
- !/bin/bash
while
# some code (( <your control expression> ))
do
:
done </source>
For example: <syntaxhighlight lang=bash>
- !/bin/bash
i=1 while
i=$[ $i + 1 ]; (( $i < 10 ))
do
:
done </source>
Functions
Log with timestamp
<syntaxhighlight lang=bash> function printlog () {
- Function:
- Log things to logfile
- Parameter:
- 1: logfile
- *: You can call printlog like printf (except the first parameter is the logfile)
- OR
- Just pipe things to printlog
local logfile=${1} shift if [ -n "${*}" ] then format=${1} shift printf "%s ${format}" "$(/bin/date '+%Y%m%d %H:%M:%S')" ${*} >> ${logfile}
else while read input do printf "%s %s\n" "$(/bin/date '+%Y%m%d %H:%M:%S')" "${input}" >> ${logfile} done fi
} </source>
<syntaxhighlight lang=bash> $ printf "test\n\ntoast\n" | printlog /dev/stdout 20190603 12:48:13 test 20190603 12:48:13 20190603 12:48:13 toast $ printlog /dev/stdout "test\n" 20190603 12:48:19 test $ printlog /dev/stdout "test %s %d %s\n" "bla" 0 "bli" 20190603 12:48:25 test bla 0 bli $ </source>
Calculations
<syntaxhighlight lang=bash> $ echo $[ 3 + 4 ] 7 $ echo $[ 2 ** 8 ] # 2^8 256 </source>
init scripts
A basic skeleton
<syntaxhighlight lang=bash>
- !/bin/bash
NAME=<myname> # The name of the daemon USER=<runuser> # The user to run the daemon as
SELF=${0##*/} CALLER=$(id -nu)
- Check if called as ${USER}
if [ "_${CALLER}_" != "_${USER}_" ] then
# If not do a su if called as root if [ "_${CALLER}_" == "_root_" ] then exec su -l ${USER} -c "$0 $@" else echo "Please start this script only as user ${USER}" exit 1 fi
fi
if [ $# -eq 1 ]
then
command=$1
else
# Called as ${NAME}-start.sh or ${NAME}-stop.sh command=${SELF%.sh} command=${command##${NAME}-} [ "_${command}_" == "_${NAME}_" ] && command=""
fi
case ${command} in start)
# start commands ;;
stop)
# stop commands ;;
restart)
$0 stop $0 start ;;
- )
[ ! -z "${command}" ] && echo "ERROR: Unknown option ${command}!" echo "Usage: $0 (start|stop|restart)"; echo "Or call as ${NAME}-(start|stop|restart).sh" exit 1 ;;
esac </source>
Logging and output in your scripts
Add a timestamp to all output
<syntaxhighlight lang=bash>
- !/bin/bash
- Find temp filename
FIFO=$(mktemp)
- Clenup on exit
trap 'rm -f ${FIFO}' 0
- Delete file created by mktemp
rm "${FIFO}"
- Create a FIFO instead
mkfifo "${FIFO}"
- Read from FIFO and add date at the beginning
sed -e "s|^|$(date '+%d.%m.%Y %H:%M:%S') :: |g" < ${FIFO} &
- Redirect stdout & stderr to FIFO
exec > ${FIFO} 2>&1
- Now your program
echo bla echo bli >&2 </source>
Add a timestamp to all output and send to file
<syntaxhighlight lang=bash>
- !/bin/bash
LOGFILE=/tmp/bla.log
- Find temp filename
FIFO=$(mktemp)
- Clenup on exit
trap 'rm -f ${FIFO}' 0
- Delete file created by mktemp
rm "${FIFO}"
- Create a FIFO instead
mkfifo "${FIFO}"
- Read from FIFO and add date at the beginning
sed -e "s|^|$(date '+%d.%m.%Y %H:%M:%S') :: |g" < ${FIFO} > ${LOGFILE}&
- Redirect stdout & stderr to FIFO
exec > ${FIFO} 2>&1
- Now your program
echo bla echo bli >&2 </source>
Parameter parsing
In progress... no time... <syntaxhighlight lang=bash> while [ $# -gt 0 ] do
case $1 in -h|--help) usage help shift; exit 0; ;; --?*=?*|-?*=?*) param=${1%=*} value=${1#*=} shift; ;; --?*=|-?*=) param=${1%=*} usage "${param} needs a vlaue!" ;; *) if [ $# -lt 2 ] ; then usage "$1 needs a value!"; fi param=$1 value=$2 shift; shift; ;; esac
case $param in *) other_params[$[${#other_params[*]} + 1]]="${param}=${value}" param=${param#--} param=${param/-/_} export ${param^^}=${value} ;; esac
done </source>