天天看点

常用shell实例1

echo使用

#使用-n不换行执行下一句话 将字符串原样输出
[root@test01 ~]# echo aa;echo bb
aa
bb
[root@test01 ~]# echo -n aa;echo bb
aabb
[root@test01 ~]# echo "aabb"
aabb

#使用-e使转义生效
[root@test01 ~]# echo -e "s\tee"
s	ee
[root@test01 ~]# echo -e "s\tee\n"
s	ee

[root@test01 ~]# echo -e "s\tee\n\n\n"
s	ee



[root@test01 ~]# 

#排列组合(括号内一个元素分别和其他括号内元素组合)
[root@test01 ~]# echo {a,b,c}{a,b,c}{a,b,c}
aaa aab aac aba abb abc aca acb acc baa bab bac bba bbb bbc bca bcb bcc caa cab cac cba cbb cbc cca ccb ccc

# 打印10个字符
[root@test01 ~]# echo {1..10}
1 2 3 4 5 6 7 8 9 10

#倒置读取文件  # 删除最后2行
[root@test01 ~]# tac dump.rdb |sed 1,2d |tac
iiiiiiiiiii
ffffffffffff
[root@test01 ~]# cat dump.rdb 
iiiiiiiiiii
ffffffffffff
eeeeeeeeee
dddddddd

# 打印颜色
[root@test01 ~]# echo -e "\e[32mgggggggggg\e[0m"
gggggggggg

# 打印同时写入文件 默认覆盖 -a追加
[root@test01 ~]# cat dump.rdb 
ttttttttt
[root@test01 ~]# echo aaaaaa | tee dump.rdb 
aaaaaa
[root@test01 ~]# cat dump.rdb 
aaaaaa
[root@test01 ~]# echo wwwwww | tee -a dump.rdb 
wwwwww
[root@test01 ~]# cat dump.rdb 
aaaaaa
wwwwww

# 返回目录名
[root@test01 ~]# cat /etc/passwd | awk -F: '{print $1}' | tail -1
mysql
[root@test01 ~]# pwd 
/root
[root@test01 ~]# pwd | awk -F/ '{print $2}'
root      

if语句格式

单分支if语句

if

判断条件;

then

    command

fi   

双分支if语句

if

判断条件;

then

    command

else

    command

fi

多分支if语句

if

判断条件1;

then

    command

elif

判断条件2;

then

    command

else

    command

fi

[root@test01 ~]# cat if.sh 
#!/bin/bash
read -p "please input your score:" a
if ((a<60)) ; then
        echo "you didn,t pass the exam."
else
        echo "good you passed the exam."
fi
[root@test01 ~]# sh if.sh 
please input your score:90
good you passed the exam.
[root@test01 ~]# sh if.sh 
please input your score:45
you didn,t pass the exam.      

在判断数值大小除了可以用”(( ))”的形式外还可以使用”[ ]”。但是就不能使用>, < , = 这样的符号了

要使用 -lt 小于-gt 大于-le 小于等于-ge 大于等于-eq 等于-ne 不等于。

[root@test01 ~]# a=10; if [ $a -lt 5 ]; then echo ok; fi
[root@test01 ~]# a=10; if [ $a -gt 5 ]; then echo ok; fi
ok      

再看看if中使用 && 和 ||的情况。&& 表示“并且”的意思|| 表示“或者”

[root@test01 ~]# a=10; if [ $a -lt 1 ] || [ $a -gt 5 ]; then echo ok; fi
ok
[root@test01 ~]# a=8; if [ $a -gt 1 ] && [ $a -lt 10 ]; then echo ok; fi
ok      

shell 脚本中if还经常判断关于档案属性比如判断是普通文件还是目录判断文件是否有读写执行权限等。

-e 判断文件或目录是否存在

-d 判断是不是目录并是否存在

-f 判断是否是普通文件并存在

-r 判断文档是否有读权限

-w 判断是否有写权限

-x 判断是否可执行

使用if判断时具体格式为 if [ -e filename ] ; then

