相互作用のないシェルプログラミング
1つ、ヒアドキュメントの無料インタラクションの概念
I / Oリダイレクトを使用して、対話型プログラムまたはコマンドにコマンドリストを提供します。たとえば、ftp、cat、またはreadコマンド
は標準入力の代わりになります。これは、スクリプト開発者が一時ファイルを使用して入力情報を作成するのではなく、「ファイル」を直接生成して「コマンド」の標準入力として使用するのに役立ちます。ヒアドキュメントは、非対話型のプログラムやコマンドでも使用できます。
1.構造
语法格式:
命令 <<标记 #标记这里不能有空格
...
内容 #标记直接是传入内容
...
标记 #标记这里不能有空格
注意が必要な事項:
マークには任意の有効な文字(通常はEOF)を使用できます。
終了マークは上部の
ボックスに入力する必要があり
、終了マークの前に文字を含めることはできません。終了マーク(スペースを含む)の後に文字を含めることはできません。スペース開始マークの前後は省略されます。
ここでのEOFは、最初のEOFが開始を示し、最後のEOFが終了を示すマークにすぎません。EOFは通常、マークを示すために使用されます
マークの内容をdd.txtファイルに渡すと、もう一度書き込むと、元の内容がすべて上書きされていることがわかります。
2. EOFの例:
1.行数の統計を実現し、カウントするコンテンツをタグ「EOF」の間に配置し、統計のためにコンテンツをwc -lに直接渡す、インタラクションのない方法。
wc -l <<EOF
>Line1
>Line2
>EOF
2.入力を受け取り、読み取りコマンドを使用して出力します。入力値は、変数iの値としての2つのEOFタグ間の部分です。
read i <<EOF
> good night #将good night 赋值给i
> rain drop #再赋值一个发现输出时只能显示一个
> EOF
3.passwdを介してユーザーのパスワードを設定します
passwd list <<EOF
>123
>123
EOF
4.変数置換をサポートします
ファイルを書き込むとき、最初に変数を実際の値に置き換え、次にcatコマンドで書き込みを完了します。
#!/bin/bash
file="ss.txt"
i="play"
cat > $file <<EOF
I want to $i
EOF
ss.txtファイルが自動的に作成されて書き込まれていることがわかります
5.変数全体に値を割り当ててから、echoコマンドを使用して変数の値を出力します。
#!/bin/bash
var="hello! I want to sleep"
myvar=$(cat <<EOF
6666
Today is a good day.
$var
EOF
)
echo $myvar
実行結果
ここに空白行がないことがわかります、
実行結果
6.変数置換機能をオフにし、文字を変更または置換せずにそのまま出力します。
#!/bin/bash
var="hello! I want to sleep"
myvar=$(cat <<'EOF'
6666
Today is a good day.
$var
EOF
)
echo "$myvar"
7.各行の前のTAB文字を削除します
#!/bin/bash
var="hello! I want to sleep"
myvar=$(cat <<-'EOF'
6666
Today is a good day.
$var
EOF
)
echo "$myvar"
8.複数行コメント
Bashのデフォルトのコメントは「#」です。このコメントメソッドは単一行コメントのみをサポートします。ヒアドキュメントの導入により、複数行コメントの問題が解決されます。
「:」は、何もしない空のコマンドを表します。ミドルマーク領域の内容は実行されず、bashによって無視されるため、バッチコメントの効果を得ることができます。
#!/bin/bash
var="hello! I want to sleep"
: <<-'EOF'
6666
Today is a good day.
$var
EOF
echo "$myvar"
echo "666"
2、相互作用を期待しない
期待する
- これはtcl言語に基づくツールであり、シェルスクリプトのインタラクティブな問題を解決するための自動制御とテストによく使用されます。
1.インストール
rpm -q expect
rpm -q tcl
yum install -y expect
2.基本的なコマンド
(1)スクリプトインタプリタ
- このファイルは、どのシェルを使用するかを示すために、expectスクリプトで最初に導入されます
#!/usr/bin/expect
(2)スポーン
- スポーンの後には通常、セッションを開き、プロセスを開始し、後続の対話情報を追跡するコマンドが続きます。
例:spawn passwd root
(3)期待する
- 最後の出力結果に指定された文字列が含まれているかどうかを判断します。含まれている場合はすぐに戻ります。含まれていない場合は、タイムアウト期間を待ってから戻ります。
- spawnによって開始されたプロセスの出力のみをキャプチャできます。
- コマンドの実行後に出力を受け取り、期待される文字列と一致させるために使用されます
(4)送信
- ユーザーの入力をシミュレートするために文字列をプロセスに送信します。このコマンドは自動的に入力して改行することはできません。通常は\ r(キャリッジリターン)または\ nを追加します。
例如:发送密码
方式一:
expect "密码" {
send "123123\r"} #同一行send部分要有{}
方式二:
expect "密码"
send "123123\r" #换行send部分不需要有{}
方式三:
expect #只要匹配了其中一个情况,执行相应的send语句后退出该expect语句
{
"密码1" {
send "123123\r"}
"密码2" {
send "123133\r"}
"密码3" {
send "abc123\r"}
}
(5)ターミネーターはeofを期待し、相互作用します
eofを期待する:
- インタラクションの終了を示し、実行が終了するのを待って、元のユーザーに戻り、スポーンに対応します
- たとえば、rootユーザーに切り替えると、expectスクリプトはデフォルトで10秒間待機します。コマンドを実行すると、デフォルトで10秒間待機した後、自動的に元のユーザーに戻ります。
expect eof
相互作用する:
-
実行が完了すると、対話状態が維持され、制御がコンソールに移されます。元の端末に戻るのではなく、ターゲット端末に留まります。この時点で、手動で操作できます。対話後のコマンド対話後に終了を追加するなど、機能しません。rootユーザーを終了しません。対話がない場合は、リモート端末にとどまるのではなく、ログイン後にログアウトします。
-
インタラクションを使用すると、ターミナルに残り、元のターミナルに戻りません。たとえば、rootユーザーに切り替えると、常にrootユーザーの状態になります。たとえば、別のサーバーにsshを実行すると、常に元のサーバーに切り替えるのではなく、ターゲットサーバー端末にいる。
interact .
(6)セット
- 期待のデフォルトのタイムアウト期間は10秒です。セッションのタイムアウト期間は、setコマンドを使用して設定できます。タイムアウト期間が制限されていない場合は、-1に設定する必要があります。
(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{}外不要再加上expect eof
#因为spawn进程结束后会向expect发送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
3、使用例:
1.期待する
- 以前の方法で実行を実行することはできません。expectは直接実行されます。スクリプトを実行するには、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 当执行完命令后,默认停留10s后,自动切回了原用户
例:無料のインタラクティブリンクssh
#!/usr/bin/expect
set timeout 3 #超时时间为3秒,不设置得话 默认为10秒
set hostname [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh $hostname
expect {
"(yes/no)" {
send "yes\r"; exp_continue }
"*password:" {
send "${password}\r"}
}
expect eof #这里执行后跳回
#interact 这里是保持执行后得控制台位置,不跳回。
2.組み込み実行モード、実行と処理を容易にするために、expectプロセスをシェルに統合します
例:ユーザーを作成してパスワードを設定する
#!/bin/bash
usrname=$1
passwd=$2
useradd $usrname #非交互得命令放在外面得脚本里
/usr/bin/expect <<EOF #嵌入expect
spawn passwd $usrname #开启spawn跟踪passwd命令
#匹配字符,并且发送字符串
expect "新的*" {
send "${passwd}\r"}
expect "重新*" {
send "${passwd}\r"}
expect eof #结束符
EOF
awkクエリキーワードの後、私が作成したユーザーの数を確認できます。
例:埋め込まれたインタラクティブなsshログイン
#!/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
実行後に自動的にジャンプバック
例:相互作用なしでディスクを作成する
#!/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
mkfs.xfs $disk -f &> /dev/null
if [ $? -eq 0 ]
then
echo -e " 磁盘格式化完成 "
mkdir $disk.1
mount $disk $disk.1
df -h
else
echo "格式化shibai"
fi