expect-正则表达式-sed-cut的使用介绍1

expect实现无交互登录

expect ([ɪkˈspekt] 期待 )是从它发展出来的。如果你想要写一个能够自动处理输入输出的脚本(如向用户提问并且验证密码)又不想面对C或者Perl,那么expect是你的最好的选择。它可以用来做一些linux下无法做到交互的一些命令操作

安装和使用expect

[root@localhost ~]# yum -y install expect

使用expect创建脚本的方法
1)定义脚本执行的shell
#!/usr/bin/expect
这里定义的是expect可执行文件的链接路径(或真实路径),功能类似于bash等shell功能
2)set timeout 30
设置超时时间,单位是秒,如果设为timeout -1 意为永不超时
3)spawn
spawn 是进入expect环境后才能执行的内部命令,如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。不能直接在默认的shell环境中进行执行主要功能,它主要的功能是给ssh运行进程加个壳,用来传递交互指令。
4)expect
这里的expect同样是expect的内部命令
主要功能:判断输出结果是否包含某项字符串,没有则立即返回,否则就等待一段时间后返回,等待时间通过timeout进行设置
5)send
执行交互动作,将交互要执行的动作进行输入给交互指令
命令字符串结尾要加上"\r",如果出现异常等待的状态可以进行核查
6)exp_continue
继续执行接下来的交互操作
7)interact
执行完后保持交互状态,把控制权交给控制台;如果不加这一项,交互完成会自动退出
8)$argv
expect 脚本可以接受从bash传递过来的参数,可以使用 [lindex $argv n]获得,n从0开始,分别表示第一个,第二个,第三个……参数
例1:免密码通过SSH登录服务器(了解) 这里不是用密钥
注:运行脚本时,要把#号后面的注释删除,不然无法运行

[root@localhost ~]# cat user.exp 
#!/usr/bin/expect
set ipaddr "10.10.100.144"
set name "root"
set passwd "toor"
set timeout 30  #设置超时时间,单位是秒;expect超时等待的时间。默认timeout为10s。
spawn ssh $name@$ipaddr   # spawn是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在shell下执行是找不到spawn命令的。这个就好比cd是shell的内建命令,离开shell,就无法执行cd一样。 它主要的功能是给ssh运行进程加个壳,用来传递交互指令。
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "$passwd\r" }     #执行交互动作,与手工输入密码的动作等效。
}

expect "#"   #判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,向下执行;否则就一直等待,直到超时时间到
send "touch /root/root.txt\r"
send "ls /etc > /root/root.txt\r"
send "mkdir /tmp/root\r"
send "exit\r"
expect eof   #执行完成上述命令后,退出Expect,把控制权交给控制台,变回手工操作
[root@localhost ~]# expect  user.exp   #开始执行

对服务器批量管理

[root@localhost ~]# cat ip_pass.txt  #这里写上要执行的IP地址和root用户密码
10.10.100.144 toor
可以写多个IP

[root@localhost ~]# cat user.exp 
#!/usr/bin/expect
set ipaddr [lindex $argv 0]
set passwd [lindex $argv 1]
set timeout 30
spawn ssh root@$ipaddr
expect {
"ys/no" { sed "yes\r";exp_continue }
"password" { sed "$passwd\r" }
}
expect "#"
send "touch /root/test.txt\r"
send "ls/root/test.txt\r"
send "mkdir /root/test\r"
send "exit\r"
expect eof

[root@localhost ~]# cat login.sh 
#!/bin/bash
echo
for ip in `awk '{print $1}' /root/ip_pass.txt`
do
	pass=`grep $ip /root/ip_pass.txt|awk '{print $2}'`
	expect /root/user.exp $ip $pass
done
[root@localhost ~]# ./login.sh 

spawn ssh root@10.10.100.144
root@10.10.100.144's password: 
Last login: Sun Oct 13 23:36:27 2019 from 10.10.100.144
/etc/profile
/etc/bashrc
/root/.bashrc
/root/.bash_profile
[root@localhost ~]# touch /root/test.txt
[root@localhost ~]# ls /etc > /root/test.txt
[root@localhost ~]# mkdir /tmp/test
[root@localhost ~]# exit
登出

正则表达式的使用

在这里插入图片描述
正则表达式,又称规则表达式。(英语:Regular Expression [ˈreɡjulə] 规则的 [ iksˈpreʃən] 表达 ),在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
正则表达式不只有一种,而且LINUX中不同的程序可能会使用不同的正则表达式,如:
工具:grep sed awk
LINUX中常用的有两种正则表达式引擎
基础正则表达式:BRE
扩展正则表达式: ERE