[root@test01 ~]# if [ -d /home ]; then echo ok; fi
ok
[root@test01 ~]# if [ -f /home ]; then echo ok; fi
[root@test01 ~]# if [ -f if.sh ]; then echo ok; fi
ok
[root@test01 ~]# if [ -w if.sh ]; then echo ok; fi
ok
[root@test01 ~]# if [ -x if.sh ]; then echo ok; fi
[root@test01 ~]# ll
总用量 4
-rw-r--r-- 1 root root 158 7月   9 15:12 if.sh      

case语法格式

case 变量 in

value1)

command

;;

value2)

value3)

esac

case脚本常用于编写系统服务的启动脚本。例如/etc/init.d/iptables中就用到了

[root@test01 ~]# cat case.sh 
#!/binb/ash
read -p "please input a number:" n
a=$[$n%2]
case $a in
1)
  echo "input number is odd"
  ;;
0)
  echo "input number is even"
  ;;
esac
[root@test01 ~]# sh case.sh 
please input a number:1
input number is odd
[root@test01 ~]# sh case.sh 
please input a number:2
input number is even      

for循环的基本结构 

格式一:

for 变量名 in 循环的条件 do

done

说明:

for

执行的时候,从循环列表中的第一个值开始执行循环,遍历循环列表,循环结束。

格式二:

for

((初始值;结束条件;变化值))

do

    command

done

for循环和生成列表在一起用时,通常要进行命令替换,如$(command)或`command`

生成列表的方法

方法一:

{a..b}:表示的是从a到b

{a..b..c}:表示的是从a到c,并且以c为增加值(步长)

[root@test01 ~]touch {1..3}
[root@test01 ~]# ll
总用量 0
-rw-r--r-- 1 root root 0 7月  10 16:17 1
-rw-r--r-- 1 root root 0 7月  10 16:17 2
-rw-r--r-- 1 root root 0 7月  10 16:17 3
[root@test01 ~]# touch {1..6..2}
[root@test01 ~]# ll
总用量 0
-rw-r--r-- 1 root root 0 7月  10 16:19 1
-rw-r--r-- 1 root root 0 7月  10 16:19 3
-rw-r--r-- 1 root root 0 7月  10 16:19 5      

方法二:

1

2

3

seq

[OPTION]... LAST

seq

[OPTION]... FIRST LAST

seq

[OPTION]... FIRST INCREMENT LAST

常用shell实例1

根据参数的不同批量添加和删除用户的脚本

[root@Server3 Learn]# cat useradd.sh 
#!/bin/bash
if [ "$1" == "add" ];then
for user in user{1..10}
do
        id $user &> /dev/null
        if [ $? -ne 0 ];then
                useradd $user &> /dev/null
                echo -n "$user" | passwd --stdin $user > /dev/null
                chage -d 0 $user > /dev/null
        fi
done
elif [ "$1" == "del" ];then
for user in user{1..10}
do
        id $user &> /dev/null
        if [ $? -eq 0 ];then
                userdel -r $user
        fi
done
else
        echo "Usage: $0 add|del"
fi      
常用shell实例1

脚本中的seq 1 5 表示从1到5的一个序列

常用shell实例1

示例4:从1加到100

[root@Server3 Learn]# cat for.sh 
#!/bin/bash
 sum=0
 for i in $(seq 1 100)
#for i in `seq 1 100`
do
#       sum=$(expr $sum + $i)
#       sum=$[$sum+$i]
#       sum=$(($sum+$i))
        let sum=$sum+$i
done
echo "$sum"
[root@Server3 Learn]# 
$(seq 1 100):这一块为循环列表,表示的是从1到100。也可以写成{1..100}。
do和done之间的循环体表示的都是计算数值相加的不同方法,结果都是一样的。      

示例5:

[root@Server3 Learn]# cat for2.sh 
#!/bin/bash
for i in $(cat /etc/passwd | cut -d: -f1)
#for i in `cat /etc/passwd | cut -d: -f1`
do
        echo "Hello $i"
done
[root@Server3 Learn]#      

实例6:

[root@Server3 Learn]# cat for2.sh
#!/bin/bash
line=$(cat /etc/passwd | wc -l)
 for i in $(seq 1 $line)
#for i in `seq $line`
do
echo "hello `head -n $i /etc/passwd | tail -n 1 | cut -d: -f1`, your shell is $(head -n $i /etc/passwd | tail -n 1 | cut -d: -f7)"
done      

