- Shell
- Shell Var
- Special Var
- Shell Array
- Operator
- Shell Order
- Flow Control
- Func
- File Include
- Redirect
Shell
Shell Types
- Bourne Shell(/usr/bin/sh or /bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
Usually, we not distinct Bourne Shell
and Bourne Again Shell
Create hello.sh
houbinbindeMacBook-Pro:shell houbinbin$ pwd
/Users/houbinbin/code/shell
houbinbindeMacBook-Pro:shell houbinbin$ vi hello.sh
Edit the content of hello.sh
#!/bin/bash
echo "hello world!"
- run the
hello.sh
houbinbindeMacBook-Pro:shell houbinbin$ /bin/sh hello.sh
hello world!
- another way to run
houbinbindeMacBook-Pro:shell houbinbin$ ./hello.sh
-bash: ./hello.sh: Permission denied
houbinbindeMacBook-Pro:shell houbinbin$ chmod +x ./hello.sh
houbinbindeMacBook-Pro:shell houbinbin$ ./hello.sh
hello world!
mean of
hello.sh
#!
tells OS which Interpreter to use, echo
to print info in window.
read from input
hello_name.sh
#!/bin/bash
# Author:houbinbin
echo "Please enter your name?"
read NAME
echo "Hello, $NAME!"
- run
houbinbindeMacBook-Pro:shell houbinbin$ vi hello_name.sh
houbinbindeMacBook-Pro:shell houbinbin$ /bin/sh hello_name.sh
Please enter your name?
houbinbin
Hello, houbinbin!
houbinbindeMacBook-Pro:shell houbinbin$
Shell Var
Define
-
No Blank between var name and
=
-
Start with [a-zA-Z], name can with
_
-
No punctuation mark and no key word
my_name="houbinbin"
Redefine
A defined var can be re-defined
my_name="houbinbin"
my_name="ryo"
Use
- use_var.sh
my_name="houbinbin"
echo $my_name
- run
houbinbindeMacBook-Pro:shell houbinbin$ vi use_var.sh
houbinbindeMacBook-Pro:shell houbinbin$ /bin/sh use_var.sh
houbinbin
ReadOnly
A readonly
var can’t be change.
- readonly_var.sh
# !/bin/bash
my_name="houbinbin"
readonly my_name
my_name="new name"
- run
houbinbindeMacBook-Pro:shell houbinbin$ vi readonly_var.sh
houbinbindeMacBook-Pro:shell houbinbin$ /bin/sh readonly_var.sh
readonly_var.sh: line 4: my_name: readonly variable
Remove
Use unset
to remove define var.
- unset_var.sh
#!/bin/bash
my_name="ryo"
unset my_name
echo ${my_name}
- run
houbinbindeMacBook-Pro:shell houbinbin$ vi unset_var.sh
houbinbindeMacBook-Pro:shell houbinbin$ /bin/sh unset_var.sh
houbinbindeMacBook-Pro:shell houbinbin$
Special Var
Command | Desc |
---|---|
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 |
$# | 传递给脚本或函数的参数个数。 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。被双引号(“ “)包含时,与 $* 稍有不同,下面将会讲到。 |
$? | 上个命令的退出状态,或函数的返回值。 |
$$ | 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。 |
- special_var.sh
#!/bin/bash
echo "File Name: $0"
echo "First Parameter : $1"
echo "First Parameter : $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters : $#"
- run
houbinbindeMacBook-Pro:shell houbinbin$ vi special_var.sh
houbinbindeMacBook-Pro:shell houbinbin$ /bin/sh special_var.sh hello world my
File Name: special_var.sh
First Parameter : hello
First Parameter : world
Quoted Values: hello world my
Quoted Values: hello world my
Total Number of Parameters : 3
$*
and$@
$*
和 $@
都表示传递给函数或脚本的所有参数,不被""
包含时,都以”$1” “$2” … “$n” 的形式输出所有参数。
但是当它们被""
包含时,$*
会将所有的参数作为一个整体,以”$1 $2 … $n”的形式输出所有参数;$@
会将各个参数分开,以”$1” “$2” … “$n” 的形式输出所有参数。
- diff_demo.sh
#!/bin/bash
# Author:houbinbin
echo "display of \$* "
for i in "$*";
do
echo $i
done
echo "display of \$@ "
for i in "$@";
do
echo $i
done
- run
houbinbindeMacBook-Pro:shell houbinbin$ vi diff_demo.sh
houbinbindeMacBook-Pro:shell houbinbin$ /bin/sh diff_demo.sh 1 2 3 4
display of $*
1 2 3 4
display of $@
1
2
3
4
houbinbindeMacBook-Pro:shell houbinbin$
Shell Array
Define
Shell only support single-dimensional arrays.
array=(value1 value2 ... valuen)
- array.sh
#!/bin/sh
# array demo
array=(a b "c" d)
# another way to define array
array_two[0]=a
array_two[1]=b
array_two[2]="c"
array_two[3]=d
Read
You can read from array like this:
${array_name[index]}
- read_array.sh
#!/bin/sh
# read from array
array=(a b c "d")
echo "First elem is ${array[0]}"
echo "Second elem is ${array[1]}"
echo "Third elem is ${array[2]}"
echo "Last elem is ${array[-1]}"
- run
root@iZuf60ahcky4k4nfv470juZ:~/code/shell# chmod +x read_array.sh
root@iZuf60ahcky4k4nfv470juZ:~/code/shell# ./read_array.sh
First elem is a
Second elem is b
Third elem is c
Last elem is d
Read all elem
We can use *
or @
to get all elem in array.
- read_all_array.sh
#!/bin/sh
# Read all elem in array
array=(a b c d)
echo "All elem in array: ${array[*]}"
echo "All elem in array: ${array[@]}"
- run
root@iZuf60ahcky4k4nfv470juZ:~/code/shell# chmod +x read_all_array.sh
root@iZuf60ahcky4k4nfv470juZ:~/code/shell# ./read_all_array.sh
All elem in array: a b c d
All elem in array: a b c d
Array Length
We can use ${#array[*]}
or ${#array[@]}
, to get the array size.
- array_length.sh
!#/bin/sh
# array length
array=(a b c d E)
echo "the size of array is: ${#array[*]}"
echo "the size of array is: ${#array[@]}"
- run
root@iZuf60ahcky4k4nfv470juZ:~/code/shell# chmod +x array_length.sh
root@iZuf60ahcky4k4nfv470juZ:~/code/shell# ./array_length.sh
the size of array is: 5
the size of array is: 5
Operator
The original bash not support math oper, we can use expr
instead.
Attention:
1.expr is in `, not ‘
2.expr between numbers should split with blank.
- num_oper.sh
#!/bin/bash
# num oper
value1=10
value2=20
sum=`expr $value1 + $value2`
echo "sum of $value1 and $value2 is: $sum"
- run
houbinbindeMacBook-Pro:shell houbinbin$ chmod +x num_oper.sh
houbinbindeMacBook-Pro:shell houbinbin$ ./ num_oper.sh
sum of 10 and 20 is: 30
Math operator
Suppose: $a
is 10, $b
is 20
Command | Desc | Demo |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30 |
- | 减法 | expr $a - $b 结果为 -10 |
* | 乘法 | expr $a \* $b 结果为 200 |
/ | 除法 | expr $b / $a 结果为 2 |
% | 取余 | expr $b % $a 结果为 0 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a |
== | 用于比较两个数字,相同则返回 true | [ $a == $b ] 返回 false |
!= | 用于比较两个数字,不相同则返回 true | [ $a != $b ] 返回 true |
Relation operator
Only support number or number string.
Suppose: $a
is 10, $b
is 20
Command | Desc | Demo |
---|---|---|
-eq | equals | [ $a -eq $b ] false |
-ne | not equals | [ $a -ne $b ] true |
-gt | great than | [ $a -gt $b ] false |
-lt | less than | [ $a -lt $b ] true |
-ge | great equals | [ $a -ge $b ] false |
-le | less equals | [ $a -le $b ] true |
Bool operator
Command | Desc | Demo |
---|---|---|
! | not | [ ! false ] true |
-o | or | [ true -o false ] true |
-a | and | [ true and false ] false |
&& |
and | [ true and false ] false |
|| |
or | [ true and false ] false |
String operator
Suppose: $a
is “10”, $b
is “20”
Command | Desc | Demo |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否为0,不为0返回 true | [ -n $a ] 返回 true。 |
str | 检测字符串是否为空,不为空返回 true | [ $a ] 返回 true。 |
File Test operator
Command | Desc |
---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true |
-d file | 检测文件是否是目录,如果是,则返回 true |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true |
-p file | 检测文件是否是具名管道,如果是,则返回 true |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true |
-r file | 检测文件是否可读,如果是,则返回 true |
-w file | 检测文件是否可写,如果是,则返回 true |
-x file | 检测文件是否可执行,如果是,则返回 true |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true |
- file_test_oper.sh
#!/bash/sh
# file test operator
file="/Users/houbinbin/code/shell/file_test_oper.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
- run
houbinbindeMacBook-Pro:shell houbinbin$ /bin/sh file_test_oper.sh
文件可读
文件可写
文件不可执行
文件为普通文件
文件不是个目录
文件不为空
文件存在
Shell Order
echo
echo [-e] string
printf
just like printf() of C
printf format-string [arguments...]
test
- test_num.sh
#!/bin/bash
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
run
houbinbindeMacBook-Pro:shell houbinbin$ /bin/sh test_num.sh
两个数相等!
- test_str.sh
#!/bin/bash
num1="runoob"
num2="runoob"
if test num1=num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi
run
houbinbindeMacBook-Pro:shell houbinbin$ /bin/sh test_str.sh
两个字符串相等!
- test_file.sh
#!/bin/bash
if test -e /bin/bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
run
houbinbindeMacBook-Pro:shell houbinbin$ /bin/sh test_file.sh
文件已存在!
Flow Control
If Else
- if
if condition
then
command1
command2
...
commandN
fi
- if else
if condition
then
command1
command2
...
commandN
else
command
fi
- if else-if else
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
demo
echo "please enter your age"
read age
if [[ $age -le 0 || $age -ge 100 ]]
then
echo "that's crazy!"
elif [ $age -le 20 ]
then
echo "little boy"
elif [[ $age -gt 20 && $age -le 40 ]]
then
echo "good time"
else
echo "be yourself"
fi
for
for loop in "hello" "boy" "see" "you" "sometimes" "somewhere"
do
echo "the word is $loop"
done
run
houbinbindeMacBook-Pro:shell houbinbin$ chmod +x for.sh
houbinbindeMacBook-Pro:shell houbinbin$ ./for.sh
the word is hello
the word is boy
the word is see
the word is you
the word is sometimes
the word is somewhere
While
while condition
do
command
done
demo
#!/bin/sh
# while demo
val=1
while( $val < 5 )
do
echo "val: $val"
let "val++"
done
run
houbinbindeMacBook-Pro:shell houbinbin$ ./while.sh
val: 1
val: 2
val: 3
val: 4
case
case val in
mode1)
command1
command2
...
commandN
;;
mode2)
command1
command2
...
commandN
;;
esac
demo
#!/bin/sh
# case demo
echo "please enter a num(1-4)"
echo you enter:
read num
case $num in
1)
echo "Enter one"
;;
2)
echo "Enter two"
;;
3)
echo "Enter three"
;;
4)
echo "Enter four"
;;
*)
echo "Your enter is out of range"
;;
esac
run
houbinbindeMacBook-Pro:shell houbinbin$ vi case.sh
houbinbindeMacBook-Pro:shell houbinbin$ ./case.sh
please enter a num(1-4)
you enter:
1
Enter one
beak
#!/bin/sh
# break demo
for num in 1 2 3 4 5
do
if [ $num -eq 4 ]
then
break
fi
echo "num is: $num"
done
run
houbinbindeMacBook-Pro:shell houbinbin$ ./break.sh
num is: 1
num is: 2
num is: 3
continue
#!/bin/sh
# continue demo
for num in 1 2 3 4 5
do
if [ $num -eq 4 ]
then
continue
fi
echo "num is: $num"
done
run
houbinbindeMacBook-Pro:shell houbinbin$ ./continue.sh
num is: 1
num is: 2
num is: 3
num is: 5
Func
[ function ] funname [()]
{
action;
[return int;]
}
demo
#!/bin/sh
# function demo
firstFunc() {
echo "This is my first shell function."
}
echo "function start"
firstFunc
echo "function end"
run
houbinbindeMacBook-Pro:shell houbinbin$ vi function.sh
houbinbindeMacBook-Pro:shell houbinbin$ chmod +x function.sh
houbinbindeMacBook-Pro:shell houbinbin$ ./function.sh
function start
This is my first shell function.
function end
- function with return value
#!/bin/sh
# func with return val
funcWithReturnVal() {
echo "enter first num: "
read firstNum
echo "enter second num: "
read secondNum
return $(($firstNum+$secondNum))
}
echo "function with return value start:"
funcWithReturnVal
returnVal=$?
echo "result: $returnVal"
run
houbinbindeMacBook-Pro:shell houbinbin$ ./funcWithReturnVal.sh
function with return value start:
enter first num:
1
enter second num:
2
result: 3
- function with parameters
#!/bin/sh
# function with param
hasParam() {
echo "all param is $*"
if [ $# -gt 0 ]
then
echo "has param"
return 1
else
echo "has no param"
return 0
fi
}
hasParam 1 2 3
run
houbinbindeMacBook-Pro:shell houbinbin$ vi funcWithParam.sh
houbinbindeMacBook-Pro:shell houbinbin$ chmod +x funcWithParam.sh
houbinbindeMacBook-Pro:shell houbinbin$ ./funcWithParam.sh
all param is 1 2 3
has param
$n
to get the param value, when n >= 10, use ${n}
!
File Include
- data.sh
#!/bin/sh
name="houbinbin"
- include.sh
use . ./data.sh
or source ./data.sh
to include the file
#!/bin/sh
source ./data.sh
echo "the name is: $name"
run
houbinbindeMacBook-Pro:shell houbinbin$ chmod +x include.sh
houbinbindeMacBook-Pro:shell houbinbin$ ./include.sh
the name is: houbinbin
Redirect
Command | Desc |
---|---|
command > file | out->file |
command < file | in->file |
command » file | out append->file |
n > file | file descriptor n ->file |
n » file | file descriptor n append->file |
n >& m | out file m&n merge |
n <& m | in file m&n merge |
« tag | content between tag for input |
File descriptor
0 //stdIn
1 //stdOut
2 //stdErr
- Out Redirect
houbinbindeMacBook-Pro:shell houbinbin$ ls > ls_file
houbinbindeMacBook-Pro:shell houbinbin$ cat ls_file
break.sh
case.sh
continue.sh
data.sh
diff_demo.sh
file_test_oper.sh
for.sh
funcWithParam.sh
funcWithReturnVal.sh
function.sh
hello.sh
hello_name.sh
if_else.sh
include.sh
ls_file
num_oper.sh
readonly_var.sh
special_var.sh
test_file.sh
test_num.sh
unset_var.sh
use_var.sh
while.sh
- In Redirect
We want to calc the line of file ls_file
houbinbindeMacBook-Pro:shell houbinbin$ wc -l ls_file
23 ls_file