当前位置:   article > 正文

shell编程之免交互

shell编程之免交互

Here Document 

        它在 Linux Shell 中使用 I/O 重定向的方式将命令列表提供给交互式程序或命令

        Here Document 是标准输入的一种替代品

        帮助脚本开发不必使用临时文件来构建输入信息,而是直接生成文件并用作命令的标准输入

        示例

  1. [root@bogon ~]# cat > my.cof << xiaojing
  2. > asdfaf
  3. > asdfs
  4. > asdcvd
  5. > asdv
  6. > xiaojing
  7. [root@bogon ~]#

                标记可以使用任意的合法字符

                结尾的标记一定要顶格写,前面不能有任何字符

                结尾的标记后面也不能有任何字符(包括空格)

                开头的标记前后的空格会被省略掉

        什么是免交互

                它通过I/O重定向的方式将命令列表提供给交互式程序或命令,从而避免了用户的手工输入,提高了脚本的自动化程度

                 统计文件内有多少行内容

                        wc -l 命令后面直接跟文件名就可以

                Here Document 格式控制

                        关闭变量替换的功能

  1. passwd lisi << 'eof'
  2. #单引号的作用代表以下特殊字符,失去特殊含义
  3. 123
  4. 123
  5. eof

                            去掉每行之前的 TAB 字符(抑制各行首 TAB 的作用)

  1. [root@localhost ~]# vim here_format_tab.sh
  2. #!/bin/bash cat <<-'EOF'
  3. This is Line 1.
  4. $kgc
  5. EOF
  6. [root@localhost ~]# sh here_format_tab.sh
  7. This is Line 1.
  8. $kgc //输出结果同上一示例
                变量设定

                        标记之间有变量被使用,会先替换变量值

  1. [root@localhost ~]# vim here_var_replace.sh
  2. #!/bin/bash doc_file="2019.txt" i="company"
  3. cat > $doc_file << HERE Take him from home to $i HERE
  4. [root@localhost ~]# chmod +x here_var_replace.sh [root@localhost ~]# ./here_var_replace.sh [root@localhost ~]# cat 2019.txt
  5. Take him from home to company

       expect 概述

                expect

                        可以让一些需要交互的任务自动化地完成

                        进行自动化控制和测试的工具

                        主要解决 shell 脚本中不可交互的问题

                expect 安装

                        1.安装软件

                                yum -y install expect

                        2.编辑ssh连接脚本文件

  1. #!/usr/bin/expect
  2. #设置超时时间
  3. set timeout 60
  4. #连接地址
  5. spawn ssh root@192.168.27.131
  6. expect {
  7. "*(yes/no)*" { send "yes\r"; exp_continue } # 如果出现"yes/no"提示,发送"yes"并继续等待
  8. "*password:*" { send "123456\r" } # 使用更具体的匹配模式
  9. }
  10. #确认登录成功,能匹配到#号就代表成功
  11. expect "*#" {send "ifconfig ens33 \r" }
  12. #退出方式
  13. interact

                                # expect eof :等待执行结束,若没有这一句,可能导致命令还没执行,脚本就结束了
                                # interact : 执行完成后保持交互状态, 把控制权交给控制台,这时可以手动输入信息。 需要注意的是,expect eof 与 interact 只能二选一。

                    脚本    

  1. #!/usr/bin/expect
  2. # expect 将超时时间设置为 60 秒
  3. set timeout 60
  4. # 记录日志文件
  5. log_file test.log
  6. # 开启控制台输出,为0时,控制台不输出
  7. log_user 1
  8. # $argc 表示参数个数
  9. if {$argc<1} {
  10. # send_user相当于shell的echo
  11. send_user "usage: $argv0 <param1><param2> ... "
  12. exit
  13. }
  14. set hostname [lindex $argv 0]
  15. set password [lindex $argv 1]
  16. # spawn 后面通常跟一个命令,表示开启一个会话、启动进程,并跟踪后续交互信息
  17. spawn ssh root@${hostname}
  18. expect {
  19. "(yes/no)"
  20. # 匹配的(yes/no)时自动输入yes,exp_continue 表示允许 expect 继续向下执行指令
  21. {send "yes\r"; exp_continue}
  22. "*password"
  23. {send "$password\r"}
  24. }
  25. expect "*#" {send "ifconfig\r"}
  26. # expect eof :等待执行结束,若没有这一句,可能导致命令还没执行,脚本就结束了
  27. # interact : 执行完成后保持交互状态, 把控制权交给控制台,这时可以手动输入信息。 需要注意的是,expect eof 与 interact 只能二选一。
  28. interact

                        创建用户脚本

  1. #!/bin/bash
  2. user=$1
  3. password=$2
  4. useradd $user
  5. expect << EOF
  6. # 开启一个进程跟踪 passwd 命令,expect 只能捕捉该进程信息
  7. spawn passwd $user
  8. # 匹配输出信息"New password:"
  9. expect "New password:"
  10. # 自动输入密码 ,英文版的可以捕捉,中文版的可能会报错
  11. send "${password}\r"
  12. # 匹配输出信息"Retype new password:"
  13. expect "Retype new password:"
  14. # 自动输入密码
  15. send "${password}\r"
  16. # 等待结束标记
  17. expect eof;
  18. EOF

 课后作业  免交互式等ssh

  1. #!/bin/bash
  2. # 检查是否安装expect命令
  3. check_expect_cmd() {
  4. #查找命令是否存在,返回0存在,否则是不存在
  5. if command -v expect &> /dev/null ;then
  6. return 0
  7. else
  8. return 1
  9. fi
  10. }
  11. #安装expect命令
  12. install_expect() {
  13. #判断操作系统,根据系统不同,执行不同的安装指令
  14. if command -v dnf &> /dev/null ;then
  15. dnf -y install expect
  16. elif command -v yum &> /dev/null ;then
  17. yum -y install expect
  18. elif command -v apt-get &> /dev/null ;then
  19. apt-get -y install expect
  20. else
  21. echo "$(data) ERROR:未知错误,请手动添加"
  22. fi
  23. }
  24. #执行命令
  25. runcmd() {
  26. local hostip=$1
  27. local user=$2
  28. local password=$3
  29. local port=$4
  30. local cmd=$5
  31. expect << EOF
  32. #定义超时时间
  33. set timeout 60
  34. #追踪ssh命令
  35. spawn ssh -p ${port} ${user}@${hostip}
  36. expect {
  37. "(yes/no)"
  38. { send "yes\r";exp_continue}
  39. "*password"
  40. { send "${password}\r"}
  41. }
  42. #匹配密码错误时退出
  43. expect "*please try again*" {
  44. send_user "\nERROR: password error\n"
  45. }
  46. #执行命令
  47. expect -re "(#|\$)" { send "${cmd}\n"}
  48. expect -re "(#|\$)" { send "exit\n"}
  49. #等待结束
  50. expect eof;
  51. EOF
  52. }
  53. if ! check_expect_cmd ;then
  54. install_expect
  55. fi
  56. runcmd "192.168.27.129" "root" "123456" "22" "pwd"


