linux 远程文件同步(shell)

1.首先安装tcl和expect(先安装tcl,再安装expect,自行百度),sshpass
2.我想把本地文件同步到其他几台机器上,因此,需要知道机器的ip,username,password,我用一个文件来存放这些内容machine_info,内容如下:

127.0.0.1 username password
192.168.12.12 usename password

编写expect shell

#!/usr/bin/expect -f
set timeout -1  #永不超时,默认为10s
set src_file [lindex $argv 0]  #argv参数读取,必须是argv
set user_name [lindex $argv 1]
set host_ip [lindex $argv 2]
set dest_file [lindex $argv 3]
set password [lindex $argv 4]
spawn scp $src_file $user_name@$host_ip:$dest_file
expect {
    "*(yes/no)?"
              {
                  send "yes\r"
                  expect "*assword:" {
                      send "$password\r"
                  }
              }
    "*assword:"{
              send "$password\r"
    }
}
expect eof

编写批量 shell,传的参数为文件名和上传到机器的路径

#!/bin/bash
#$0含义
file_name=$1 # =不能空格
file_path=$2
#逐行读取machine_info里面的数据,while read不能改
while read line
do 
    ip=`echo $line | cut -d' ' -f 1`
    user_name=`echo $line | cut -d' ' -f 2`
    password=`echo $line | cut -d' ' -f 3`
    sshpass -p $password ssh $user_name@$ip mkdir -p $file_path </dev/null #后面的</dev/null很重要,还有记住这种写法
    ./expect.sh $file_name $user_name $ip $file_path $password
done < machine_info

注:mkdir没有为你创建,有的话就什么都不做,为什要加上/dev/null?
原因是while重定向机制,machine_info文件中的信息都已经读入并重定向给了整个while语句。所以当我们在while循环中再一次调用read语句,就会读取到下一条记录。问题就出在这里,ssh语句正好会读取输入中的所有东西,可以用下面命令证明:

sshpass -p $password ssh $user_name@$ip cat

会发现打印出所有内容,这就导致调用完ssh语句后,输入缓存中已经都被读完了,当read语句再读的时候当然也就读不到纪录,循环也就退出了。因此就要让ssh重定向,就要加/dev/null,或者改用for来执行循环,还有的说ssh加一个-n也行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章