ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

shell入门(五)

2020-12-14 23:34:18  阅读:270  来源: 互联网

标签:shell 入门 shellDemo echo expect root declare localhost


目录

1、随机数

1、如何生成随机数

RANDOM,随机会产生0-32767的随机整数

产生一个随机数
[root@localhost ~]# echo $RANDOM
13214
产生0-10之间的随机数,只需要取余11
[root@localhost shellDemo]# echo $[RANDOM%11]
6
产生1-50之间的随机数
[root@localhost ~]# echo $[RANDOM%50+1]
35
产生10-99之间的随机数
[root@localhost ~]# echo $[RANDOM%90+10]
98
产生100-999的随机数
[root@localhost ~]# echo $[RANDOM%900+100]
914
产生50-100的随机数
[root@localhost ~]# echo $[RANDOM%51+50]

2、随机产生以139开头的电话号码

#! /bin/env bash

# 产生1000个以139开头的电话号码并保存文件phonenum.txt中

#文件值
file=/root/shellDemo/phonenum.txt

#循环
for((i=1;i<=1000;i++))
do
#每一个都取随机数,避免重复
        n1=$[RANDOM%10]
        n2=$[RANDOM%10]
        n3=$[RANDOM%10]
        n4=$[RANDOM%10]
        n5=$[RANDOM%10]
        n6=$[RANDOM%10]
        n7=$[RANDOM%10]
        n8=$[RANDOM%10]
#>>追加到文件中
        echo "139$n1$n2$n3$n4$n5$n6$n7$n8" >>  $file
done

3、随机抽出5位幸运观众

具体需求:

  1. 在上面的1000个手机号里抽奖5个幸运观众,显示出这5个幸运观众。
  2. 但只显示头3个数和尾号的4个数,中间的都用*代替

① 思路

  1. 确定幸运观众所在的行 0-1000 随机找出一个数字 $[$RANDOM%1000+1]
  2. 将电话号码提取出来 head -随机产生行号 phonenum.txt |tail -1
  3. 显示前3个和后4个数到屏幕 echo 139****

② 落地实现

#! /bin/env bash
# 随机抽取2个幸运观众,并显示出来

#获取幸运观众个数
n=$1

#定义变量
phone=/root/shellDemo/phonenum.txt

#循环
for((i=1;i<=$n;i++))
do
        #确定文件行数,命令执行结果赋值给变量需要使用``包起命令来
        line=`wc -l $phone |cut -d ' ' -f1`
        #产生1-line之间的随机数
        num=$[RANDOM%$line+1]
        #将电话号码提取出来
        luck_num=`head -$num $phone |tail -1`

        #显示到屏幕,从第8位开始,截取4位,索引从0开始
        echo "139****${luck_num:7:4}"
        echo $luck_num >> luck.txt
        #删除已经被抽取的幸运观众
        sed -i "/$luck_num/d" $phone
done
[root@localhost shellDemo]# ./randomdemo2.sh 5
139****9240
139****2506
139****0196
139****5403
139****6964
139****2316
#抽一次删除一次
[root@localhost shellDemo]# wc -l phonenum.txt 
1000 phonenum.txt

4、批量创建用户(密码随机产生)

**需求:**批量创建5个用户,每个用户的密码为一个随机数

① 思路

  1. 循环5次创建用户
  2. 产生一个密码文件来保存用户的随机密码
  3. 从密码文件中取出随机密码赋值给用户

② 落地实现

#!/bin/env bash
#crate user and set passwd
#产生一个保存用户名和密码的文件
echo user0{1..5}:itcast$[$RANDOM%9000+1000]#@~|tr ' ' '\n'>> user_pass.file

#循环创建5个用户
for ((i=1;i<=5;i++))
do
	user=`head -$i user_pass.file|tail -1|cut -d: -f1`
	pass=`head -$i user_pass.file|tail -1|cut -d: -f2`
	useradd $user
	echo $pass|passwd --stdin $user
done

2 、嵌套循环

循环嵌套就是外层循环一次,内层循环一轮。

1、打印指定图案

#!/bin/env bash

for((i=1;i<=5;i++))
do
        for((x=1;x<=$i;x++))
        do
                #-n表示不换行输出
                echo -n $x
        done
