"Let us distinguish two parts of a programming language. First, its framework which gives the overall rules of the system, and second, its changeable parts, whose existence is anticipated by the framework but whose particular behavior is not specified by it. For example, the for statement, and almost all other statements, are part of Algol's framework but library functions and user- defined procedures are changeable parts." (Link)
WRONG!
$ if -f /etc/hosts
> then
> echo /etc/hosts
> fi
-f: command not found
RIGHT!
$ if [ -f /etc/hosts ]
> then
> echo /etc/hosts
> fi
/etc/hosts
$ if env > /dev/null
> then
> echo true
> fi
$ if touch /werwer 2> /dev/null
> then
> echo created /werwer
> else
> echo did not create /werwer
> fi
did not create /werwer
$ if touch /werwer 2> /dev/null
> then
> echo created /werwer
> elif touch /tmp/werwer 2> /dev/null
> then
> echo created /tmp/werwer
> else
> echo cannot create any werwer
> fi
created /tmp/werwer
Syntax | Meaning |
---|---|
( EXP ) | Expression is true |
! EXP | Expression is false |
EXP1 -a EXP2 | Logical and |
EXP1 -o EXP2 | Logical or |
-n STR | String has length > 0 |
-z STR | String has length = 0 |
STR1 = STR2 | Strings are equal |
STR1 != STR2 | Strings are not equal |
Syntax | Meaning | |
---|---|---|
INT1 -eq INT2 | Integers are equal | |
INT1 -ge INT2 | INT1 is greater or equal to INT2 | |
INT1 -gt INT2 | INT1 is greater than INT2 | |
INT1 -le INT2 | INT1 is less than or equal to INT2 | |
INT1 -lt INT2 | INT1 is less than INT2 | |
INT1 -ne INT2 | INT1 is not equal to INT2 |
Syntax | Meaning |
---|---|
FILE1 -ef FILE2 | files have same device and inode number |
FILE1 -nt FILE2 | FILE1 is newer than FILE2 |
FILE1 -ot FILE2 | FILE1 is older than FILE2 |
-d DIR | DIR is an existing directory |
Syntax | Meaning |
---|---|
-e FILE | FILE exists |
-f FILE | FILE exists and is a regular file |
-h FILE, -L FILE | FILE exists and is a soft link |
-r FILE | FILE exists and is readable |
-s FILE | FILE exists and has a size > 0 |
-w FILE | FILE exists and is writable |
-x FILE | FILE exists and is executable |
-t FD FD r | efers to a terminal device |
$ for name in !(*~)
> do
> echo $name
> done
01-introduction.tex
1.aux
1.html
1.log
1.nav
1.out
1.pdf
#!/bin/bash -x
# prints each command line argument
for name
do
echo I found $name
done
$ for((i=0; i<10; i++))
> do
> echo $i
> done
0
1
2
3
4
5
6
7
8
9
$ while true
> do
> echo 1
> done
1
1
1 [...]
until false
> do
> echo 1
> done
1
1
1
$ x=yellow
$ case $x in
> green)
> echo this is green
> ;;
> yellow)
> echo this is yellow
> ;;
> esac
this is yellow
$ cat ./simple-set.sh
#!/bin/bash -x
echo Current params: $*
set `hostname`
echo Current params: $*
$ ./simple-set.sh a b c d e f
+ echo Current params: a b c d e f
Current params: a b c d e f
++ hostname
+ set linprog3
+ echo Current params: linprog3
Current params: linprog3
$ set a b c d e f
$ echo $*
a b c d e f
$ shift
$ echo $*
b c d e f
$ set a b c d e f
$ echo $#
6
$ set "$*"
$ echo $#
1
$ set a b c d e f
$ set "$@"
$ echo $#
6
$ cat /proc/self/environ | tr '\0' '\n'
$ cat /proc/self/environ | tr '\0' '\n' | grep ALI
$ export ALIBABA=HOCUSPOCUS
$ cat /proc/self/environ | tr '\0' '\n' | grep ALI
ALIBABA=HOCUSPOCUS
(For more fun with environments, grab environ.c)
$ readarray hosts < /etc/hosts
$ for name in "${hosts[@]}"
> do
> echo $name
> done
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters