1.ヒアドキュメントは相互作用がありません
1.関連する概念
- I / Oリダイレクトを使用して、ftp、cat、readコマンドなどの対話型プログラムにコマンドリストを提供します
- 標準入力の代わりになることで、スクリプト開発者は一時ファイルを使用して入力情報を作成するのではなく、「ファイル」を直接生成して「コマンド」の標準入力として使用できます。ヒアドキュメントは、非対話型のプログラムやコマンドでも使用できます。
2.文法形式
命令 <<标记
...
内容 #标记之间是传入内容
...
标记
3.注意が必要な事項
- マークには任意の正当な文字(通常はEOF)を使用できます
- 終了マークは、前に文字を付けずに上部グリッドに書き込む必要があります
- 終了タグの後に文字(スペースを含む)を含めることはできません
- 開始タグの前後のスペースは省略されます
4.例
(1)相互作用なしで行数の統計を実現する
- カウントするコンテンツをタグ「EOF」の間に置き、統計のためにコンテンツをwc-lに直接渡します。
wc -l <<EOF
>Line1
>Line2
>EOF
(2)入力を受け取り、読み取りコマンドを使用して印刷します
- 入力値は、変数iの値としての2つのEOFタグ間の部分です。
read i <<EOF
>Hi
>EOF
echo $i
(3)passwdを介してユーザーのパスワードを設定します
passwd lisi <<EOF
>abc1234 #这两行是输入的密码和确认密码
>abc1234
>EOF
(4)変数置換をサポートする
vim ti.sh
#!/bin/bash
file="ti.txt"
i="lisi"
cat > $file <<EOF
hello $i
EOF
sh ti.sh
cat ti.txt
(5)変数全体に値を割り当てます
#!/bin/bash
var="Great! I am going to school!"
bian=$(cat <<EOF
Today is Monday.
$var
EOF
)
echo $bian
(6)変数置換の機能をオフにします
#!/bin/bash
var="Great! I am going to school!"
bian=$(cat <<'EOF'
Today is Monday.
$var
EOF
)
echo $bian
(6)各行の前のTAB文字を削除します
#!/bin/bash
var="Great! I am going to school!"
bian=$(cat <<-EOF #对标记前加“-”,即可抑制各行首TAB或空格
Today is Monday.
$var
EOF
)
echo "$bian"
(7)複数行コメント
- Bashのデフォルトのコメントは「#」です。このコメントメソッドは単一行コメントのみをサポートします
- ヒアドキュメントの導入により、複数行コメントの問題が解決されます。「:」は、何もしない空のコマンドを表します。ミドルマーク領域の内容は実行されず、bashによって無視されるため、バッチコメントの効果を得ることができます。
#!/bin/bash
var="Great! I am going to school!"
: bian=$(cat <<EOF
Today is Monday.
$var
EOF
)
echo "$bian"
echo "$var"
2、相互作用を期待しない
- シェルスクリプトのインタラクティブな問題を解決するために、自動制御とテストによく使用されるtcl言語に基づいて構築されたツール
- インストールツール
rpm -q expect
rpm -q tcl
yum install -y expect
1.基本的なコマンド
(1)スクリプトインタプリタ
- このファイルは、どのシェルが使用されているかを示すために、expectスクリプトで最初に導入されます。
#!/usr/bin/expect
(2)スポーン
- スポーンの後には通常、セッションを開き、プロセスを開始し、後続の対話情報を追跡するコマンドが続きます。
例:spawn passwd root
(3)期待する
- 指定された文字列が最後の出力結果に含まれているかどうかを判別します。
- はいの場合、すぐに戻ります
- それ以外の場合は、タイムアウト期間を待ってから戻ります。
- spawnによって開始されたプロセスの出力のみをキャプチャできます。
- コマンドの実行後に出力を受け取り、期待される文字列と一致させるために使用されます
(4)送信
- ユーザーの入力をシミュレートするために文字列をプロセスに送信します。このコマンドは自動的に入力して改行することはできません。通常は\ r(キャリッジリターン)または\ nを追加します。
例如:发送密码
方式一:
expect "密码" {
send "123456\r"} #同一行send部分要有{}
方式二:
expect "密码"
send "123456\r" #换行send部分不需要有{}
方式三:
expect #只要匹配了其中一个情况,执行相应的send语句后退出该expect语句
{
"密码1" {
send "123456\r"}
"密码2" {
send "123123\r"}
"密码3" {
send "abc123\r"}
}
(5)ターミネーター
- eofを期待する
- インタラクションの終了を示し、実行が終了するのを待って、スポーンに対応する元のユーザーに戻ります
- たとえば、rootユーザーに切り替えると、expectスクリプトはデフォルトで10秒間待機します。コマンドを実行すると、デフォルトで10秒間待機した後、自動的に元のユーザーに戻ります。
expect eof
- 相互作用する
- 実行が完了すると、対話状態が維持され、制御がコンソールに移されます。元の端末に戻るのではなく、ターゲット端末に留まります。この時点で、手動で操作できます。対話後のコマンド対話後にexitを追加するなど、機能しません。rootユーザーを終了しません。対話がない場合は、リモート端末にとどまるのではなく、ログイン後にログアウトします。
- インタラクションを使用すると、元のターミナルに戻るのではなく、ターミナルに留まります。たとえば、rootユーザーに切り替えると、常にrootユーザーの状態になります。たとえば、別のサーバーにSSHで接続すると、元のサーバーに切り替えるのではなく、常にターゲットサーバーターミナルにいることになります。
interact
注:eofを期待し、対話できるのは1つだけです。
(6)セット
- 期待のデフォルトのタイムアウト期間は10秒です。セッションのタイムアウト期間は、setコマンドを使用して設定できます。タイムアウト期間が制限されていない場合は、-1に設定する必要があります。
例:设置超时时间为30秒
set timeout 30
(7)exp_continue
- exp_continueは、特定の期待判断項目に追加されるため、項目が一致した後も、期待判断文の他の項目と一致し続けることができます。exp_continueは、制御ステートメントのcontinueステートメントに似ています。
- 例:次の例では、対話型出力にyes / noまたは* passwordがあるかどうかを判別します。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を追加しないでください。
スポーンプロセスが終了した後、eofがexpectに送信され、後続のeofの実行でエラーが報告されることを期待する
(8)send_user
- echoと同等のechoコマンドを表します
send_user
(9)受信パラメータ
- expectスクリプトは、bashコマンドラインから渡されたパラメーターを受け入れ、[lindex $ argvn]を使用して取得できます。その中で、nは0から始まり、それぞれ1番目、2番目、3番目のパラメーターを表します。
例:
set hostname [lindex $argv 0] 相当于 hostname=$1
set password [lindex $argv 1] 相当于 password=$2
2.例
(1)直接実行を期待する
- 以前の方法で実行を実行することはできません。スクリプトを実行するには、expectコマンドを使用する必要があります。
- 例:suスイッチユーザー
#!/usr/bin/expect
set timeout 3
set username [lindex $argv 0]
set password [lindex $argv 1]
spawn su $username
expect "密码" {
send "$password\r"}
interact #或者expect eof
(2)埋め込み実行
- 実行と処理を容易にするために、expectプロセスをシェルに統合します
- 例:ユーザーを作成してパスワードを設定する
#!/bin/bash
user=$1
password=$2
useradd $user
/usr/bin/expect <<EOF
spawn passwd $user
expect "新的*" {send "${password}\r"}
expect "重新*" {send "${password}\r"}
expect eof
EOF
(3)ssh自動ログインを実現
- 期待値で直接実行
#!/usr/bin/expect
set timeout 5
set hostname [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh $hostname
expect {
"Connection refused" exit
"Name or service not known" exit
"to continue" {
send "yes\r";exp_continue}
"password:" {
send "$password\r"}
}
interact
exit #interact后的命令不起作用
- 埋め込み
#!/bin/bash
hostname=$1
password=$2
/usr/bin/expect <<EOF
spawn ssh $hostname
expect {
"(yes/no)" {send "yes\r";exp_continue}
"*password" {send "$password\r"}
}
expect "*]#" {send "ifconfig\r"}
expect eof
EOF