相互作用のないシェルプログラミング(ドキュメントと期待)

1つ、ヒアドキュメントは相互作用がありません

(I.概要

I / Oリダイレクトを使用して、ftp、cat、readコマンドなどの対話型プログラムまたはコマンドにコマンドのリストを提供します。標準入力の代わりになります。スクリプト開発者は、一時ファイルを使用して入力情報を作成するのではなく、その場で直接「ファイル」を生成し、それを「コマンド」の標準入力として使用できます。ヒアドキュメントは、非対話型のプログラムやコマンドでも使用できます。
1.文法形式:

命令 <<标记
...
内容    #标记直接是传入内容
...
标记

予防:

  • マークには任意の有効な文字(通常はEOF)を使用できます
  • 終了マークは、前に文字を付けずに一番上のグリッドに書き込む必要があります
  • 終了タグの後に文字(スペースを含む)を含めることはできません
  • 開始タグの前後のスペースは省略されます
    ここに画像の説明を挿入
    == 1。インタラクションフリーモードは、行数の統計を実現し、カウントするコンテンツをタグ「EOF」の間に配置し、コンテンツを直接wc-lに渡します。統計の場合==
wc -l <<EOF
>Line1
>Line2
>EOF

ここに画像の説明を挿入

==2。入力を受け取り、readコマンドで出力します。入力値は、変数a ==の値として、2つのEOFタグの間の部分です。

read a <<EOF
>123
>EOF
echo $a

ここに画像の説明を挿入
ここに画像の説明を挿入

3.passwdを介してユーザーのパスワードを設定します

passwd list <<EOF
>abc123123            
>abc123123
EOF

変数置換をサポート
== 4.ファイルを書き込むとき、変数は最初に実際の値に置き換えられ、次にcatコマンドと組み合わされて書き込みが完了します==

#/bin/bash
file="EOFtest.txt"
i=home
cat>$file <<EOF
I am going $i
EOF

cat EOFtest.txt 

ここに画像の説明を挿入

5.値全体を変数に割り当ててから、echoコマンドを使用して変数値を出力します。

#/bin/bash
var="Great I am going school!"
i=school
mytest=$(cat << EOF
This is `date +%F`
I am going $i
EOF
)
echo $mytest

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

6.変数置換の機能をオフにし、変更や置換を行わずに、文字の元の外観に従って出力します。

#/bin/bash
var="Great I am going school!"
i=school
mytest=$(cat << 'EOF'  #也可以使用单引号''
This is `date +%F`
I am going $i
$var
EOF
)
echo "$mytest"

ここに画像の説明を挿入
ここに画像の説明を挿入
== 7。各行の前のTAB文字を削除します==

#/bin/bash
var="Great I am going school!"
i=school
mytest=$(cat <<-EOF             #在标记前加“-”,即可抑制各行tab字符
        This is `date +%F`
                I am going $i
                        $var
EOF
)
echo "$mytest"

ここに画像の説明を挿入
ここに画像の説明を挿入
8.複数行コメントBashのデフォルトコメントは「#」です。このコメントメソッドは単一行コメントのみをサポートします。ヒアドキュメントの導入により、複数行コメントの問題が解決されます。「:」は、何もしない空のコマンドを表します。ミドルマーク領域の内容は実行されず、bashによって無視されるため、バッチコメントの効果を実現できます。

#/bin/bash
var="Great I am going school!"
i=school
:<<-EOF   #多行注释,":"开头的Here Document 标记内容不会被执行
        This is `date +%F`
                I am going $i
                        $var
EOF
echo "$mytest"

ここに画像の説明を挿入

二、期待する

tcl言語に基づいて構築されたツールは、シェルスクリプトのインタラクティブな問題を解決するための自動制御とテストによく使用されます。

rpm -q expect
rpm -q tcl
yum -y install expect

(1)基本コマンド:

1.スクリプトインタプリタ

このファイルは、どのシェルが使用されているかを示すために、expectスクリプトで最初に導入されます

#!/usr/bin/expect

2.スポーン

スポーンの後には通常、Linux実行コマンドが続きます。これは、セッションを開き、プロセスを開始し、後続の対話情報を追跡することを意味します。
例:spawn passwd root

3.期待する

最後の出力結果に指定された文字列が含まれているかどうかを判断します(ある場合はすぐに返します。そうでない場合はタイムアウトを待ってから戻り
ます。spawnによって開始されたプロセスの出力のみをキャプチャできます。
コマンドの実行後に出力を受け取るために使用されますそして、期待に応えます文字列照合

4.ユーザーの入力をシミュレートするために文字列を送信します。このコマンドは、自動的に入力して改行することはできません。通常、\ r(キャリッジリターン)または\ nを追加します。

例:
方法1

expect "密码" {
    
    send "abc123\r"}  #同一行send部分要有{}

方法2

expect "密码" 
send "abc123\r"       #换行send部分不需要有{}

方法3
複数のブランチをサポートすることを期待する

expect     #只要匹配了其中一个情况,执行相应的send语句后退出该expect语句
{
    
    
"密码1" {
    
    send "abc123\r"}
"密码2" {
    
    send "123456\r"}
"密码3" {
    
    send "123123\r"}
}

5.ターミネーター

1.eofを期待する

インタラクションの終了を示し、実行が終了するのを待って、spawnに対応する元のユーザーに戻ります。たとえば
、rootユーザーに切り替えると、expectスクリプトはデフォルトで10秒間待機します。コマンドが実行されると、デフォルトは10秒間そのままになり、その後自動的に元のユーザーに戻ります。

2.対話する

実行が完了すると、対話状態が維持され、制御がコンソールに移されます。元の端末に戻るのではなく、ターゲット端末に留まります。この時点で、手動で操作できます。対話後のコマンド対話後に終了を追加するなど、機能しません。rootユーザーを終了しません。また、インタラクションがない場合は、リモート端末にとどまるのではなく、ログインが完了した後にログアウトします。
インタラクションを使用すると、ターミナルに残り、元の端末に戻りません。たとえば、ルートに切り替えた場合ユーザーの場合、常にrootユーザー状態になります。たとえば、別のサーバーへのsshサーバーは常にターゲットサーバーターミナルにあり、元のサーバーに戻ることはありません。
注:eofを期待し、対話できるのは1つだけです

6.セット

期待のデフォルトのタイムアウト時間は10秒です。セッションタイムアウト時間はsetコマンドで設定できます。タイムアウト時間が制限されていない場合は、-1に設定する必要があります。
例:set timeout 30

7.exp_continue

exp_continueは、特定の期待判断項目に追加されるため、項目が一致した後も、期待判断文の他の項目と一致し続けることができます。exp_continueは、制御ステートメントのcontinueステートメントに似ています。期待値が命令を下向きに実行し続けることが許可されていることを示します。
次に例を示します。次の例では、インタラクティブ出力にyes / noまたは* asswordがあるかどうかを判別します。yes / noに一致する場合は、yesを出力し、判定を再実行します。* passwordに一致する場合は、abc123を出力し、expectステートメントを終了します。

expect {
    
    
    "(yes/no)" {
    
    send "yes\r"; exp_continue;}
    "*password" {
    
    set timeout 300; send "abc123\r";}
}

注:exp_continueを使用する場合、パスワードを入力した後にプロセスを終了するためにpasswdなどのコマンドを追跡する場合は、expect {}の外にexpecteofを追加しないでください。
これは、spawnプロセスが終了した後、デフォルトでeofをexpectに送信するためです。その後、eofが実行されることを期待します。エラーを報告します。

8.send_user

send_userは、echoと同等のechoコマンドを意味します

9.パラメータを受信します

expectスクリプトは、bashコマンドラインから渡されたパラメーターを受け入れ、[lindex $ argvn]を使用して取得できます。その中で、nは0から始まり、それぞれ1番目、2番目、3番目のパラメーターを表します。
例:

set hostname [lindex $argv 0]    相当于 hostname=$1 #在内嵌时使用hostname=$1
set password [lindex $argv 1]  相当于 password=$2

(2)関連する実装例

1.直接実行することを期待します。スクリプトを実行するには、expectスクリプトを使用する必要があります。

実行時には、「。/」のみを使用して実行でき、setのみを使用してパラメーターを渡すことができます。
suスイッチユーザー

#!/usr/bin/expect   #一定要注释解释器  使用内嵌的#!/bin/bash
set username [lindex $argv 0]    
set password [lindex $argv 1]
#开始追踪命令
spawn su $username
#免交互执行,捕捉信息并匹配
expect "密码"
send "$password\r"
expect "*]#"
send_user "ok"   #send_user表示回显命令不被解释器解释
#把控制权交给控制台
interact
#expect eof

ここに画像の説明を挿入

ここに画像の説明を挿入
ここに画像の説明を挿入

2.組み込み実行モード、expectプロセスをシェルに統合します。これは実行と処理に便利です。

ユーザーを作成し、パスワードを設定します

#!/bin/bash
user=$1
password=$2
#非交互命令放在expect外面
useradd $user
#开始免交换执行
/usr/bin/expect <<-EOF
#expect开始标志
spawn passwd $user
#开启-一个进程跟踪passwd命令,expect只能捕捉该进程信息
expect "新的*"
send "${password}\r"
expect "重新*"
send "${password}\r"
expect eof
EOF

ここに画像の説明を挿入
ここに画像の説明を挿入

3.ssh自動ログインを実現します

直接実行モード

#!/usr/bin/expect   #注意与内嵌模式的区别
set host [lindex $argv 0]
set passwd [lindex $argv 1]
spawn ssh $host
expect {
    
    
"Connection refused" exit     #连接失败情况,比如对方ssh服务关闭
"No route to host" exit       #无法连接的情况
"(yes/no)" {
    
    send "yes\r"; exp_continue}   #匹配成立输入yes
"*password:" {
    
    send "${passwd}\r"}        #条件成立输入密码
}
interact

ここに画像の説明を挿入
ここに画像の説明を挿入
埋め込み

#!/bin/bash
username=$1
passwd=$2
/usr/bin/expect<<-EOF
spawn ssh $username
expect {
    
    
"Connection refused" exit
"No route to host" exit
"(yes/no)" {
    
    send "yes\r";exp_contiune}
"password:" {
    
    send "$passwd\r"}
}
expect eof
EOF

ここに画像の説明を挿入
ここに画像の説明を挿入

5.相互作用なしでディスクを作成します

#!/bin/bash
disk=$1
/usr/bin/expect <<-EOF
spawn fdisk $disk
expect "命令" {
    
    send "n\r"}
expect "Select" {
    
    send "\r"}
expect "分区" {
    
    send "\r"}
expect "起始" {
    
    send "\r"}
expect "Last" {
    
    send "\r"}
expect "命令(输入 m 获取帮助):" {
    
    send "w\r"}
expect eof
EOF
partprobe $disk
mkfs.xfs $disk -f &> /dev/null
if [ $? -eq 0 ]
then
echo "finsh"
mount $disk /mnt
else
echo "fail"
fi

おすすめ

転載: blog.csdn.net/weixin_53567573/article/details/114897483