本節(jié)所講內(nèi)容
23.1? expect? 實(shí)現(xiàn)無交互登錄
23.2? 正則表達(dá)式
23.3? sed 流編譯器
23.4?? cut 命令
23.5? 實(shí)戰(zhàn)-bash? 腳本語法檢查和查看詳細(xì)的執(zhí)行過程
23.1?? expect? 實(shí)現(xiàn)無交互登錄
expect? 是它發(fā)展出來的穷吮,如果想要寫一個(gè)能夠自動(dòng)處理輸入輸出的腳本(如向用戶提問并且要驗(yàn)證碼)又不想面對(duì)C或者Perl?? 那么expect 是你最好的選擇?? 它可以用用來做一些linux下無法交互的一些命令操作
安裝?? expect???? 正則表達(dá)式
[root@localhost ~]# yum -y install expect
1)? 定義腳本執(zhí)行的shell?
#! /bin/bash/expect??
這里定義的是expect? 可執(zhí)行文件的連接路徑?? (或真實(shí)路徑) 功能類似于bash? 等shell功能
2)?? set? timeout? 30??
設(shè)置超時(shí)時(shí)間瞻颂,單位是秒? 。如果設(shè)為timeout? -1?? 意味永不過時(shí)
3)? spawn?
spawn? 是進(jìn)入expect 環(huán)境之后才能執(zhí)行的內(nèi)部命令,如果沒有裝expect? 或者直接在默認(rèn)的SHELL下執(zhí)行時(shí)找不到spawn? 命令的額竞慢,不能直接在默認(rèn)的shell環(huán)境中進(jìn)行執(zhí)行主要功能是給ssh? 運(yùn)行進(jìn)程加個(gè)殼
用來傳遞交互指令
4)? expect
這里的expect 同樣是expect 的內(nèi)部命令
主要功能:判斷輸出結(jié)果是否包含某項(xiàng)字符串汤纸,沒有則立即返回,否則等待一段時(shí)間后
timeout 進(jìn)行設(shè)置
5)? send?
執(zhí)行交互動(dòng)作 骗绕,將交互要執(zhí)行的動(dòng)作進(jìn)行輸入給交互指令
命令字符串結(jié)尾要加上"\r"?? 藐窄,如果出現(xiàn)異常等待的狀態(tài)可以進(jìn)行核查
6) exp_continue??
繼續(xù)執(zhí)行接下來的交互操作
7)? interact???
執(zhí)行完保持交互狀態(tài),把控制器交給控制臺(tái)酬土,如果不加這一項(xiàng)荆忍,交互完成后,就會(huì)自動(dòng)退出
8)? $ argv?
expect 腳本可以接受從bash?? 傳遞過來的參數(shù),可以使用?? [ lin dex $argv n] 獲得刹枉,n從
一個(gè)叽唱,第二個(gè),第三個(gè)微宝,棺亭。。蟋软。侦铜。。參數(shù)
例1? :? 面密碼通過ssh? 登錄服務(wù)器? (了解)
注意: 運(yùn)行腳本時(shí)钟鸵,要把#號(hào)后面的文字刪除钉稍,不然無法運(yùn)行
[root@localhost ~]# vim ssh.exp
①#! /usr/bin/expect?? 這是開頭
②#! /usr/bin/expect
不加注釋的腳本
#!/usr/bin/expect
set ipaddr "192.168.1.63"
set name "root"
set passwd "123456"
set timeout 30????#設(shè)置超時(shí)時(shí)間,單位是秒棺耍;expect超時(shí)等待的時(shí)間贡未。默認(rèn)timeout為10s。
spawn ssh $name@$ipaddr???#?spawn是進(jìn)入expect環(huán)境后才可以執(zhí)行的expect內(nèi)部命令蒙袍,如果沒有裝expect或者直接在shell下執(zhí)行是找不到spawn命令的俊卤。這個(gè)就好比cd是shell的內(nèi)建命令,離開shell害幅,就無法執(zhí)行cd一樣消恍。 它主要的功能是給ssh運(yùn)行進(jìn)程加個(gè)殼,用來傳遞交互指令以现。 ?
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "$passwd\r" }???#執(zhí)行交互動(dòng)作狠怨,與手工輸入密碼的動(dòng)作等效。
}
?
expect "#"???#判斷上次輸出結(jié)果里是否包含“password:”的字符串邑遏,如果有則立即返回佣赖,向下執(zhí)行;否則就一直等待记盒,直到超時(shí)時(shí)間到
send "touch /root/xuegod1011.txt\r"
send "ls /etc > /root/xuegod1011.txt\r"
send "mkdir /tmp/xuegod1011\r"
send "exit\r"
expect eof???#執(zhí)行完成上述命令后憎蛤,退出Expect,把控制權(quán)交給控制臺(tái)纪吮,變回手工操作
③
[root@localhost ~]# expect ssh.exp
spawn ssh root@192.168.24.169
root@192.168.24.169's password:
Last login: Sun Apr 12 07:47:56 2020 from 192.168.24.169
[root@localhost ~]# touch /root/xuegod1011.txt
[root@localhost ~]# ls /etc > /root/xuegod1011.txt
[root@localhost ~]# mkdir /tmp/xuegod1011
mkdir: cannot create directory ‘/tmp/xuegod1011’: File exists
[root@localhost ~]# exit
logout
Connection to 192.168.24.169 closed.
④
例2:對(duì)服務(wù)器批量管理(了解一下)
[root@xuegod63 ~]# cat ip_pass.txt????#這里寫上要執(zhí)行的IP地址和root用戶密碼
192.168.1.63 ?123456
192.168.1.63 ?123456
192.168.1.63 ?123456
[root@xuegod63 ~]# cat ssh2.exp???#編寫要執(zhí)行的操作
#!/usr/bin/expect
?
set ipaddr [lindex $argv 0]
set passwd [lindex $argv 1]
set timeout 30
spawn ssh root@$ipaddr
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "$passwd\r" }
}
?
expect "#"
send "touch /root/xuegod1011.txt\r"
send "ls /etc > /root/xuegod1011.txt\r"
send "mkdir /tmp/xuegod1011\r"
send "exit\r"
send? eof?
3)cat login.sh ???#開始執(zhí)行
#!/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/ssh.exp $ip $pass
done
4) 開始執(zhí)行
bash?? login.sh?
特別字符描述
$匹配輸入字符串的結(jié)尾位置俩檬。要匹配 $ 字符本身,請(qǐng)使用 \$
( )標(biāo)記一個(gè)子表達(dá)式的開始和結(jié)束位置碾盟。要匹配這些字符棚辽,請(qǐng)使用 \( 和 \)
*匹配前面的子表達(dá)式零次或多次。要匹配 * 字符巷疼,請(qǐng)使用 \*
+匹配前面的子表達(dá)式一次或多次晚胡。要匹配 + 字符灵奖,請(qǐng)使用 \+
.匹配除換行符 \n 之外的任何單字符。要匹配 . 估盘,請(qǐng)使用 \.
[標(biāo)記一個(gè)中括號(hào)表達(dá)式的開始瓷患。要匹配 [,請(qǐng)使用 \[
?匹配前面的子表達(dá)式零次或一次遣妥,或指明一個(gè)非貪婪限定符擅编。要匹配 ? 字符,請(qǐng)使用 \?
\將下一個(gè)字符標(biāo)記為或特殊字符箫踩、或原義字符爱态、或向后引用、或八進(jìn)制轉(zhuǎn)義符境钟。例如锦担, 'n' 匹配字符 'n'。'\n' 匹配換行符慨削。序列 '\\' 匹配 "\"洞渔,而 '\(' 則匹配 "("
^匹配輸入字符串的開始位置,除非在方括號(hào)表達(dá)式中使用缚态,此時(shí)它表示不接受該字符集合磁椒。要匹配 ^ 字符本身,請(qǐng)使用 \^
{標(biāo)記限定符表達(dá)式的開始玫芦。要匹配 {浆熔,請(qǐng)使用 \{
|指明兩項(xiàng)之間的一個(gè)選擇。要匹配 |桥帆,請(qǐng)使用 \| ??如: ?Y | y
定位符
^匹配輸入字符串開始的位置
$匹配輸入字符串結(jié)尾的位置
非打印字符
\n匹配一個(gè)換行符
\r匹配一個(gè)回車符
\t匹配一個(gè)制表符
找出下列中以# 號(hào)或者$? 開頭的多少行
①grep "^$ \|#" /etc/ssh/sshd_config
②[root@localhost ~]# grep -v "^$\|^#" /etc/ssh/sshd_config??? #? 取反?? 使用基礎(chǔ)正則表達(dá)式
③[root@localhost ~]# grep -E -v "^$\|^#" /etc/ssh/sshd_config?? 擴(kuò)展表達(dá)式
4)[root@localhost ~]# egrep? -v "^$\|^#" /etc/ssh/sshd_config??? 擴(kuò)展正則表達(dá)式
例3?? :? [root@localhost ~]# grep .ot /etc/passwd???? 查找passwd? 文件包括.ot? 的字符
root:x:0:0:root:/root:/bin/bash
23.3?? sed? 流編譯器
sed? 編譯器是一行一行處理文件的医增,正在處理的內(nèi)容放在模式空間內(nèi),處理完成后安裝選項(xiàng)的規(guī)定進(jìn)行輸出或文件的修改
23.3 ?sed流編輯器
23.3.1 ?sed ?strem editor 流編輯器
sed編輯器是一行一行的處理文件內(nèi)容的环葵。正在處理的內(nèi)容存放在模式空間(緩沖區(qū))內(nèi)调窍,處理完成后按照選項(xiàng)的規(guī)定進(jìn)行輸出或文件的修改。
接著處理下一行张遭,這樣不斷重復(fù),直到文件末尾地梨。文件內(nèi)容并沒有改變菊卷,除非你使用重定向存儲(chǔ)輸出。Sed主要用來自動(dòng)編輯一個(gè)或多個(gè)文件宝剖;簡化對(duì)文件的反復(fù)操作洁闰;
sed也是支持正則表達(dá)式的,如果要使用擴(kuò)展正則加參數(shù)-r
sed的執(zhí)行過程:
[if !supportLists]1万细、?[endif]一次讀取一行數(shù)據(jù)
[if !supportLists]2扑眉、?[endif]根據(jù)我們提供的規(guī)則來匹配相關(guān)的數(shù)據(jù),比如查找root。
[if !supportLists]3腰素、?[endif]按照命令修改數(shù)據(jù)流中的數(shù)據(jù)聘裁,比如替換
[if !supportLists]4、?[endif]將結(jié)果進(jìn)行輸出
[if !supportLists]5弓千、?[endif]重復(fù)上面四步
23.3.2? 如何使用?
語法格式:sed?? 選項(xiàng)??? 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/aplle/dog/' a.txt
this is dog
[root@localhost ~]# cat a.txt
this is aplle
23.3.3?? sed? 選項(xiàng)? | 參數(shù)
options??
-a?? 在當(dāng)前行下面插入文件
-n?? 賭氣下一行輸入行? 衡便,用下要給命令處理新的行而不是用一個(gè)命令
-e?? 執(zhí)行多個(gè)sed? 指令
-i?? 編輯文件內(nèi)容
?-i.bak?? 編輯的同時(shí)參加。bak?? 的備份
-r?? 使用擴(kuò)展的正則表達(dá)式
命令:? 重點(diǎn)
i?? 在當(dāng)前上面插入文件
c? 把選定的行為改為新的指標(biāo)的文本
p? 打印
d?? 刪除
r/R?? 讀取文件/? 一行
w?? 另存
s? 查找
y? 代替
h?? 拷貝模板的內(nèi)容到內(nèi)存中的緩沖區(qū)
H 追加模板庫的內(nèi)容到內(nèi)存中的緩沖區(qū)
g?? 獲得內(nèi)存緩沖區(qū)的內(nèi)容洋访,并代替當(dāng)前模板庫的文本
G? 獲得內(nèi)存緩沖區(qū)的內(nèi)容镣陕,并追加到當(dāng)前模板塊文本的后面
D?? 刪除\n 之前的內(nèi)容
p?? 打印\n??? 之前的內(nèi)容
例1? :s?? 只替換第一個(gè)匹配到的字符,將password中的root? 用戶換成? xuegod?
[root@localhost ~]# sed 's/root/xuegod/' /etc/passwd???? 發(fā)現(xiàn)只替換了第一個(gè)匹配的root? 姻政,后面的沒有替換
全面替換g??
例2 ? [root@localhost ~]# sed 's/root/xuegod/g' /etc/passwd??? 全面替換???
xuegod:x:0:0:xuegod:/xuegod:/bin/bash??? #? 全部替換了
例子2?? 將sed? 中默認(rèn)的/? 定界符改成#號(hào)??
[root@localhost ~]# sed 's#/bin/bash#/sbin/nologin#' /etc/passwd | more
[root@localhost ~]# sed 's/root/xuegod/g' /etc/passwd |more
daemon:x:2:2:daemon:/sbin:/sbin/nologin
sed 's/root/xuegod/g' /etc/passwd | more
以 /? 來做定界符
[root@localhost ~]# sed 's/\/bin\/bash/\/sbin\/nologin/' /etc/passwd | more
(2)? 按行查找代替
寫法如下
用數(shù)字表示行范圍呆抑,$? 表示行尾
用文本模式配置來過濾
例1? 單行代替,將第2行中bin?? 替換成xuegod?
[root@localhost ~]# sed '2s/bin/xuegod/' /etc/passwd | more
root:x:0:0:root:/root:/bin/bash
xuegod:x:1:1:bin:/bin:/sbin/nologin?? 可以看到替換了
[root@localhost ~]# sed '2,$s/bin/xuegod/' /etc/passwd | more? 第二行到?? 最后
都替換為xuegod
(3) 刪除第2行到第4行??
[root@localhost ~]# sed '2,4d' /etc/hosts
127.0.0.1? localhost localhost.localdomain localhost4 localhost4.localdomain4
[root@localhost ~]# sed '/192.168/d' /etc/hosts??? 將192.168? 的行刪除
127.0.0.1? localhost localhost.localdomain localhost4 localhost4.localdomain4
::1? ? ? ? localhost localhost.localdomain localhost6 localhost6.localdomain6
(4)? 添加行
命令i? (insert)?? 插入汁展,在當(dāng)前行前面加入一行鹊碍,i\?
命令?? a? append?? 附加,在當(dāng)前行后面添加一行? a\
[root@localhost ~]# echo "hello world" | sed 'i\xuegod'
xuegod
hello world
[root@localhost ~]# echo "hello world" | sed 'a\xuegod'
hello world
xuegod
[root@localhost ~]# sed '$a\192.3123 xue.cn' /etc/hosts??? 在最后一行追加??
127.0.0.1? localhost localhost.localdomain localhost4 localhost4.localdomain4
::1? ? ? ? localhost localhost.localdomain localhost6 localhost6.localdomain6
192.3123 xue.cn
例4? 文件在第二行之后開始追加
[root@localhost ~]# sed '2a\192.3123 xue.cn' /etc/hosts?? 在?? 第二行追加
127.0.0.1? localhost localhost.localdomain localhost4 localhost4.localdomain4
::1? ? ? ? localhost localhost.localdomain localhost6 localhost6.localdomain6
192.3123 xue.cn
例5 ? [root@localhost ~]# sed '2,4a\192.3123 xue.cn' /etc/hosts??? 在第二行和第四行之間都追加
127.0.0.1? localhost localhost.localdomain localhost4 localhost4.localdomain4
::1? ? ? ? localhost localhost.localdomain localhost6 localhost6.localdomain6
192.3123 xue.cn
(5)? c\? 修改?? change??
[root@localhost ~]# sed '4c\19234.1 192.3123.cn' /etc/hosts
127.0.0.1? localhost localhost.localdomain localhost4 localhost4.localdomain4
::1? ? ? ? localhost localhost.localdomain localhost6 localhost6.localdomain6
例2?? 將第二行到最后全部修改成192.168.65.cn?? /etc/hosts??
[root@localhost ~]# sed '2,$c\192.168.1.65 xuegod65.cn' /etc/hosts
127.0.0.1? localhost localhost.localdomain localhost4 localhost4.localdomain4
192.168.1.65 xuegod65.cn
例3??? 將包含?? 192.168.1.65? 行的內(nèi)容修改成?? 192.168.1.64?
[root@localhost ~]# sed '/192.168.1.65/c\192.168.1.64' /etc/hosts
127.0.0.1? localhost localhost.localdomain localhost4 localhost4.localdomain4
::1? ? ? ? localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.64
(6)?? 打印善镰,直接輸入文件中的內(nèi)容?
例1? 輸出 第2行的內(nèi)容?
[root@localhost ~]# sed -n '2p' /etc/hosts
::1? ? ? ? localhost localhost.localdomain localhost6 localhost6.localdomain6
(7)? 將修改過的文件保存到另一個(gè)文件中
例2? 將pass外的中的包含root字樣的行保存到c.txt?? 中
[root@localhost ~]# sed -n '/root/w c.txt' /etc/passwd
[root@localhost ~]# vim c.txt
(8)? -i?? 對(duì)源文件修改妹萨,保存? (必須會(huì))
[root@localhost opt]# sed -i 's/root/xuegod/' /etc/passwd
修改IP地址并保存?
[root@localhost opt]# sed -i 's/IPADDR=192.168.0.151/IPADDR=192.168.0.67/' /etc/sysconfig/network-scripts/ifcfg-ens33
23.4?? cut命令??
cut? 命令用來顯示指定部分,輸出文件中的指定字段
說明:該命令有良項(xiàng)功能炫欺,其一是用來顯示文件的內(nèi)容乎完,它依次讀取由參數(shù)file所指的文件,將他們的內(nèi)容輸出到標(biāo)準(zhǔn)輸出上品洛,其二是連接兩個(gè)或多個(gè)文件上树姨,如cut? f2? >f3?? 將文件f1? 和fn?? 所指明的內(nèi)容合并起來,然后通過輸出重定向符 ">"?? 的作用桥状,將他們放入文件f3?? 中
語法:cut?? 選項(xiàng)? 參數(shù)
選項(xiàng)
-b? 僅顯示行中指定范圍的內(nèi)容
-c?? 僅顯示行中指定范圍的字符
-d?? 指定字段的分隔符帽揪,默認(rèn)的字段分隔符為?? “TAB”
-f? 顯示指定字段的內(nèi)容
例1? :? 輸出系統(tǒng)中所有用戶名
使用-f?? 選項(xiàng)提取指定字段,使用-d?? 選項(xiàng)字符分隔符? 這里以“:”?? 冒號(hào)做分割
[root@localhost ~]# cut -f1 -d ":" /etc/passwd?? 指定第一列? -d?? 以什么為分隔符? “:”
23.4.2?? cut? 命令可以將一串字符作為列來顯示辅斟,字符字段的記發(fā)
N-?? :從第N? 個(gè)字符转晰,字符,字段到結(jié)尾
N-M?? :? 從第N個(gè)字節(jié)士飒,字符查邢,字段到第M 個(gè)(包括M在內(nèi))字節(jié),字符酵幕,字段
-M?? :? 從第1個(gè)字符扰藕,字節(jié),地段到第M 個(gè)? 包括M在內(nèi)? 字節(jié)芳撒,字符邓深,字段
上面是記發(fā)??
-b?? 表示字節(jié)
-c?? 表示字符
-d?? 指定字段的分隔符
-f?? 表示定義字段
示例?? [root@localhost ~]# cut -c1-3 /etc/passwd? 打印三個(gè)字符???
[root@localhost ~]# cut -c-4 /etc/passwd
23.5?? 實(shí)戰(zhàn)-bash? 腳本語法檢查和查看詳細(xì)的執(zhí)行過程
檢查語法是否有錯(cuò)
bash -v?? test.sh?????? #?? 查看bash? 是否存在語法錯(cuò)誤
bash? -x?? test.bash?? #?? 查看bash?? 詳細(xì)的執(zhí)行過程
# Script to show debug of shell
tot=`expr $1 + $2`
expr??? 語法錯(cuò)誤未桥,??? 錯(cuò)誤在沒有寫參數(shù)?? 運(yùn)行時(shí)沒有給參數(shù)
secho $tot? ? #? 這里是故意寫錯(cuò)? 沒有找到哦啊命令
~? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
過程
[root@localhost ~]# bash -x a.sh 2 3?? 相差詳細(xì)過程
++ expr 2 + 3
+ tot=5
+ expr 2 + 3
5
+ echo 5
5