相信很多人都在工作中接触过Linux系统,所以也就理所当然要和 Shell 打交道,所以有必要对Shell做一个简单的总结性介绍来帮助新手能够快速认识Shell并了解Shell:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Shell 入门基础<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Shell 既是一种脚本解释器(读取脚本文件并执行语句,供用户和内核通信),又是一种脚本语言(脚本语言是相对于编译型语言来说的,无需编译即可运行)。
位置参数: 向Shell脚本传递的参数
$n: 向脚本传递的第n个参数(n=1,、2、3、4....9)
$0: 脚本的名字
$# : 位置参数的总个数
$* : 以“ $1 $2 $3....$n" 的形式输出所有位置参数的值
$@ : 以 ”$1" "$2" "$3" ....."$n" 的形式输入所有位置参数的值
$? : 上一条命令的执行状态码{0-255},0表示执行成功,非0 执行失败
$$: 返回本程序的ID ,即 进程PID
不过 经过实验,貌似$* 和$@ 作用并没有什么不同
以上 $n $0 $# $* $? .....都是系统变量
Shell脚本通常应该具备的三要素:
1. 指定脚本解释器以及解释器的绝对路径 :如 #!/bin/bash (当安装有多个脚本解释器时候,可以指定其他不同解释器 如:#!/user/bin/php ) (也可以指定某些命令 如: #!/bin/more #! /bin/cat 如此一来就会把shell语句原样输出)
2. 注释 说明代码功能
3. 可执行语句,实现程序的功能
# echo "$SHELL" 查看当前系统默认的shell
# echo "$BASH_VERSION" 查看当前shell的版本
#cat /etc/shells 列出目前系统支持的shell
当我们安装了新的shell之后,兵不能立即使用,需要将其绝对路径添加到 /etc/shells 列表中 :如 echo " /bin/local/Python " >> /etc/shells
Shell 注释风格:
1. # 单行注释
2. <<string
..................
..................<string
: 多行注释
string
Shell 执行方式:
1. 授予脚本可执行权限,使得脚本可以直接执行 : 如 # chmod a+x test1.bash # ./test1.bash # /home/oracle/test1.sh
2.调用脚本解释器 来执行: 如 # bash test1.sh # sh test1.sh
3. 用" source " 或 “ . " 执行: 如 # source test1.sh # . test1.sh
前两种方式会开启一个子Shell,在子Shell 中去执行脚本中的命令,然后退出子Shell。第三种方式直接在当前Shell中执行语句。
Shell的退出状态:
每条语句执行完之后都会有一个状态码 (0---255); 0 表示上一条语句执行成功,否则失败。
脚本和函数执行完之后也会有退出状态码,默认由脚本和函数的最后一条语句的退出状态码决定
也可以直接在脚本中 用exit 指定脚本退出状态码 ,此时脚本执行到此处,便以指定状态码退出脚本。(如果exit 后面还有语句也不再执行)
Shell 之 vi :
一般模式:执行vi 操作, 刚进入的模式。 可进行 dd y$ 等操作
编辑模式:在一般模式 点击 i o 等进去可编辑文本的模式。可进行文本的编辑
命令模式:在一般模式 点击 Shift + : 进入命令模式 。 可进行 wq ! q! 等保存退出的操作 以及 set nu 显示行号
vi 操作:
a---从当前字符后面插入;
i---从当前字符前面插入;
A---光标移动到当前行的最后面;
I---光标移动到当前行的最前面;
o---光标从当前行的下面一行开始插入;
O---光标从当前行的上面一行开始插入;
u---恢复到操作之前的状态;
gg--光标移动到界面的首行;
G---光标移动到界面的尾行;
nG--光标移动到第n行;
d$--删除本行光标所在字符以及其后字符;
d#--删除本行光标前面字符;
dgg/d1G--删除光标所在行到第一行
dG-- 删除光标所在行到最后一行
yy--复制当前行
nyy--复制从当前行开始的n行
y^--复制当前到行首的内容
y$--复习当前到行尾的内容
p--从光标所在字符后面插入
P--从光标所在字符
:set nu --设置行号; set nonu ---取消行号
一般模式下: ZZ or :wq!--保存退出;
h--光标向左移动;
l--光标向右移动;
j--光标向下移动;
k--光标向上移动;
正在进行 vi 编辑时候,如果想临时进去命令行查看东西时候,可以 用 CTRL + z 把 vi 暂停到后台,之后 在用 fg 命令 把vi调到前台继续操作(也可以先执行jobs 查看目前的后台工作)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>...................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>> >>>>>>>> >>>>>>>>>>>>>>>>>>>>Shell 编程基础<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Shell 之 变量:
本质上 变量是程序中保存用户数据的一段内存空间,变量名就是这段内存空间的地址;变量名可以有字母、 数字、 下划线组成,只能以字母或下划线开头。
根据变量是否需要强制指定变量类型可以分为 :强语言类型、弱语言类型
强语言类型:程序中需要强制指定变量数据类型的语言:如 Java、C++
弱语言类型:程序中不要求强制指定变量数据类型的语言:如 VBScript 、Shell
根据变量类型确定的时间,可以分为: 静态语言、动态语言
动态语言类型:在程序执行过程中才确定变量的数据类型:如VBScript 、PHP、Python
静态语言类型:在程序编译期间就确定变量的数据类型:如 Java 、C++
显然Shell 属于动态和弱语言
Shell 无需事先定义变量,可以直接使用变量并赋值,亦不用显式指定变量类型;
Shell中变量不分数据类型,统一按照字符串存储,但是变量的数据类型会根据不同的操作自动变化,例如字符串的比较,数字的运算等。
当然有时为了控制变量 也可以用declare/typeset 来赋予变量一些属性:
declare/ typeset -i var : 定义整型
declare / typeset -r var : 定义只读变量
declare / typeset -x var :将变量设置成环境变量,等价于 export var
Shell 之 变量和引号:
Shell中引号有三种: 双引号 ” 、 单引号 ' 、 反引号 `
单引号 : 单引号里面的所有字符都将被解释为普通字符
双引号:除了 ”\“ (转义符)、“$” 、” ” “ (双引号) 、 “ `” (反引号) 保留特殊功能外,其他所有字符都被解释为普通字符(此时相当于单引号)
反引号:反引号当中的字符将被解释为 命令去执行,等价于 $()
变量的作用域:全局变量 、 局部变量
全局变量:从定义开始到脚本结束或者显示删除变量一直有效;可以在脚本中或函数中定义,在脚本中定义的变量都是全局变量,函数中默认也是全局变量,也可以在函数中 在变量的前面 加 ”local“ 把变量设定了局部变量(只在函数中有效)
系统变量: $0 $* $@ $? $$ $#
环境变量:所有子shell都可以使用的变量 如: PATH 、HOME(cd 的默认目录)、TMOUT (Shell 非活动退出时间)、SHELL (shell 的全路径)
变量赋值: 用“=”,两边不能有空格
引用变量的值: 变量前加"$"
清除变量: unset var
命令替换: 将命令执行的结果赋给变量,可以用 反引号 `` 或 $() 如 b=`pwd` or b=$(pwd)
Shell 之条件测试 : "test" 命令 和 "[" 命令 (若测试条件为真,则返回值为0)
1. test expression
2. [ expression ] (实际上 "[" 在Shell中是一个命令,因为命令与参数之间本来就需要有一个空格所以 [ ] 需要前后保持空格,Shell中为了增强可读性所以 用“]” 与 “[”配对
字符串测试:
1. -z "string" :判断字符串是否为空
2.“string1” = “string2” :判断字符串是否相等 (“=”两边需要留出一个空格,字符串需要加双引号)
3. ”string1“ != ”string2 “: 判断字符串是否不等 (“!=” 两边需要留出一个空格,字符串需要加双引号)
整数测试:
1. number1 gt number2 :是否满足大于条件
2. number1 lt number2 :是否满足小于条件
3. number1 eq number2 : 是否满足等于条件
4. number1 ge number2 : 是否满足大于等于条件
5. number1 le number2 : 是否满足小于等于条件
文件测试: (如下仅列出一些常用的判断)
1. -e file1 : 文件file1 是否存在
2. -f file1 : 是否file1存在并且为普通文件类型
3. -d file1 : 是否file1 存在且为目录类型
4. -b file1 : 是否file1 存在且为块类型
逻辑操作符:
1. ! expression :expression为假,判断条件为真,返回0
2. expression1 -a expression2 : 两个表达式都真,判断条件才为真,返回0
3. expression1 -o expression2 :只要一个表达式为真,判断条件就为真,返回0
简单样例如下:
#! /bin/bash
a=1 b=2 c=3 d=4
if [ $a lt $b -a $c lt $d ]
then echo "yes"
else echo "no"
fi
算术运算符:
+ :相加
- :相减
* :相乘
/ : 相除
% :求余
** :幂运算
4中算术运算方式:
1. `expr expression` : 如 result1=`expr 2 + 3 ` (运算符两边要有空格,并且是纯数字运算,不能用$var 取值) expr 不支持 幂运算
expr 的运算中 * 和 () 需要转义 :如 result2=`expr 3 \* \( 3 + 5 \)`
2. $((expression)) : 如 result3=$(( 3 * (2+3) )) result4=$(( 2**3 ))
3. $[ expression ] : 语法和 $(())等价
4. let expression : 如 i=3 let i=i+1 (除了 expr 之外,$(()) 和$[] 都支持这种方式 如: i=3 i=$((i+1)) 、 i=3 i=$[i+1]
Shell 之条件判断:
1. 简单的 if 判断 :如下:
----------------------------------------------------------------------------------------------------------
if [ expression ] if test expression ; then
then statement1
statement1 或者 statement2
statement2 fi
fi
--------------------------------------------------------------------------------------------------------
2. 使用 if else / if elif else 判断多条件: 如下:
---------------------------------------------------------------------------------------------------------
#! /bin/bash #! /bin/bash
if [ expression1 ] if [ expression1 ]
then then
statement1 statement1
statement2 statement2
else elif [ expression2 ] # 用elif 代替 else if 从而省掉了结尾的对应的 fi
if [ expression2 ] 或者 then
then statement3
statement3 statement4
statement4 else
else statement5
statement5 fi
fi
fi
--------------------------------------------------------------------------------------------------------------
3.用 case 判断多条件语: 如下:
#! /bin/bash
read -p "Please input one number :" var
case $var in
value1)
statement1
statement2
;;
value2)
statement3
statement4
;;
value3)
exit
;;
*)
statement10
;;
esac
当然也可以 使用 “ &&” “||” 取代简单的 if 判断语句如:
test $i -gt 5 && echo "yes" <===> if test $i -gt 5 ;then echo "yes"; fi
test $i -gt 5 || echo "no " <==> 条件为真不运行后者,否者反之
当然除了条件判断之外,命令同样适用:如下:
cmd1 && cmd2 :当两个命令都能运行成功时候才同时运行
cmd1 || cmd2 :当前者运行失败 才运行后者,否则 不运行后者
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>...................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Shel l循环结构<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>...................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Shell 循环结构: for 循环、 while 循环、 until 循环
1. for循环又分为: 带列表的循环、不带列表的循环、类C 的循环
(1)、带列表的循环:如下: (2)、不带列表的循环: 如下: (3)、类C风格的for循环 :如下:
for var in {value1 value2 value3} for var for (( expression1;expression2;expression3))
do do do
statement statement statement
done done done
带列表的for循环还可以 :
for var in {1..10} (从1连续增加到10)
for var in {1..10..2} (从1到10,步长是2)
不带列表的for循环将从命令行读取参数列表 比如 :bash test.sh 1 2 3
2. while 循环 如下:
while [ expression ] # 等价于 while test expression
do
statement
done
3. until 循环 如下:
until test expression #等价于 until [ expression ]
do
statement
done
下面用三种循环写一个批量增加用户的脚本供大家参考他们的异同之处:
1. 2. 3.
#! /bin/bash #! /bin/bash #! /bin/bash
for ((i=1;i<=10;i++)) i=1 i=1
do while [ $i -le 10 ] until [ $i -gt 10]
useradd user$i do do
echo "password" | passwd --stdin user$i useradd user$i useradd user$i
done echo "password" | passwd --stdin user$i echo "password" | passwd --stdin user$i
let i=i+1 i=$[ i+1 ] # 或者 i=$(( i+1 ))
done done
不难发现,for 和 while 中的条件判断为真时候,执行循环体,直到判断条件不成立时候,退出循环;而until 刚好相反
用for嵌套循环写一个基本的乘法表:
#!/bin/bash
for ((i=1;i<=9;i++))
do
for ((j=1;j<=i;j++))
do
product=$[ j*i ]
echo - n -e " $j*$i=$product \t" # -n 取消默认换行 ; -e 能够支持转义字符 使得\t 能被当做制表符解释
done
echo #内层循环结束后,输出空字符,重在使用echo的默认换行功能
done
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.......................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Shell 之 正则表达式<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..........................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
所谓正则表达式 就是描述某些字符串匹配规则的工具;主要用在处理文本;
常见的支持正则表达式的工具如下:
grep 命令族: 用于匹配文本行
sed 流编辑器:用于改变输入流
awk : 用于处理字符串的语言
more and less :查看文本
vi Vim ed : 文本编辑
正则表达式中常见的元字符的意义如下:
1. " ^" :行首定位符 ; 如下
cat /etc/passwd | grep "^user"
2. "$" :行尾定位符 :如下
cat /etc/passwd |grep "user$"
3. " . " : 单字符匹配:表示至少有一个字符 (包括空格)如下:
grep "ora." test1
4 . " *" :限定符 :表示*前面一个字符重复0---n次
5. " []" :字符集匹配: 只要匹配当中任何一个字符即可满足: 如下
grep "ora[abc]" test1
6."[^]" :字符集不匹配: 作用与 [] 相反
Shell 之 sort 排序: (注意:sort 命令中一个文本最多包括10列)
-k 指定列排序 如: sort -k 3,3 file :按照第三列排序 ; sort -k 2,2nr -k 3,3n file 按照第2列以数字倒序 ,第3列正序排序
-r 反序列排序 如:sort -r -k 3 file :按照第三列到尾列进行颠倒排序
-n 按数字排序 (因为默认所有字符都按照字符串排序) 如: sort -r -n -k 3,3 file :把第三列以数字的形式倒序排序
-t 自定义分隔符排序 (默认是连续的空格或制表符) 如: sort -t : -k 3,3n /etc/passwd : 以 : 为分隔符,把第三列以数字形式进行排序
-u 删除重复的行,只保留一行 如: sort -u file1 >file2
sort [-r] file1 file2 ... :按照顺序/倒序合并文件
如: sort file1 file2 > file3
Shell 之 cut 选取列:
-d 定义分隔符(默认是制表符): 如: cut -d ": "
-f 选取指定的列 : 如 cut -d ":" -f 1 /etc/passwd 、 cut -d ":" -f 1,3 /etc/passwd 、 cut -d ":" -f 1-3 /etc/passwd (分别是截取第一列,第一和第三列,第一到第三列)
-c 按行选取指定的字符 : 如 : cut -c 2 /etc/passwd 、 cut -c 2-3 /etc/passwd 、 cut -c 2-3,6 /etc/passwd (分别是选每行的第二个字符,第二到第三字符,第二三第六字符)
wc -l :统计行数
wc -w :统计单词个数
wc -m: 统计字符个数
wc -c : 统计字节数
wc -L :统计最长行的长度(单位字节)
Shell之 sed 流编辑器之常用操作:(默认会读取行并输出)
-n 取消默认输出 (就类似 echo -n 取消默认换行一样)
1. p 选择文本: 格式如: sed -n "1,3p" file1 :打印输出第1行到第3行 (-n取消默认输出,否则会把整个文本再原样输出一次)
2. s 替换文本: 格式如:sed " 1,3 s/hello/HELLO/g " file 、 sed -n " 1,3 s/abc/ABC / file 替换第一到第三行的"abc” 为 ”ABC" ,前者全局替换,后者只替换第一个匹配的字符串
3. d 删除文本: 格式如: sed "1 ,3 d" file1 或者 sed -e 1,3d file1 (-e 等价于 " ") : 删除第1到第3列
Shell之awk字符串处理:
-F " " :指定字符串分隔符 : 如 awk -F " : " ' { printf $1 } ' /etc/passwd (以 " : " 为分割符 打印第一个字段) 注意: { printf $1 } 需要用单引号 引起来
awk 还支持 do ....while 循环 (do....while 是先执行循环体再判断条件,所以相比较do 至少会循环一次)
</string
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Shell 入门基础<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Shell 既是一种脚本解释器(读取脚本文件并执行语句,供用户和内核通信),又是一种脚本语言(脚本语言是相对于编译型语言来说的,无需编译即可运行)。
位置参数: 向Shell脚本传递的参数
$n: 向脚本传递的第n个参数(n=1,、2、3、4....9)
$0: 脚本的名字
$# : 位置参数的总个数
$* : 以“ $1 $2 $3....$n" 的形式输出所有位置参数的值
$@ : 以 ”$1" "$2" "$3" ....."$n" 的形式输入所有位置参数的值
$? : 上一条命令的执行状态码{0-255},0表示执行成功,非0 执行失败
$$: 返回本程序的ID ,即 进程PID
不过 经过实验,貌似$* 和$@ 作用并没有什么不同
以上 $n $0 $# $* $? .....都是系统变量
Shell脚本通常应该具备的三要素:
1. 指定脚本解释器以及解释器的绝对路径 :如 #!/bin/bash (当安装有多个脚本解释器时候,可以指定其他不同解释器 如:#!/user/bin/php ) (也可以指定某些命令 如: #!/bin/more #! /bin/cat 如此一来就会把shell语句原样输出)
2. 注释 说明代码功能
3. 可执行语句,实现程序的功能
# echo "$SHELL" 查看当前系统默认的shell
# echo "$BASH_VERSION" 查看当前shell的版本
#cat /etc/shells 列出目前系统支持的shell
当我们安装了新的shell之后,兵不能立即使用,需要将其绝对路径添加到 /etc/shells 列表中 :如 echo " /bin/local/Python " >> /etc/shells
Shell 注释风格:
1. # 单行注释
2. <<string
..................
..................<string
: 多行注释
string
Shell 执行方式:
1. 授予脚本可执行权限,使得脚本可以直接执行 : 如 # chmod a+x test1.bash # ./test1.bash # /home/oracle/test1.sh
2.调用脚本解释器 来执行: 如 # bash test1.sh # sh test1.sh
3. 用" source " 或 “ . " 执行: 如 # source test1.sh # . test1.sh
前两种方式会开启一个子Shell,在子Shell 中去执行脚本中的命令,然后退出子Shell。第三种方式直接在当前Shell中执行语句。
Shell的退出状态:
每条语句执行完之后都会有一个状态码 (0---255); 0 表示上一条语句执行成功,否则失败。
脚本和函数执行完之后也会有退出状态码,默认由脚本和函数的最后一条语句的退出状态码决定
也可以直接在脚本中 用exit 指定脚本退出状态码 ,此时脚本执行到此处,便以指定状态码退出脚本。(如果exit 后面还有语句也不再执行)
Shell 之 vi :
一般模式:执行vi 操作, 刚进入的模式。 可进行 dd y$ 等操作
编辑模式:在一般模式 点击 i o 等进去可编辑文本的模式。可进行文本的编辑
命令模式:在一般模式 点击 Shift + : 进入命令模式 。 可进行 wq ! q! 等保存退出的操作 以及 set nu 显示行号
vi 操作:
a---从当前字符后面插入;
i---从当前字符前面插入;
A---光标移动到当前行的最后面;
I---光标移动到当前行的最前面;
o---光标从当前行的下面一行开始插入;
O---光标从当前行的上面一行开始插入;
u---恢复到操作之前的状态;
gg--光标移动到界面的首行;
G---光标移动到界面的尾行;
nG--光标移动到第n行;
d$--删除本行光标所在字符以及其后字符;
d#--删除本行光标前面字符;
dgg/d1G--删除光标所在行到第一行
dG-- 删除光标所在行到最后一行
yy--复制当前行
nyy--复制从当前行开始的n行
y^--复制当前到行首的内容
y$--复习当前到行尾的内容
p--从光标所在字符后面插入
P--从光标所在字符
:set nu --设置行号; set nonu ---取消行号
一般模式下: ZZ or :wq!--保存退出;
h--光标向左移动;
l--光标向右移动;
j--光标向下移动;
k--光标向上移动;
正在进行 vi 编辑时候,如果想临时进去命令行查看东西时候,可以 用 CTRL + z 把 vi 暂停到后台,之后 在用 fg 命令 把vi调到前台继续操作(也可以先执行jobs 查看目前的后台工作)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>...................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>> >>>>>>>> >>>>>>>>>>>>>>>>>>>>Shell 编程基础<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Shell 之 变量:
本质上 变量是程序中保存用户数据的一段内存空间,变量名就是这段内存空间的地址;变量名可以有字母、 数字、 下划线组成,只能以字母或下划线开头。
根据变量是否需要强制指定变量类型可以分为 :强语言类型、弱语言类型
强语言类型:程序中需要强制指定变量数据类型的语言:如 Java、C++
弱语言类型:程序中不要求强制指定变量数据类型的语言:如 VBScript 、Shell
根据变量类型确定的时间,可以分为: 静态语言、动态语言
动态语言类型:在程序执行过程中才确定变量的数据类型:如VBScript 、PHP、Python
静态语言类型:在程序编译期间就确定变量的数据类型:如 Java 、C++
显然Shell 属于动态和弱语言
Shell 无需事先定义变量,可以直接使用变量并赋值,亦不用显式指定变量类型;
Shell中变量不分数据类型,统一按照字符串存储,但是变量的数据类型会根据不同的操作自动变化,例如字符串的比较,数字的运算等。
当然有时为了控制变量 也可以用declare/typeset 来赋予变量一些属性:
declare/ typeset -i var : 定义整型
declare / typeset -r var : 定义只读变量
declare / typeset -x var :将变量设置成环境变量,等价于 export var
Shell 之 变量和引号:
Shell中引号有三种: 双引号 ” 、 单引号 ' 、 反引号 `
单引号 : 单引号里面的所有字符都将被解释为普通字符
双引号:除了 ”\“ (转义符)、“$” 、” ” “ (双引号) 、 “ `” (反引号) 保留特殊功能外,其他所有字符都被解释为普通字符(此时相当于单引号)
反引号:反引号当中的字符将被解释为 命令去执行,等价于 $()
变量的作用域:全局变量 、 局部变量
全局变量:从定义开始到脚本结束或者显示删除变量一直有效;可以在脚本中或函数中定义,在脚本中定义的变量都是全局变量,函数中默认也是全局变量,也可以在函数中 在变量的前面 加 ”local“ 把变量设定了局部变量(只在函数中有效)
系统变量: $0 $* $@ $? $$ $#
环境变量:所有子shell都可以使用的变量 如: PATH 、HOME(cd 的默认目录)、TMOUT (Shell 非活动退出时间)、SHELL (shell 的全路径)
变量赋值: 用“=”,两边不能有空格
引用变量的值: 变量前加"$"
清除变量: unset var
命令替换: 将命令执行的结果赋给变量,可以用 反引号 `` 或 $() 如 b=`pwd` or b=$(pwd)
Shell 之条件测试 : "test" 命令 和 "[" 命令 (若测试条件为真,则返回值为0)
1. test expression
2. [ expression ] (实际上 "[" 在Shell中是一个命令,因为命令与参数之间本来就需要有一个空格所以 [ ] 需要前后保持空格,Shell中为了增强可读性所以 用“]” 与 “[”配对
字符串测试:
1. -z "string" :判断字符串是否为空
2.“string1” = “string2” :判断字符串是否相等 (“=”两边需要留出一个空格,字符串需要加双引号)
3. ”string1“ != ”string2 “: 判断字符串是否不等 (“!=” 两边需要留出一个空格,字符串需要加双引号)
整数测试:
1. number1 gt number2 :是否满足大于条件
2. number1 lt number2 :是否满足小于条件
3. number1 eq number2 : 是否满足等于条件
4. number1 ge number2 : 是否满足大于等于条件
5. number1 le number2 : 是否满足小于等于条件
文件测试: (如下仅列出一些常用的判断)
1. -e file1 : 文件file1 是否存在
2. -f file1 : 是否file1存在并且为普通文件类型
3. -d file1 : 是否file1 存在且为目录类型
4. -b file1 : 是否file1 存在且为块类型
逻辑操作符:
1. ! expression :expression为假,判断条件为真,返回0
2. expression1 -a expression2 : 两个表达式都真,判断条件才为真,返回0
3. expression1 -o expression2 :只要一个表达式为真,判断条件就为真,返回0
简单样例如下:
#! /bin/bash
a=1 b=2 c=3 d=4
if [ $a lt $b -a $c lt $d ]
then echo "yes"
else echo "no"
fi
算术运算符:
+ :相加
- :相减
* :相乘
/ : 相除
% :求余
** :幂运算
4中算术运算方式:
1. `expr expression` : 如 result1=`expr 2 + 3 ` (运算符两边要有空格,并且是纯数字运算,不能用$var 取值) expr 不支持 幂运算
expr 的运算中 * 和 () 需要转义 :如 result2=`expr 3 \* \( 3 + 5 \)`
2. $((expression)) : 如 result3=$(( 3 * (2+3) )) result4=$(( 2**3 ))
3. $[ expression ] : 语法和 $(())等价
4. let expression : 如 i=3 let i=i+1 (除了 expr 之外,$(()) 和$[] 都支持这种方式 如: i=3 i=$((i+1)) 、 i=3 i=$[i+1]
Shell 之条件判断:
1. 简单的 if 判断 :如下:
----------------------------------------------------------------------------------------------------------
if [ expression ] if test expression ; then
then statement1
statement1 或者 statement2
statement2 fi
fi
--------------------------------------------------------------------------------------------------------
2. 使用 if else / if elif else 判断多条件: 如下:
---------------------------------------------------------------------------------------------------------
#! /bin/bash #! /bin/bash
if [ expression1 ] if [ expression1 ]
then then
statement1 statement1
statement2 statement2
else elif [ expression2 ] # 用elif 代替 else if 从而省掉了结尾的对应的 fi
if [ expression2 ] 或者 then
then statement3
statement3 statement4
statement4 else
else statement5
statement5 fi
fi
fi
--------------------------------------------------------------------------------------------------------------
3.用 case 判断多条件语: 如下:
#! /bin/bash
read -p "Please input one number :" var
case $var in
value1)
statement1
statement2
;;
value2)
statement3
statement4
;;
value3)
exit
;;
*)
statement10
;;
esac
当然也可以 使用 “ &&” “||” 取代简单的 if 判断语句如:
test $i -gt 5 && echo "yes" <===> if test $i -gt 5 ;then echo "yes"; fi
test $i -gt 5 || echo "no " <==> 条件为真不运行后者,否者反之
当然除了条件判断之外,命令同样适用:如下:
cmd1 && cmd2 :当两个命令都能运行成功时候才同时运行
cmd1 || cmd2 :当前者运行失败 才运行后者,否则 不运行后者
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>...................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Shel l循环结构<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>...................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Shell 循环结构: for 循环、 while 循环、 until 循环
1. for循环又分为: 带列表的循环、不带列表的循环、类C 的循环
(1)、带列表的循环:如下: (2)、不带列表的循环: 如下: (3)、类C风格的for循环 :如下:
for var in {value1 value2 value3} for var for (( expression1;expression2;expression3))
do do do
statement statement statement
done done done
带列表的for循环还可以 :
for var in {1..10} (从1连续增加到10)
for var in {1..10..2} (从1到10,步长是2)
不带列表的for循环将从命令行读取参数列表 比如 :bash test.sh 1 2 3
2. while 循环 如下:
while [ expression ] # 等价于 while test expression
do
statement
done
3. until 循环 如下:
until test expression #等价于 until [ expression ]
do
statement
done
下面用三种循环写一个批量增加用户的脚本供大家参考他们的异同之处:
1. 2. 3.
#! /bin/bash #! /bin/bash #! /bin/bash
for ((i=1;i<=10;i++)) i=1 i=1
do while [ $i -le 10 ] until [ $i -gt 10]
useradd user$i do do
echo "password" | passwd --stdin user$i useradd user$i useradd user$i
done echo "password" | passwd --stdin user$i echo "password" | passwd --stdin user$i
let i=i+1 i=$[ i+1 ] # 或者 i=$(( i+1 ))
done done
不难发现,for 和 while 中的条件判断为真时候,执行循环体,直到判断条件不成立时候,退出循环;而until 刚好相反
用for嵌套循环写一个基本的乘法表:
#!/bin/bash
for ((i=1;i<=9;i++))
do
for ((j=1;j<=i;j++))
do
product=$[ j*i ]
echo - n -e " $j*$i=$product \t" # -n 取消默认换行 ; -e 能够支持转义字符 使得\t 能被当做制表符解释
done
echo #内层循环结束后,输出空字符,重在使用echo的默认换行功能
done
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.......................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Shell 之 正则表达式<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>..........................<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
所谓正则表达式 就是描述某些字符串匹配规则的工具;主要用在处理文本;
常见的支持正则表达式的工具如下:
grep 命令族: 用于匹配文本行
sed 流编辑器:用于改变输入流
awk : 用于处理字符串的语言
more and less :查看文本
vi Vim ed : 文本编辑
正则表达式中常见的元字符的意义如下:
1. " ^" :行首定位符 ; 如下
cat /etc/passwd | grep "^user"
2. "$" :行尾定位符 :如下
cat /etc/passwd |grep "user$"
3. " . " : 单字符匹配:表示至少有一个字符 (包括空格)如下:
grep "ora." test1
4 . " *" :限定符 :表示*前面一个字符重复0---n次
5. " []" :字符集匹配: 只要匹配当中任何一个字符即可满足: 如下
grep "ora[abc]" test1
6."[^]" :字符集不匹配: 作用与 [] 相反
Shell 之 sort 排序: (注意:sort 命令中一个文本最多包括10列)
-k 指定列排序 如: sort -k 3,3 file :按照第三列排序 ; sort -k 2,2nr -k 3,3n file 按照第2列以数字倒序 ,第3列正序排序
-r 反序列排序 如:sort -r -k 3 file :按照第三列到尾列进行颠倒排序
-n 按数字排序 (因为默认所有字符都按照字符串排序) 如: sort -r -n -k 3,3 file :把第三列以数字的形式倒序排序
-t 自定义分隔符排序 (默认是连续的空格或制表符) 如: sort -t : -k 3,3n /etc/passwd : 以 : 为分隔符,把第三列以数字形式进行排序
-u 删除重复的行,只保留一行 如: sort -u file1 >file2
sort [-r] file1 file2 ... :按照顺序/倒序合并文件
如: sort file1 file2 > file3
Shell 之 cut 选取列:
-d 定义分隔符(默认是制表符): 如: cut -d ": "
-f 选取指定的列 : 如 cut -d ":" -f 1 /etc/passwd 、 cut -d ":" -f 1,3 /etc/passwd 、 cut -d ":" -f 1-3 /etc/passwd (分别是截取第一列,第一和第三列,第一到第三列)
-c 按行选取指定的字符 : 如 : cut -c 2 /etc/passwd 、 cut -c 2-3 /etc/passwd 、 cut -c 2-3,6 /etc/passwd (分别是选每行的第二个字符,第二到第三字符,第二三第六字符)
wc -l :统计行数
wc -w :统计单词个数
wc -m: 统计字符个数
wc -c : 统计字节数
wc -L :统计最长行的长度(单位字节)
Shell之 sed 流编辑器之常用操作:(默认会读取行并输出)
-n 取消默认输出 (就类似 echo -n 取消默认换行一样)
1. p 选择文本: 格式如: sed -n "1,3p" file1 :打印输出第1行到第3行 (-n取消默认输出,否则会把整个文本再原样输出一次)
2. s 替换文本: 格式如:sed " 1,3 s/hello/HELLO/g " file 、 sed -n " 1,3 s/abc/ABC / file 替换第一到第三行的"abc” 为 ”ABC" ,前者全局替换,后者只替换第一个匹配的字符串
3. d 删除文本: 格式如: sed "1 ,3 d" file1 或者 sed -e 1,3d file1 (-e 等价于 " ") : 删除第1到第3列
Shell之awk字符串处理:
-F " " :指定字符串分隔符 : 如 awk -F " : " ' { printf $1 } ' /etc/passwd (以 " : " 为分割符 打印第一个字段) 注意: { printf $1 } 需要用单引号 引起来
awk 还支持 do ....while 循环 (do....while 是先执行循环体再判断条件,所以相比较do 至少会循环一次)
</string
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31135825/viewspace-2112894/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/31135825/viewspace-2112894/