Shell正则表达式的组成
基础正则表达式
在这里插入图片描述

统计/etc/ssh/sshd_config文件中除去空行和#号开头的行的行数

[root@localhost ~]# grep -v "^$\|^#" /etc/ssh/sshd_config    #使用基础正则表达式
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
AuthorizedKeysFile	.ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
Subsystem	sftp	/usr/libexec/openssh/sftp-server
[root@localhost ~]# grep -E -v "^$|^#" /etc/ssh/sshd_config  #扩展正则表达式
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
AuthorizedKeysFile	.ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
Subsystem	sftp	/usr/libexec/openssh/sftp-server
[root@localhost ~]# egrep -v "^$|^#" /etc/ssh/sshd_config     #扩展正则表达式
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
AuthorizedKeysFile	.ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
Subsystem	sftp	/usr/libexec/openssh/sftp-server

点字符

[root@localhost ~]# grep .ot /etc/passwd     #查找passwd文件包括.ot 的字符
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

sed流编辑器

sed strem editor 流编辑器
sed编辑器是一行一行的处理文件内容的。正在处理的内容存放在模式空间(缓冲区)内,处理完成后按照选项的规定进行输出或文件的修改。
接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;
sed也是支持正则表达式的,如果要使用扩展正则加参数-r
sed的执行过程:
1、一次读取一行数据
2、根据我们提供的规则来匹配相关的数据,比如查找root。
3、按照命令修改数据流中的数据,比如替换
4、将结果进行输出
5、重复上面四步

如何使用
语法格式:sed [options] ‘[commands]’ filename

[root@localhost ~]# echo "this is aplle " | sed 's/aplle/dog/'
this is dog 
[root@localhost ~]# echo "this is aplle" > a.txt
[root@localhost ~]#  sed 's/apple/dog/' a.txt
this is aplle
[root@localhost ~]# cat a.txt   #发现并没有修改文件
this is aplle

sed选项|参数
options:
-a 在当前行下面插入文件
-n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令
-e 执行多个sed指令
-f 运行脚本
-i 编辑文件内容 ***
-i.bak 编辑的同时创造.bak的备份
-r 使用扩展的正则表达式

命令:
i 在当前行上面插入文件
c 把选定的行改为新的指定的文本
p 打印 ***
d 删除 ***
r/R 读取文件/一行
w 另存
s 查找
y 替换
h 拷贝模板块的内容到内存中的缓冲区。
H 追加模板块的内容到内存中的缓冲区。
g 获得内存缓冲区的内容,并替代当前模板块中的文本。
G 获得内存缓冲区的内容,并追加到当前模板块文本的后面
D 删除\n之前的内容
P 打印\n之前的内容

替换标记:
数字:表明新文本将替换第几处模式匹配的地方
g:表示新文本将会替换所有匹配的文本
\1:子串匹配标记,前面搜索可以用元字符集(…),
&:保留搜索到的字符用来替换其它字符

sed匹配字符集
^ 匹配行开始,如:/^sed/匹配所有以sed开头的行。
$ 匹配行结束,如:/sed$/匹配所有以sed结尾的行。
. 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。

  • 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。

s 只替换第一个匹配到的字符,将passwd中的root用户替换成test

[root@localhost ~]# sed 's/root/test/' /etc/passwd    #发现只替换了第一个匹配的root,后面的没有替换
test:x:0:0:root:/root:/bin/bash
全面替换标记g
[root@localhost ~]# sed 's/root/test/g' /etc/passwd              #全部替换了
test:x:0:0:test:/test:/bin/bash
[root@localhost ~]# cat userdel.sh 
#!/bin/bash
#awk -F':' '{ print $1}' /etc/passwd  > user.txt
for user in `cat user.txt`
do
	userdel -r $user
	echo "The user deletc success !"
done

将sed中默认的/ 定界符改成#号

[root@localhost ~]# sed 's#/bin/bash#/sbin/nologin#' /etc/passwd  | more

以/来做定界符:

[root@localhost ~]# sed 's/\/bin\/bash/\/sbin\/nologin/' /etc/passwd

按行查找替换
写法如下:
用数字表示行范围;$表示行尾
用文本模式配置来过滤
单行替换,将第2行中bin替换成test

[root@localhost ~]#  sed '2s/bin/test/' /etc/passwd  | more
root:x:0:0:root:/root:/bin/bash
test:x:1:1:bin:/bin:/sbin/nologin

多行替换,如果涉及到多行处理,用逗号表示行间隔。 将第3行到最行尾中bin替换成test