while循环基本格式为

while 条件; do

常用shell实例1

也可以把循环条件忽略掉可以常常这样写监控脚本。

while :; do

shell脚本中的函数

函数就是把一段代码整理到了一个小单元中并给这个小单元起一个名字当用到这段代码时直接调用这个小单元的名字即可。有时候脚本中的某段代码总是重复使用如果写成函数每次用到时直接用函数名代替即可这样就节省了时间还节省了空间。

fun.sh 中的sum() 为自定义的函数在shell脚本中要用

函数名()  {

}

这样的格式去定义函数。

常用shell实例1

在shell脚本中函数一定要写在最前面不能出现在中间或者最后因为函数是要被调用的如果还没有出现就被调用肯定是会出错的。

系统变量

bash变量类型

环境变量:声明环境变量的格式export VARNAME=VALUE作用域:当前shell进程及其子进程。

本地变量:声明本地变量的格式VARNAME=VALUE。作用域:对整个脚本进程或整个bash进程有效。

局部变量:声明局部链路的格式local VARNAME=VALUE。作用域:只对当前的代码段有效。

位置变量:$n,第n个位置变量,引用脚本中参数的位置的。如果n大于10,则要写成${n}

特殊变量:bash内置的变量。如$?,保存的是上一个命令的执行状态返回值(范围是0-255),如果是0,则表示正确执行,如果是非0,则表示执行失败。1,2,127为系统预留。其他值则可以用户自已定义。

变量赋值方法:VAR_NAME=VAULE 引用变量:${var_name} 实例:

使用env或者export命令即可全部列出系统预设的全部系统变量了。不过登录的用户不一样这些环境变量的值也不一样。

set不仅可以显示系统预设的变量也可以连同用户自定义的变量显示出来。

使用bash命令即可再打开一个shell此时先前设置的myname变量已经不存在了退出当前shell回到原来shellmyname变量还在。

常用shell实例1
常用shell实例1

1 要想系统内所有用户登录后都能使用该变量

需要在/etc/profile文件最末行加入 “export myname=Aming” 然后运行”source /etc/profile”就可以生效了。此时你再运行bash命令或者直接su - test账户看看。

常用shell实例1

2只想让当前用户使用该变量

需要在用户主目录下的.bashrc文件最后一行加入“export myname=Aming” 然后运行”source .bashrc”就可以生效了。这时候再登录test账户myname变量则不会生效了。

linux下设置自定义变量有规则

a. 设定变量的格式为”a=b”其中a为变量名b为变量的内容等号两边不能有空格

b. 变量名只能由英、数字以及下划线组成而且不能以数字开头

c. 当变量内容带有特殊字符如空格时需要加上单引号

常用shell实例1

特殊情况变量内容中本身带有单引号这就需要用到双引号。

常用shell实例1

d. 如果变量内容中需要用到其他命令运行结果则可以使用反引号

常用shell实例1

e. 变量内容可以累加其他变量的内容需要加双引号

常用shell实例1

在当前shell中运行bash指令后会进入一个新的shell这个shell就是原来shell的子shell了可以用pstree查看一下。

常用shell实例1

pstree这个指令会把linux系统中所有进程通过树形结构打印出来。在父shell中设定一个变量后进入子shell后该变量是不会生效的如果想让这个变量在子shell中生效则要用到export指令。

export其实是声明一下这个变量的意思让该shell的子shell也知道变量abc的值是123.如果export后面不加任何变量名则它会声明所有的变量。

常用shell实例1

想取消某个变量只要输入”unset 变量名”即可。

常用shell实例1

用unset abc后再echo $abc则不再输出任何内容。

20.系统环境变量与个人环境变量的配置文件

用户一登陆shell就自动有了这些变量呢

/etc/profile 这个文件预设了几个重要变量例如PATH, USER, LOGNAME, MAIL, INPUTRC, HOSTNAME, HISTSIZE, umask

/etc/bashrc 这个文件主要预设umask以及PS1。PS1就是我们在敲命令时前面那串字符例如笔者的inux系统PS1就是 [root@localhost ~]# 

常用shell实例1

\u就是用户\h 主机名 \W 则是当前目录\$就是那个’#’了如果是普通用户则显示为’$’

