Bash - Overview
Bash is (almost) universally available on Linux, macOS, and even Windows.
The official manual: http://www.gnu.org/software/bash/manual/bash.html
Check Bash Version
bash --version
echo "${BASH_VERSION}"
Ctrl+x Ctrl+v
Bash Script
bash syntax: https://devmanual.gentoo.org/tools-reference/bash/index.html
Evaluate numbers
$((i-1))
Check if exists
if [ -d foo ]; then
mkdir foo
fi
Loop
for S in FOO BAR BAZ
do
...
done
Skeleton of a bash script
#!/bin/bash
usage="Usage: server.sh (start|stop)"
# command is 'start' or 'stop'
command=$1
case $command in
(start)
...
;;
(stop)
...
;;
(*)
echo $usage
exit 1
;;
esac
Redirect StdErr to StdOut
Use 2>&1
$ (do whatever) > /home/ubuntu/`date +"%Y%m%d"`.log 2>&1
2>&1 indicates that the standard error (2>) is redirected to the same file descriptor that is pointed by standard output (&1).
Image Not Found
Error
dyld: Library not loaded: /usr/local/opt/readline/lib/libreadline.6.dylib
Referenced from: /usr/local/bin/bash
Reason: image not found
Trace/BPT trap: 5
Solution
Reinstall bash
$ brew upgrade bash
Count lines in markdown files
for file in `find ../src -name '*.md'`; do
wc -l ${file}
done | sort -n > ../_tmp/result.txt
Change -l
to -w
to count words.
yes or no
Some commands/programs will pause to ask you y
or N
. To Answer that automatically, use yes
or yes n
for no
$ yes | xxxx
$ yes n | xxxx
Style Guide
Use "$foo"
, or "${foo}"
, not $foo
Global Search And Replacement
$ find / -name game
$ find . -type f -name '*.txt' -exec sed -i '' s/this/that/g {} +
List the largest files/directories
If you want to find and print the top 10 largest files names (not directories) in a particular directory and its sub directories
$ find . -printf '%s %p\n'|sort -nr|head
To restrict the search to the present directory use -maxdepth 1
with find.
$ find . -maxdepth 1 -printf '%s %p\n'|sort -nr|head
print the top 10 largest "files and directories":
$ du -a . | sort -nr | head
Environment Variables
PATH
: where to look for commandsSHELL
: default is/bin/bash
HOME
: default is/home/<your_username>/
USER
: your username
Alias
$ alias sayhello='echo hello'
$ sayhello
hello
Wildcards
*
: matches any characters?
: matches one and only one character[abc]
: matchesa
orb
orc
[!abc]
: matches any characters other thana
orb
orc
{abc, def}
: matchesabc
ordef
{1..5}
: generates the sequence1 2 3 4 5
Input/Output
A shell opens 3 standard IO streams:
0
: standard inputstdin
1
: standard outputstdout
2
: standard errorstderr
They are basically file handles ("Everything is a file").
Redirect
-
<
redirectsstdin
, e.g.$ sort < /etc/group
-
>
redirectsstdout
, e.g.$ echo 'hello' > hello.txt
-
2>
redirectsstderr
, e.g.2>
will redirectstderr
toerrors.txt
:$ find / -name term 2> errors.txt
-
2>&1
assigns stream2
to1
, so allstderr
is also showing instdout
, e.g.$ find / -name term 2>&1 > all.txt
-
|
(a pipe) transfers thestdout
as the input of next segment
Start Daemon
if kill -0 $pid > /dev/null 2>&1; then
echo Database is already running ...
else
echo Starting Database ...
bin/mongod &
fi
Step by Step:
kill -0 $pid
:-0
for testing if the pid is available to kill. It will return0
if you can kill<pid>
,1
if<pid>
is invalid or you do not have access.... > /dev/null 2>&1
: redirect the output to/dev/null
, a blackhole.2
stands forSTDERR
,1
forSTDOUT
. This command means redirectSTDOUT
to/dev/null
, and redirectSTDERR
toSTDOUT
(which is/dev/null
), so bothSTDOUT
andSTDERR
will be quiet. Remember the&
before destination.bin/mongod &
: if it is not running, start the daemon. Remember the&
for running in the background.
Wait before it is up:
while true; do
sleep 1
if pgrep mongod; then
break
fi
done
Stop Daemon
Similar to the previous section.
if kill -0 $pid_mongod > /dev/null 2>&1; then
echo Stopping mongod Server ...
kill -9 $pid_mongod
else
echo No mongod Server to stop ...
fi
Different from the POSIX shell
[[ condition ]]
does not work; use[ condition ]
- Arrays do not work; use IFS
- Local variables do not work; use a subshell