[root@localhost ~]#  sed '2,$s/bin/test/' /etc/passwd  | more
root:x:0:0:root:/root:/bin/bash
test:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/stest:/sbin/nologin

删除第2行到第4行的内容

[root@localhost ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.10.100.144 test.com
10.10.100.145 test.com
10.10.100.146 test.com
[root@localhost ~]# sed '2,4d' /etc/hosts             
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
10.10.100.146 test.com
[root@localhost ~]# sed '/10.10/d' /etc/hosts   #将包含10.10的行删除
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

添加行
命令i(insert插入),在当前行前面插入一行 i
命令a(append附加),在当前行后面添加一行 a
插入
[root@localhost ~]# echo “hello world” | sed 'i\ test ’
test
hello world

追加
[root@localhost ~]# echo “hell word” |sed ‘a\test’
hell word
test
在文件最后追加内容

[root@localhost ~]# sed '$a\10.10.100.144 test.com' /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.10.100.144 test.com
10.10.100.145 test.com
10.10.100.146 test.com
10.10.100.144 test.com   #后面追加的内容        

在文件中第2行之后,开始追加内容

[root@localhost ~]# sed '2a\dierhang' /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
dierhang
10.10.100.144 test.com
10.10.100.145 test.com
10.10.100.146 test.com

在文件中第2行到第4行之后分别追加内容

[root@localhost ~]# sed '2,4a\dierhang' /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
dierhang
10.10.100.144 test.com
dierhang
10.10.100.145 test.com
dierhang
10.10.100.146 test.com

修改行命令c (change) c
将第4行内容改成testtest.com

[root@localhost ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.10.100.144 test.com
10.10.100.145 test.com
10.10.100.146 test.com
[root@localhost ~]# sed '4c\testest.com' /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.10.100.144 test.com
testest.com
10.10.100.146 test.com

将第2行到最后全部修改成testest.com

[root@localhost ~]# sed '2,$c\testest.com' /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
testest.com

将包括10.10.100.144行的内容修改成10.10.100.145

[root@localhost ~]# sed '/10.10.100.144/c\10.10.100.145' /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.10.100.145
10.10.100.145 test.com
10.10.100.146 test.com

打印,直接输入文件中的内容
输入第2行内容

[root@localhost ~]# sed -n '2p' /etc/hosts
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

将修改或过滤出来的内容保存到另一个文件中
将passwd中的包括root字样的行保存到 c.txt 中

[root@localhost ~]# sed -n '/root/w c.txt' /etc/passwd
[root@localhost ~]# cat c.txt 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

-i 对原文件修改,保存( 必会 ) 使用场景: 替换或修改服务器配置文件

[root@localhost ~]# cp /etc/passwd ./
[root@localhost ~]# sed -i 's/root/test/' passwd 
[root@localhost ~]# head -n 1 passwd 
test:x:0:0:root:/root:/bin/bash

修改IP地址

[root@localhost ~]#sed -i 's/IPADDR=10.10.100.144/IPADDR=10.10.100.145/' /etc/sysconfig/network-scripts/ifcfg-ens33

cut命令
cut常用参数
cut命令用来显示行中的指定部分,删除文件中指定字段。
说明:该命令有两项功能,其一是用来显示文件的内容,它依次读取由参数file所指明的文件,将它们的内容输出到标准输出上;其二是连接两个或多个文件,如cut fl f2 > f3将把文件fl和fn的内容合并起来,然后通过输出重定向符“>”的作用,将它们放入文件f3中。

语法: cut(选项)(参数)
选项
-b:仅显示行中指定范围的字节数;
-c:仅显示行中指定范围的字符;
-d:指定字段的分隔符,默认的字段分隔符为“TAB”;
-f:显示指定字段的内容;

输出系统中所有用户名
使用 -f 选项提取指定字段,使用 -d 选项指定字段分隔符,这里以:冒号做分隔

[root@localhost ~]# cut -f1 -d ":" /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
systemd-network
dbus
polkitd
sshd
postfix
chrony
alon
tcpdump
apache
mysql

cut命令可以将一串字符作为列来显示,字符字段的记法:
N-:从第N个字节、字符、字段到结尾;
N-M:从第N个字节、字符、字段到第M个(包括M在内)字节、字符、字段;
-M:从第1个字节、字符、字段到第M个(包括M在内)字节、字符、字段。
上面是记法,结合下面选项将摸个范围的字节、字符指定为字段:

-b 表示字节;
-c 表示字符;
-f 表示定义字段。

打印第1个到第3个字符:

[root@localhost ~]#  cut -c1-3 /etc/passwd
roo
bin
dae
adm
lp:
syn
shu
hal
mai
ope
gam
ftp
nob
sys
dbu
pol
ssh
pos
chr
alo
tcp
apa
mys

打印前2个字符

[root@localhost ~]#  cut -c1-2 /etc/passwd
ro
bi
da
ad
lp
sy
sh
ha
ma
op
ga
ft
no
sy
db
po
ss
po
ch
al
tc
ap
my

打印从第5个字符开始到结尾:

[root@localhost ~]# cut -c5- /etc/passwd
:x:0:0:root:/root:/bin/bash
x:1:1:bin:/bin:/sbin/nologin
on:x:2:2:daemon:/sbin:/sbin/nologin
x:3:4:adm:/var/adm:/sbin/nologin
:4:7:lp:/var/spool/lpd:/sbin/nologin
:x:5:0:sync:/sbin:/bin/sync
down:x:6:0:shutdown:/sbin:/sbin/shutdown
:x:7:0:halt:/sbin:/sbin/halt
:x:8:12:mail:/var/spool/mail:/sbin/nologin
ator:x:11:0:operator:/root:/sbin/nologin
s:x:12:100:games:/usr/games:/sbin/nologin
x:14:50:FTP User:/var/ftp:/sbin/nologin
dy:x:99:99:Nobody:/:/sbin/nologin
emd-network:x:192:192:systemd Network Management:/:/sbin/nologin
:x:81:81:System message bus:/:/sbin/nologin
itd:x:999:998:User for polkitd:/:/sbin/nologin
:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
fix:x:89:89::/var/spool/postfix:/sbin/nologin
ny:x:998:996::/var/lib/chrony:/sbin/nologin
:x:1000:1000::/home/alon:/bin/bash
ump:x:72:72::/:/sbin/nologin
he:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
l:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin

bash脚本语法检查和查看详细的执行过程

检查语法是否有错:
bash -v test.bash #查看bash是否存在语法错误
bash -x test.bash #查看bash详细的执行过程

[root@localhost ~]# cat cat.sh 
# Script to show debug of shell
#
tot=`expr $1 + $2`
secho $tot             #这里故意写错
[root@localhost ~]# bash -v cat.sh 
# Script to show debug of shell
#
tot=`expr $1 + $2`
expr $1 + $2
expr: 语法错误
secho $tot 
cat.sh:行4: secho: 未找到命令
[root@localhost ~]# sed -i 's/secho/echo/' cat.sh
[root@localhost ~]# bash cat.sh 2 4
6
[root@localhost ~]# cat 99.sh 
for i in  `seq 9`
do
         for j in `seq $i`
         do
              echo  -n  "$i*$j= `echo $(($i*$j))` "
         done
        echo "  "
done
[root@localhost ~]# bash -x 99.sh  #查看九九乘法表shell脚本运行过程
++ seq 9
+ for i in '`seq 9`'
++ seq 1
+ for j in '`seq $i`'
++ echo 1
+ echo -n '1*1= 1 '
1*1= 1 + echo '  '
  
+ for i in '`seq 9`'
++ seq 2
+ for j in '`seq $i`'
++ echo 2
+ echo -n '2*1= 2 '
2*1= 2 + for j in '`seq $i`'
++ echo 4
+ echo -n '2*2= 4 '
2*2= 4 + echo '  '
  
+ for i in '`seq 9`'
++ seq 3
+ for j in '`seq $i`'
++ echo 3
+ echo -n '3*1= 3 '
3*1= 3 + for j in '`seq $i`'
++ echo 6
+ echo -n '3*2= 6 '
3*2= 6 + for j in '`seq $i`'
++ echo 9
+ echo -n '3*3= 9 '
3*3= 9 + echo '  '
  
+ for i in '`seq 9`'
++ seq 4
+ for j in '`seq $i`'
++ echo 4
+ echo -n '4*1= 4 '
4*1= 4 + for j in '`seq $i`'
++ echo 8
+ echo -n '4*2= 8 '
4*2= 8 + for j in '`seq $i`'
++ echo 12
+ echo -n '4*3= 12 '
4*3= 12 + for j in '`seq $i`'
++ echo 16
+ echo -n '4*4= 16 '
4*4= 16 + echo '  '
  
+ for i in '`seq 9`'
++ seq 5
+ for j in '`seq $i`'
++ echo 5
+ echo -n '5*1= 5 '
5*1= 5 + for j in '`seq $i`'
++ echo 10
+ echo -n '5*2= 10 '
5*2= 10 + for j in '`seq $i`'
++ echo 15
+ echo -n '5*3= 15 '
5*3= 15 + for j in '`seq $i`'
++ echo 20
+ echo -n '5*4= 20 '
5*4= 20 + for j in '`seq $i`'
++ echo 25
+ echo -n '5*5= 25 '
5*5= 25 + echo '  '
  
+ for i in '`seq 9`'
++ seq 6
+ for j in '`seq $i`'
++ echo 6
+ echo -n '6*1= 6 '
6*1= 6 + for j in '`seq $i`'
++ echo 12
+ echo -n '6*2= 12 '
6*2= 12 + for j in '`seq $i`'
++ echo 18
+ echo -n '6*3= 18 '
6*3= 18 + for j in '`seq $i`'
++ echo 24
+ echo -n '6*4= 24 '
6*4= 24 + for j in '`seq $i`'
++ echo 30
+ echo -n '6*5= 30 '
6*5= 30 + for j in '`seq $i`'
++ echo 36
+ echo -n '6*6= 36 '
6*6= 36 + echo '  '
  
+ for i in '`seq 9`'
++ seq 7
+ for j in '`seq $i`'
++ echo 7
+ echo -n '7*1= 7 '
7*1= 7 + for j in '`seq $i`'
++ echo 14
+ echo -n '7*2= 14 '
7*2= 14 + for j in '`seq $i`'
++ echo 21
+ echo -n '7*3= 21 '
7*3= 21 + for j in '`seq $i`'
++ echo 28
+ echo -n '7*4= 28 '
7*4= 28 + for j in '`seq $i`'
++ echo 35
+ echo -n '7*5= 35 '
7*5= 35 + for j in '`seq $i`'
++ echo 42
+ echo -n '7*6= 42 '
7*6= 42 + for j in '`seq $i`'
++ echo 49
+ echo -n '7*7= 49 '
7*7= 49 + echo '  '
  
+ for i in '`seq 9`'
++ seq 8
+ for j in '`seq $i`'
++ echo 8
+ echo -n '8*1= 8 '
8*1= 8 + for j in '`seq $i`'
++ echo 16
+ echo -n '8*2= 16 '
8*2= 16 + for j in '`seq $i`'
++ echo 24
+ echo -n '8*3= 24 '
8*3= 24 + for j in '`seq $i`'
++ echo 32
+ echo -n '8*4= 32 '
8*4= 32 + for j in '`seq $i`'
++ echo 40
+ echo -n '8*5= 40 '
8*5= 40 + for j in '`seq $i`'
++ echo 48
+ echo -n '8*6= 48 '
8*6= 48 + for j in '`seq $i`'
++ echo 56
+ echo -n '8*7= 56 '
8*7= 56 + for j in '`seq $i`'
++ echo 64
+ echo -n '8*8= 64 '
8*8= 64 + echo '  '
  
+ for i in '`seq 9`'
++ seq 9
+ for j in '`seq $i`'
++ echo 9
+ echo -n '9*1= 9 '
9*1= 9 + for j in '`seq $i`'
++ echo 18
+ echo -n '9*2= 18 '
9*2= 18 + for j in '`seq $i`'
++ echo 27
+ echo -n '9*3= 27 '
9*3= 27 + for j in '`seq $i`'
++ echo 36
+ echo -n '9*4= 36 '
9*4= 36 + for j in '`seq $i`'
++ echo 45
+ echo -n '9*5= 45 '
9*5= 45 + for j in '`seq $i`'
++ echo 54
+ echo -n '9*6= 54 '
9*6= 54 + for j in '`seq $i`'
++ echo 63
+ echo -n '9*7= 63 '
9*7= 63 + for j in '`seq $i`'
++ echo 72
+ echo -n '9*8= 72 '
9*8= 72 + for j in '`seq $i`'
++ echo 81
+ echo -n '9*9= 81 '
9*9= 81 + echo '  '
[root@localhost ~]# bash 99.sh 
1*1= 1   
2*1= 2 2*2= 4   
3*1= 3 3*2= 6 3*3= 9   
4*1= 4 4*2= 8 4*3= 12 4*4= 16   
5*1= 5 5*2= 10 5*3= 15 5*4= 20 5*5= 25   
6*1= 6 6*2= 12 6*3= 18 6*4= 24 6*5= 30 6*6= 36   
7*1= 7 7*2= 14 7*3= 21 7*4= 28 7*5= 35 7*6= 42 7*7= 49   
8*1= 8 8*2= 16 8*3= 24 8*4= 32 8*5= 40 8*6= 48 8*7= 56 8*8= 64   
9*1= 9 9*2= 18 9*3= 27 9*4= 36 9*5= 45 9*6= 54 9*7= 63 9*8= 72 9*9= 81   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rio520

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值