shell脚本初识
目录
编写要求:
(1)声明: #!/bin/bash (2)正文:必须是shell能识别的
执行:
(1)bash/sh + shell脚本
(2)./ shell脚本(需要当前用户有执行权限)
(3)source /. +shell 脚本 (有权限,当前bash执行)
1:基本定义
增: 变量名=变量值
删:unset
改: 变量名=变量值
查:echo $变量名 /set
2:特殊关键字:
readonly(只读)/export(全局变量)
3:基本注意
(1)变量赋值,都是字符串存在,无法进行计算。
(2)值中有空格,需要用引号。(单引:不能识别$,进行脱义,双引号可以脱义)
(3)反引号:将引号中的命令执行结果赋值给变量。(f=`pwd` echo $f 输出的是当前所在路径 )
`命令`等价于$(命令) (f=$(pwd) echo=$f 输出的是当前所在路径)
4:特殊变量
$?: 上一条命令的返回值!如果返回值是0,则说明上一条命令成功。
$#:传入的参数个数。
$*:大方向和$@一样,个别情况不同。这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体
$@:参数列表。这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待
$0~n: 0指当前的运行脚本名称,其余数字指第几个参数,10以上的参数用${n}大括号括起来。
5:运算符(整数运算)
1:$((运算符))或$[运算符] (num=$((1+1)) / num=$[(1+1)*2])
2:expr +,-,\*,/,% (运算符两端要有空格:expr_1_+_1 _代表空格)(其中不支持括号)
expr `expr_1_+_1`_\*_2_-_1 (3)
expr $(expr_`expr_1_+_1`_\*_2_-_1)_\*_2 (多次计算,` 只能用一次,多用后一个会和前一个匹配,用$解决)
6:条件判断
1:基本语法
[_condition_] 结果为true/false
注意:条件非空即为true,[ atguigu ]返回true,[] 返回false。
echo $? 可以检验[_condition_]
2. 常用判断条件(左右两边要有空格,不加空格就指是字符串,不是运算符。)
(1)两个整数之间比较
= 字符串比较(_=_左右两边要有空格)
-lt 小于(less than) -le 小于等于(less equal)
-eq 等于(equal) -gt 大于(greater than)
-ge 大于等于(greater equal) -ne 不等于(Not equal)
(2)按照文件权限进行判断
-r 有读的权限(read) -w 有写的权限(write)
-x 有执行的权限(execute)
(3)按照文件类型进行判断
-f 文件存在并且是一个常规的文件(file)
-e 文件存在(existence) -d 文件存在并是一个目录(directory)
-s 文件存在且不为空 -L 文件存在且是一个链接(link)
7:流程控制
1.if语法
if_[_条件判断式_] (不能直接连接then,除非加;C语言风格可以 if(($1==1));then 可以没有空格 可以用==)
then
程序
elif 条件判断式
then 程序..
else 程序..
fi (作为结束标记)
localhost:~ string$ cat test3.sh
#! /bin/bash
if [ $1 -eq 1 ]
then
echo "1111"
elif [ $1 -eq 2 ]
then
echo "2222"
elif [ $1 -eq 3 ]
then
echo "3333"
else echo "error"
fi
localhost:~ string$ bash test3.sh 3
3333
localhost:~ string$ bash test3.sh 2
2222
localhost:~ string$ bash test3.sh 1
1111
localhost:~ string$ bash test3.sh 4
error
2:case 语句
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
;;
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
(case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。双分号“;;”表示命令序列结束,相当于java中的break。最后的“*)”表示默认模式,相当于java中的default。)
localhost:~ string$ touch case.sh
localhost:~ string$ vim case.sh
!/bin/bash
case $1 in
"1")
echo "i"
;;
"2")
echo "love"
;;
*)
echo "u"
;;
esac
localhost:~ string$ bash case.sh 1
i
3:for语法
for 变量 in 值1 值2 值3…
do
程序
done
或
for 变量 in 1 2 3; do 程序; done
或
for 变量 in {1..3}; do 程序; done
或
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
或
for (( 初始值;循环控制条件;变量变化 )); do 程序; done
($*和$@都表示传递给函数或脚本的所有参数,不被双引号“”包含时,都以$1 $2 …$n的形式独立输出所有参数。当它们被双引号“”包含时,“$*”会将所有的参数作为一个整体,以“$1 $2 …$n”的形式整体输出所有参数;“$@”会将各个参数分开,以“$1” “$2”…”$n”的形式分别输出所有参数。)
localhost:myShells string$ vim for.sh
#!/bin/bash
for i in "$*"
#$*中的所有参数看成是一个整体,所以这个for循环只会循环一次
do
echo "demo $i"
done
for j in "$@"
#$@中的每个参数都看成是独立的,所以“$@”中有几个参数,就会循环几次
do
echo "demo $j"
done
localhost:myShells string$ bash for.sh 11 22 33
demo 11 22 33
demo 11
demo 33
4:while 语法
while_[_条件判断式_] (while []中只能写条件判断,赋值在while之前做,for可以在[]中都做了)
do
程序
done
或
while((表达式))
do
程序
done
#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
#while (($I<=100))
do
s=$[$s+$i]
#i=$[$i+1]
let i++
done
echo $s
8:系统函数
(1)read(选项)(参数) (从控制台读取用户输入的信息)
选项:
-p:提示要做的事,描述(不加,就无提示);
-t:指定等待的秒数(不加就一直等待,直到输入)。
参数:
变量:指定读取值的变量名
$ vim demo.sh
#!/bin/bash
read -t 7 -p "Enter your name:" NAME
echo $NAME
$ bash demo.sh
Enter your name:
father
$ echo $NAME
father
(2)dirname
读取路径,可以用来指定获取文件路径
localhost:myShells string$ dirname /Users/string/Desktop/myShells
/Users/string/Desktop
basename(可以去后缀)
localhost:myShells string$ basename /Users/string/Desktop/myShells
myShells
localhost:myShells string$ basename /Users/string/Desktop/myShells lls
myShe
9:自定义函数
function funname[()] (function可以省略
)
{
Action;
[return int;]
}
funname
(函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255),调用直接使用函数名就行。)
localhost:myShells string$ vim fun.sh
#!/bin/bash
function sum()
{
s=0
s=$[ $1 + $2 ]
echo "$s"
#return $s
}
read -p "Please input the number1: " n1;
read -p "Please input the number2: " n2;
sum n1 n2;
localhost:myShells string$ ./fun.sh
Please input the number1: 2
Please input the number2: 5
7
shell必掌握手段:
1: wc [选项参数] filename
wc命令用来计算数字。wordcount
利用wc指令我们可以计算文件的Byte数、字数或是列数,若不指定文件名称,或是所给予的文件名为“-”,则wc指令会从标准输入设备读取数据。
选项参数 | 功能 |
-l | 统计文件行数 |
-w | 统计文件的单词数 |
-m | 统计文件的字符数(一个汉字3个占3个字符UTF-8算法,空格不算字符) |
-c | 统计文件的字节数 |
2:cut [选项参数] filename
cut的工作就是“剪”。
具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。
选项参数 | 功能 |
-f | f为fileds,列号,提取第几列,多个用逗号间隔。取第n列后所有列用 -f n-。取1到5,和8列用 -f 1-5,8。 |
-d | d为Descriptor分隔符,按照指定分隔符分割列(默认制表符\t) |
localhost:myShells string$ ifconfig en0 | grep "inet " | cut -d " " -f 2
192.168.019.103
3:sed [选项参数] ‘command’ filename
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容没有改变,只是缓冲区的改变了,除非你使用重定向存储输出。
选项参数 | 功能 |
-e |
多个‘command’时每一个前加,不然只能识别第一个,后面的被认为是文件路径。 |
命令 | 功能描述 |
a | add,a的前面加行号,a的后面接字串,在指定行号下一行出现。 ‘2a li’ 在第二行后加一行 li |
d | delete删除, 用/word/ 进行匹配。sed ‘/li/ d’ li.txt 删除了li.txt 中所以包含’li‘的行。 ‘2d’删除第二行,‘$ d’ 删除最后一行, ‘3,$ d’删除3到最后一行 |
s | serach查找并替换 ‘s/li/leo/g’ 将全文li 替换成leo g代表全文,不加g只替换第一个匹配到的。 |
4: 三个壮汉写的,自称是一门语言,awk是分别取了三个人的首字母没实际意义。
awk [选项参数] ‘pattern1{action1} pattern2{action2}...’ filename
pattern:表示AWK在数据中查找的内容,就是匹配模式,不写就是所以都匹配
action:在找到匹配内容时所执行的一系列命令
一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
选项参数 | 功能 |
-F | 指定输入文件折分隔符,默认是空格切割。 -F ' ' |
-v | 赋值一个用户定义变量 |
内置变量 | 说明 |
FILENAME | 文件名 |
NR | 已读的记录数(行号)numberRow |
NF | 浏览记录的域的个数(切割后列的个数,列号)numberField |
关键字
print: 向屏幕输出内容
$1-$n: 第n列
BEGIN: 代表开始读取文件所遇内容之前,做什么事! 初始化代码块
END: 代表开始读取文件所有内容之后,做什么事! 结束代码块
localhost:myShells string$ awk -F : 'BEGIN{print "Leo"} /^root/{print $1","$7} END{print "Leo"}' passwd
Leo
root,/bin/bash
Leo
用:分割所有行,然后找到以root开始的行中第一列和第七列,中间用逗号分隔。
并且在开头输出leo,结束后输出leo
#找ip
localhost:myShells string$ ifconfig en0 | grep "inet " | awk '{print $2}'
192.168.019.103
#找空行行号。/^$/ 意思是以空^开始,以空$结尾 则这行为空
localhost:myShells string$ awk '/^$/{print NR}' demo.txt
9
5:sort(选项)(参数)
sort命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出。
默认情况以第一个字符串的字典顺序来排序!(abcd...1234...)
sort -t : -urnk 4 demo.txt
使用:分割demo.txt文件每一行,对第四列进行数字、倒叙、去重、排序。
选项 | 说明 |
-n | 依照数值的大小排序 |
-r | 以相反的顺序来排序 |
-t | 设置排序时所用的分隔字符,默认使用TAB |
-k | 指定需要排序的列 |
-u | u为unique的缩写,即如果出现相同的数据,只出现一行 |