記事ディレクトリ
1.ここでドキュメントは相互作用がありません
1。概要
- I / Oリダイレクトを使用して、ftp、cat、readコマンドなどのインタラクティブなプログラムまたはコマンドにコマンドのリストを提供します
- これは標準入力の代わりになり、スクリプト開発者が一時ファイルを使用して入力情報を作成するのではなく、その場で直接「ファイル」を生成し、それを「コマンド」の標準入力として使用するのに役立ちます。
- ここで、ドキュメントは非対話型のプログラムやコマンドでも使用できます
2.文法形式
命令 <<标记
...
内容 #标记直接是传入内容
...
标记
3.注意が必要な事項
- マークは任意の正当な文字を使用できます(通常はEOFを使用します)
- 終了マークは、前に文字を付けずに上部グリッドに書き込む必要があります
- 終了タグの後に文字(スペースを含む)を含めることはできません
- 開始タグの前後のスペースは省略されます
4.例
4.1行数の統計を実現するためのインタラクションフリーモード
- カウントするコンテンツをタグ「EOF」の間に入れます
- 統計のためにコンテンツを直接wc-lに渡します
[root@localhost ~]# wc -l <<EOF
> xcf1
> xcf2
> EOF
2
4.2入力を受け取り、読み取りコマンドを使用して印刷します
- 入力値は、2つのEOFタグの間の部分です。
- 変数iに直接値を割り当てます
[root@localhost ~]# read i <<EOF
> hello xcf~
> EOF
[root@localhost ~]# echo $i
hello xcf~
4.3passwdを介してユーザーのパスワードを設定する
[root@localhost ~]# useradd xcf123
[root@localhost ~]# passwd xcf123 << EOF
123123
123123
EOF
更改用户 xcf123 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。
4.4変数置換のサポート
- ファイルを書き込むときに、変数は実際の値に置き換えられます
- 次に、catコマンドを組み合わせて書き込みを完了します
[root@localhost shell]# vim zxc1.sh
#!/bin/bash
file="xcf1.txt"
i="chicken"
cat > $file <<EOF
I'd like some $i
EOF
[root@localhost shell]# . zxc1.sh
[root@localhost shell]# ls
xcf1.txt zxc1.sh
[root@localhost shell]# cat xcf1.txt
I'd like some chicken
4.5変数全体に値を割り当ててから、echoコマンドを使用して変数値を出力します。
[root@localhost shell]# vim zxc2.sh
#!/bin/bash
name="OMG! xucheng come!"
myname=$(cat <<EOF
It's a beautiful day
Today is Sunday
School starts again tomorrow
$name ~
EOF
)
echo $myname
[root@localhost shell]# . zxc2.sh
It's a beautiful day Today is Sunday School starts again tomorrow OMG! xucheng come! ~
4.6変数置換の機能をオフにする
- これにより、文字がそのまま出力されます
- 変更や交換なし
4.7各行の前のTAB文字を削除します
- この使用法で各行のタブ文字を削除できることを知っているので、あまり役に立ちません
4.8複数行のコメント
- Bashのデフォルトのコメントは「#」です。このコメントメソッドは1行のコメントのみをサポートします
- Here Documentの導入により、複数行のコメントの問題が解決されます
- 「:」は何もしない空のコマンドを表します
- ミドルマーク領域の内容は実行されず、bashによって無視されるため、バッチコメントの効果を実現できます。
2、自動化された相互作用を期待する
1。概要
- 期待は無料のプログラミングツール言語であり、人間の介入なしに通信するための自動でインタラクティブなタスクを実現するために一般的に使用されます
- expectはTclプログラミング言語のサポートを必要とします。システムでexpectを実行するには、最初にTclをインストールする必要があります。
yum -y install tcl
yum -y install expect
2.基本的なコマンド
2.1スクリプトインタープリター
- このファイルは、どのシェルが使用されているかを示すために、expectスクリプトで最初に導入されます
#!/usr/bin/expect
2.2スポーン
- スポーンの後には通常、Linux実行コマンドが続きます。これは、セッションを開き、プロセスを開始し、後続の対話情報を追跡することを意味します。
例: spawn passwd root ##跟踪启动更改用户密码的进程
2.3期待する
- 最後の入力結果に指定された文字列が含まれているかどうかを確認します。含まれている場合はすぐに戻ります。含まれていない場合は、タイムアウト期間が戻るのを待ちます
- スポーンによって開始されたプロセスの出力のみをキャプチャできます
- コマンドの実行後に出力を受け取り、期待される文字列と一致させるために使用されます
2.4送信
- プロセスに文字列を送信して、ユーザー入力をシミュレートします
- このコマンドは自動的に入力してラインフィードを入力することはできません。通常は\ r(キャリッジリターン)または\ nを追加します。
- 方法1
expect “密码” {
send “abc123\r”}
##同一行send部分要有{}
- 方法2
expect “密码”
send “$abc123\r”
##换行send部分不需要有{}
- 方法3
expect “支持多个分支
expect {
##只要匹配了其中一个情况,就执行相应的send语句后退出该expect语句
"密码1 {send "abc123\r"}"
"密码2 {send "123123\r"}"
"密码3 {send "123123\r"}"
}
2.5ターミネーター
expect eof
- インタラクションの終了を示し、実行が終了するのを待って、スポーンに対応する元のユーザーに戻ります
- 例:rootユーザーに切り替えると、expectスクリプトはデフォルトで10秒間待機します。コマンドを実行すると、デフォルトで10秒間待機した後、元のユーザーに自動的に戻ります。
interact
- 実行が完了すると、対話状態が維持され、制御がコンソールに移され、ターゲット端末に留まります。このとき、手動操作が可能です。対話後のコマンドは動作しません。 、rootユーザーへの切り替えなど、常にrootユーザーになります
- たとえば、別のサーバーへのsshは、元のサーバーに戻るのではなく、常にターゲットサーバーの端末にあります。
- 注:eofを期待し、対話できるのは1つだけです
2.6セット
- 期待のデフォルトのタイムアウト時間は10秒です。セッションタイムアウト時間はsetコマンドで設定できます。タイムアウト時間が制限されていない場合は、-1に設定する必要があります。
##例:
set timeout 30
2.7 exp_continue
- exp_continueは、特定の期待判断項目に追加されるため、項目が一致した後も、期待判断文の他の項目と一致し続けることができます。
- exp_continueは、制御ステートメントのcontinueステートメントに似ています。つまり、expectは命令を下向きに実行し続けます。
- 次の例では、インタラクティブ出力にyes / noまたは* passwordがあるかどうかを判断します。yes/ noと一致する場合は、yesを出力して判断を再実行します。* asswordと一致する場合は、123123を出力し、expectステートメントを終了します。
expect
"(yes/no)" {
send "yes\r"; exp_ continue; }
"*password" {
set timeout 300; send "123123\r";}
2.8 send_user
- send_ userは、echoと同等のechoコマンドを意味します
2.9受信パラメータ
- expectスクリプトは、bashコマンドラインから渡されたパラメーターを受け入れ、[lindex $ argv n]を使用して取得できます。ここで、nは0から始まり、1番目、2番目、3番目を表します。
- 例:
set hostname [lindex $argv 0]
##相当于hostname=$1
set password [lindex $argv 1]
##相当于password=$2
3.直接実行を期待する
- 例としてSSHを取り上げます。
- $ argv0は位置変数$ 1を表します
- $ argv1は位置変数$ 2を表します
- #!/ usr / bin / expectはExpectバイナリファイルのパスです
[root@localhost shell]# vim zxc11.sh
#!/usr/bin/expect
#设置超时时间
set timeout 20
#开启日志
log_file test.log
#显示信息
log_user 1
#定义变量
set hostname [lindex $argv 0]
set password [lindex $argv 1]
#追踪指令
spawn ssh root@${hostname}
#捕捉提示信息
expect {
"connecting (yes/no)"
{
send "yes\r";exp_continue}
"*password:"
{
send "${password}\r";}
}
#转交控制权
interact
4.埋め込み実行を期待する
- 実行と処理を容易にするために、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
- 例としてSSHを取り上げます。
#!/bin/bash
hostname=$1
password=$2
/usr/bin/expect<<-EOF
spawn ssh root@${hostname}
expect {
"(yes/no)"
{send "yes\r";exp_continue}
"*password"
{send "$password\r"}
}
expect "*]#"
send "exit\r"
expect eof
EOF 'Expect结束标志,EOF前后不能有空格'
5.SSH自動ログインを実現します
[root@localhost shell]# vim zxc12.sh
#!/usr/bin/expect
set timeout 15
set hostname [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh root@${hostname}
expect {
"connection refused" exit
#连接失败情况,比如对方ssh服务关闭
"Name or service not known" exit
#找不到服务器,比如输入的IP地址不正确
"to continue"{
send "yes\r";exp_continue}
"password:"{
send "${password}\r";}
}
interact
#携带interact参数表示登录成功后将控制台交给用户,否则登录完成后将退出
exit
6.対話なしでディスクを作成します
- 最初に仮想マシンのオフ状態のディスクを手動で追加してから、電源をオンにします
- スクリプティング
[root@localhost ~]# vim disk.sh
#!/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 "\033[31m 磁盘格式化完成 \033[0m"
mkdir $disk.1
mount $disk $disk.1
df -h
else
echo "格式化失败,脚本有bug"
fi
- この記事の冒頭に記載されているパッケージがインストールされているかどうかを確認してください
[root@localhost ~]# rpm -q tcl
tcl-8.5.13-8.el7.x86_64
[root@localhost ~]# rpm -q expect
expect-5.45-14.el7_1.x86_64
- スクリプトを実行する
[root@localhost ~]# sh disk.sh /dev/sdb$1
spawn fdisk /dev/sdb
欢迎使用 fdisk (util-linux 2.23.2)。
更改将停留在内存中,直到您决定将更改写入磁盘。
使用写入命令前请三思。
Device does not contain a recognized partition table
使用磁盘标识符 0x1f0887af 创建新的 DOS 磁盘标签。
命令(输入 m 获取帮助):n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p):
Using default response p
分区号 (1-4,默认 1):
起始 扇区 (2048-41943039,默认为 2048):
将使用默认值 2048
Last 扇区, +扇区 or +size{
K,M,G} (2048-41943039,默认为 41943039):
将使用默认值 41943039
分区 1 已设置为 Linux 类型,大小设为 20 GiB
命令(输入 m 获取帮助):w
The partition table has been altered!
Calling ioctl() to re-read partition table.
正在同步磁盘。
Warning: 无法以读写方式打开 /dev/sr0 (只读文件系统)。/dev/sr0 已按照只读方式打开。
磁盘格式化完成
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda2 20G 3.8G 17G 19% /
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 1.9G 9.0M 1.9G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/sr0 4.3G 4.3G 0 100% /mnt
/dev/sda1 6.0G 174M 5.9G 3% /boot
/dev/sda3 10G 37M 10G 1% /home
tmpfs 378M 8.0K 378M 1% /run/user/42
tmpfs 378M 0 378M 0% /run/user/0
/dev/sdb 20G 33M 20G 1% /dev/sdb.1