etc/os-release   Linux中都存在这个文件,可以用来过滤操作系统
dnf是yum命令的升级版:
 

  1. [root@bogon ~]# cat host.cfg
  2. [test]
  3. 192.168.27.131 username=root password=123456 port=22
  4. 192.168.27.110 username=root password=123456 port=22
  5. [kgc]
  6. 192.168.27.128 username=root password=123456 port=22
  7. 192.168.27.131 username=root password=123456 port=22

根据文本文件连接

  1. #!/bin/bash
  2. file_name="hosts.cfg"
  3. # 判断配置文件是否存在
  4. check_file() {
  5. local file=$1
  6. if [ ! -f "$file" ];then
  7. echo "$(date) ERROR: ${file} 不存在"
  8. exit 1
  9. fi
  10. }
  11. # 判断组是否存在
  12. check_group() {
  13. local group=$1
  14. grep -w "\[${group}\]" $file_name &> /dev/null
  15. if [ "$?" -eq 0 ];then
  16. return 0
  17. else
  18. exit 1
  19. fi
  20. }
  21. # 检测是否有expect命令
  22. # 返回0表示存在命令,返回1表示不存在命令
  23. check_expect_cmd() {
  24. if command -v expect &> /dev/null ;then
  25. return 0
  26. else
  27. return 1
  28. fi
  29. }
  30. # 安装expect
  31. install_expect() {
  32. if command -v dnf &> /dev/null ;then
  33. dnf -y install expect
  34. elif command -v yum &> /dev/null ;then
  35. yum -y install expect
  36. elif command -v apt-get &> /dev/null ;then
  37. apt-get -y install expect
  38. else
  39. echo "$(date) ERROR: 未知的操作系统,请手动安装expect命令"
  40. fi
  41. }
  42. # 执行命令
  43. runcmd() {
  44. local hostip=$1
  45. local user=$2
  46. local password=$3
  47. local port=$4
  48. local cmd=$5
  49. expect << EOF
  50. # 定义超时时间
  51. set timeout 10
  52. # 追踪ssh命令
  53. spawn ssh -p ${port} ${user}@${hostip}
  54. expect {
  55. "(yes/no)"
  56. { send "yes\r";exp_continue }
  57. "*password"
  58. { send "${password}\r" }
  59. }
  60. # 匹配到密码错误时退出
  61. expect "*please try again*" {
  62. send_user "\nERROR: password error\n"
  63. }
  64. # 执行命令
  65. expect -re "(#|\$)" { send "${cmd}\n" }
  66. expect -re "(#|\$)" { send "exit\n" }
  67. # 等待结束标记
  68. expect eof;
  69. EOF
  70. }
  71. # 获取指定组里面的信息
  72. get_group_info() {
  73. local group_name=$1
  74. local ip
  75. local user
  76. local password
  77. local port
  78. local cmd=$2
  79. local info=$(awk -v group="$group_name" '
  80. $0 ~ "^\\[" group "\\]$" { test=1; next }
  81. $0 ~ "^\\[" { test=0 }
  82. test && /^[^[:space:]]+/{ print $1, $2, $3, $4 }
  83. ' "$file_name")
  84. echo "$info" | while IFS= read -r line;do
  85. # 获取相关信息
  86. ip=$(echo "${line}" | awk '{print $1}')
  87. user=$(echo "${line}" | awk '{print $2}' | awk -F '=' '{print $2}')
  88. password=$(echo "${line}" | awk '{print $3}' | awk -F '=' '{print $2}')
  89. port=$(echo "${line}" | awk '{print $4}' | awk -F '=' '{print $2}')
  90. # 执行命令
  91. runcmd "${ip}" "${user}" "${password}" "${port}" "${cmd}"
  92. done
  93. }
  94. main() {
  95. while getopts "f:g:c:h" opt; do
  96. case $opt in
  97. f)
  98. file_name=$OPTARG
  99. ;;
  100. g)
  101. group=$OPTARG
  102. ;;
  103. c)
  104. cmd=$OPTARG
  105. if [ -z "$cmd" ]; then
  106. echo "no command"
  107. exit 1
  108. fi
  109. ;;
  110. h)
  111. echo "Usage: $0 -f hosts.cfg -g group -c cmd"
  112. esac
  113. done
  114. # 判断是否有命令
  115. if ! check_expect_cmd ;then
  116. install_expect
  117. fi
  118. # 检测配置文件是否存在
  119. check_file "$file_name"
  120. # 检测组是否存在
  121. if [ "$?" -eq 0 ] ;then
  122. check_group "$group"
  123. else
  124. exit 1
  125. fi
  126. # 批量执行命令
  127. get_group_info "$group" "$cmd"
  128. }
  129. if [ "$#" -eq 0 ];then
  130. main -h
  131. exit 1
  132. fi
  133. main "$@"

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/794607
推荐阅读
相关标签
  

闽ICP备14008679号