#换行
echo
done

结果:
1
12
123
1234
12345

3、影响shell程序的内置命令

exit 退出整个程序
break 结束当前循环
continue 跳过本次循环
shift 使位置参数向左移动,默认移动一位,可以使用shift 2

举例说明:

以下脚本都能够实现用户自定义输入数字,然后脚本计算和:
[root@MissHou shell04]# cat shift.sh 
#!/bin/bash
sum=0
while [ $# -ne 0 ]
do
let sum=$sum+$1
#使位置参数向左移动 显示参数1,然后参数2下向左移动一位
shift
done
echo sum=$sum

./shift.sh  1 2 3
6

[root@MissHou shell04]# cat for3.sh 
#!/bin/bash
sum=0
# for循环的一种语法结构
for i
do
let sum=$sum+$i
done
echo sum=$sum

./for3.sh   1  2 3
6

4、expect

expect自动应答,tcl语言,是一门语言。

https://www.cnblogs.com/zhengbin/p/8872836.html

安装:yum -y install expect

例子1::远程登录到另一个服务器上什么都不做,exit退出

[root@localhost shellDemo]# cat expect.sh 
#!/usr/bin/env expect 

#开启一个程序,开启会话,接下来通过 expect ... send 来执行交互操作
spawn ssh root@192.168.169.128

#expect期望输出的字符串,send发送交互字符串,回车为 /n,注意空格
# 捕获相关内容 \r表示回车,exp_continue如果没有上一个,继续往下执行
expect {
        "(yes/no)?" { send "yes\r";exp_continue }
        "password:" { send "12345678\r" }
}
#交互
interact

使用位置参数:

#!/usr/bin/expect
set ip [ lindex $argv 0 ]
set pass [ lindex $argv 1 ]
set timeout 5
spawn ssh root@$ip
expect {
        "yes/no" { send "yes\r";exp_continue }
        "password:" { send "$pass\r" }
}
interact

执行脚本:
[root@localhost shellDemo]# ./expect.sh  192.168.169.128 12345678

例子2::远程登录到另一个服务器上做一些事情,exit退出

#!/usr/bin/expect
set ip [ lindex $argv 0 ]
set pass [ lindex $argv 1 ]
set timeout 5
spawn ssh root@$ip
expect {
        "yes/no" { send "yes\r";exp_continue }
        "password:" { send "$pass\r" }
}

#看到#号就做一些事
expect "#"
#删除目录里a,并回车
send "rm -rf /root/a\r"
#删除完目录,我还想看看主机名
send "hostname\r"
#再打一个日期看看
send "date +%F\r"
#结束程序,等待结束执行,若没有该结束符,脚本可能没有执行完毕就提前退出了
expect eof

执行脚本:
[root@localhost shellDemo]# ./expect.sh  192.168.169.128 12345678

例子3:shell脚本和expect结合使用,在多台服务器上创建1个用户

#!/bin/bash
# 循环在指定的服务器上创建用户和文件

#循环的从文件ip.txt中获取ip和密码
while read ip pass
do
        #/usr/bin/expect 脚本中首先引入解释文件,表明使用哪种 shell 解释器
        # <<-END表示遇到END,结束,这是shell的here文档,-表示END前面允许有制表符,这里不一定要写END,自定义的,一个字符而已
        #如果中途有一些输出全不要,丢到&>/dev/null中
        /usr/bin/expect <<-END
        #开启一个程序
        spawn ssh root@$ip
        expect {
        "(yes/no)?" { send "yes\r";exp_continue }
        "password:" { send "$pass\r" }
        }
        #期望看到#,如果看到就创建一个用户,删除一些东西,然后退出远程服务器
        expect "#" { send "useradd yy1;rm -rf /tmp/*;exit\r" }
        #结束程序
        expect eof
        END
echo "$ip服务器用户创建完毕!"
done < ip.txt

远程服务器查看用户是否创建成功

[root@localhost ~]# id yy1
uid=1001(yy1) gid=1001(yy1) 组=1001(yy1)

例子4:将跳板机上运维用户的公钥推送搭配局域网内可以ping通的所有机器上

跳板机,就是可以给你远程连接的机器,然后通过这个机器再去访问别的机器,

5、sudo简单介绍

给一个账号授予一些权限。

visudo
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL
yunwei  ALL=(root)      NOPASSWD:ALL,!/sbin/shutdown,!/sbin/init,!/bin/rm -rf /

解释说明:
1)第一个字段yunwei指定的是用户:可以是用户名,也可以是别名。每个用户设置一行,多个用户设置多行,也可以将多个用户设置成一个别名后再进行设置。
2)第二个字段ALL指定的是用户所在的主机:可以是ip,也可以是主机名,表示该sudo设置只在该主机上生效,ALL表示在所有主机上都生效!限制的一般都是本机,也就是限制使用这个文件的主机;一般都指定为"ALL"表示所有的主机,不管文件拷到那里都可以用。比如:10.1.1.1=...则表示只在当前主机生效。
3)第三个字段(root)括号里指定的也是用户:指定以什么用户身份执行sudo,即使用sudo后可以享有所有root账号下的权限。如果要排除个别用户,可以在括号内设置,比如ALL=(ALL,!oracle,!pos)。
4)第四个字段ALL指定的是执行的命令:即使用sudo后可以执行所有的命令。除了关机和删除根内容以外;也可以设置别名。NOPASSWD: ALL表示使用sudo的不需要输入密码。
5)也可以授权给一个用户组
	%admin ALL=(ALL) ALL	表示admin组里的所有成员可以在任何主机上以任何用户身份执行任何命令