.bash_profile 定义了用户的个人化路径与环境变量的文件名称。每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次。

.bashrc 专用于你的shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取。例如你可以将用户自定义的alias或者自定义变量写到这个文件中。

.bash_history 记录命令历史用的。

.bash_logout 当退出shell时会执行该文件。可以把一些清理的工作放到这个文件中。

 21.linux shell中的特殊符号

 *  : 代表零个或多个字符或数字。

常用shell实例1

test后面可以没有任何字符也可以有多个字符总之有或没有都能匹配出来。

. ? 只代表一个任意的字符

常用shell实例1

不管是数字还是字母只要是一个都能匹配出来。

\ 脱意字符将后面的特殊符号例如”*” 还原为普通字符。

常用shell实例1

 | 管道符作用将符号前面命令的结果丢给符号后面的命令。但并不是所有的命令都可以的一般针对文档操作的命令比较常用例如cat, less, head, tail, grep, cut, sort, wc, uniq, tee, tr, split, sed, awk等等。

cut 截取某一个字段

语法cut -d “分隔字符” [-cf] n 这里的n是数字

-d 后面跟分隔字符分隔字符要用双引号括起来

-c 后面接的是第几个字符

-f 后面接的是第几个区块   -f 1 就是截取第一段-f和1之间的空格可有可无。

常用shell实例1

-c 后面可以是1个数字n也可以是一个区间n1-n2还可以是多个数字n1,n2,n3

常用shell实例1

>, >>, 2>, 2>> 即重定向符号> 以及>> 分别表示取代和追加的意思后面的2> 和 2>> 分别表示错误重定向和错误追加重定向当我们运行一个命令报错时报错信息会输出到当前屏幕如果想重定向到一个文本里则要用2>或者2>>。

常用shell实例1

[ ] 中括号中间为字符组合代表中间字符中的任意一个

常用shell实例1

 分号。想在一行中运行两个或两个以上的命令则需要在命令之间加一个”;”。

常用shell实例1

&& 与 ||与用于多条命令间的分隔符

1) command1 ; command2

2) command1 && command2

3) command1 || command2

使用”;”时不管command1是否执行成功都会执行command2 使用”&&”时只有command1执行成功后command2才会执行否则command2不执行使用”||”时command1执行成功后command2 不执行否则去执行command2总之command1和command2总有一条命令会执行。

split 切割文档常用选项

-b 依据大小来分割文档单位为byte

常用shell实例1

后面的test0000为分割后文件名的前缀分割后的文件名为test0000aa,test0000ab,test0000ac

-l 依据行数来分割文档

常用shell实例1

tr 替换字符常用来处理文档中出现的特殊符号

-d 删除某个字符-d 后面跟要删除的字符

-s 把重复的字符去掉

最常用的就是把小写全部变大写 tr ‘[a-z]’ ‘[A-Z]’

常用shell实例1

当然替换一个字符也是完全可以的。

常用shell实例1

替换、删除以及去重复都是针对一个字符来讲的有一定局限性。

常用shell实例1

tee 后跟文件名类似重定向”>”它在把文件写入后面所跟的文件中同时还显示在屏幕上。

常用shell实例1

sort 用做排序  语法sort [-t 分隔符] [-kn1,n2] [-nru] 这里的n1 < n2

常用shell实例1

-u  在输出行中去除重复行。

常用shell实例1

-r  sort默认的排序方式是升序如果想改成降序就加个-r就搞定了。

常用shell实例1

-o   由于sort默认是把结果输出到标准输出所以需要用重定向才能将结果写入文件形如sort filename > newfile。

常用shell实例1

-kn1,n2 由n1区间排序到n2区间可以只写-kn1即对n1字段排序

常用shell实例1

 uniq 去重复的行

-c 统计重复的行数并把行数写在前面

常用shell实例1

在进行uniq之前需要先用sort排序然后才能uniq否则你将得不到你想要的。

date用来打印当前系统时间

常用shell实例1

%Y表示年%m表示月%d表示日期%H表示小时%M表示分钟%S表示秒

-d 选项它可以打印n天前或者n天后的日期当然也可以打印n个月/年前或者后的日期。同时星期几也是常用的。

常用shell实例1

read -p 选项类似echo的作用