6、数组定义

数组分类:

  • 普通数组:只能使用整数作为数组索引
  • 关联索引:可以使用字符串作为数组索引

普通数组定义:

一次赋予一个值

数组名[索引下标]=值
array[0]=v0
array[1]=v1
array[2]=v2

一次赋予多个值:

数组名=(v1 v2 v3...)
names=(a b c d)
也可以是一个命令的输出
array1=(`cat 1.txt`)
array2=(`ls /root`)

查看普通数组:

获取指定的元素
[root@localhost shellDemo]# echo ${array1[3]}
world
获取所有元素
[root@localhost shellDemo]# echo ${array1[*]}
hello world hello world
获取数组长度
[root@localhost shellDemo]# echo ${#array1[*]}
4
获取数组元素的索引下标
[root@localhost shellDemo]# echo ${!array1[@]}
0 1 2 3
获取部分元素
[root@localhost shellDemo]# echo ${array1[*]:1:3}
world hello world
查看数组信息
[root@localhost shellDemo]# declare -a
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='()'
declare -a BASH_SOURCE='()'
declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='()'
declare -a GROUPS='()'
declare -a PIPESTATUS='([0]="0")'
declare -a array='([0]="harry" [1]="jack" [5]="jackaaa")'
declare -a array1='([0]="hello" [1]="world" [2]="hello" [3]="world")'
declare -a names='([0]="a" [1]="b" [2]="c" [3]="d")

关联数组定义:

[root@localhost shellDemo]# declare -A asso_array1
[root@localhost shellDemo]# asso_array1[linux]=1
[root@localhost shellDemo]# asso_array1[java]=2
[root@localhost shellDemo]# asso_array1=([php]=3 [python]=4 [go]=5)
[root@localhost shellDemo]# let asso_array1[linux]++

查看关联数组:

获取指定的元素
[root@localhost shellDemo]# echo ${asso_array1[go]}
5
打印数组的所有元素
[root@localhost shellDemo]# echo ${asso_array1[*]}
2 1
打印数组的索引
[root@localhost shellDemo]# echo ${!asso_array1[*]}
java linux
查看关联数组信息
[root@localhost shellDemo]# declare -A
declare -A BASH_ALIASES='()'
declare -A BASH_CMDS='()'
declare -A asso_array1='([java]="2" [linux]="1" )'

使用例子:写一个脚本,统计web服务的不同链接状态个数

在这里插入图片描述

7、其他变量定义

变量内容的删出和替换:
在这里插入图片描述
去除一个目录下的目录和文件:
在这里插入图片描述

标签:shell,入门,shellDemo,echo,expect,root,declare,localhost
来源: https://blog.csdn.net/weixin_42412601/article/details/110997769

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有