要求,在A机器执行脚本,把A机器的某个目录文件拷贝到B机器。
第一版ftp实现:
1、A 机器先安装 ftp 客户端
$ sudo yum install ftp
2、B机器安装ftp服务端
$ sudo yum -y install vsftpd
2.1、查询B机器是否安装完成,执行后有下面的输出,就是ok的。
$ netstat -an | grep 21
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN
2.2、ftp 的重启命令
$ sudo service vsftpd restart
3、在A机器中编写一个执行脚本
vi upload.sh
#!/bin/bash #upload dir to remote ftp server read -p "Input local dir: " updir #local dir read -p "Input remote dir: " todir #remote dir read -p "Input remote IP: " ip #remote IP read -p "Input ftp username: " user #ftp username read -p "Input password: " password #password sss=`find $updir -type d -printf $todir/'%P\n'| awk '{if ($0 == "")next;print "mkdir " $0}'` aaa=`find $updir -type f -printf 'put %p %P \n'` ftp -nv $ip <<EOF user $user $password type binary prompt $sss cd $todir $aaa quit EOF
4、再给这个 .sh 文件赋予执行权限
chmod +x upload.sh
5、执行sh
$ ./upload.sh
输入五个参数
/home/admin/testA
aa
1xx.xx.xxx.xx
admin
xxx
完成。
注意:
都是在 admin 账户下操作,所以用了 sudo 借用 root 权限, roo t账户可以省去。
目标服务器只能写一层目录 aa,不能写多层 aa/bb/cc
改善版scp实现:
1、实现过程需要使用到 expect 处理交互,先安装 expect
sudo yum -y install expect
2、在A机器上编写执行脚本
#!/bin/bash #upload dir to remote scp server read -p "Input local dir: " updir #localdir read -p "Input remote dir: " todir #remote dir read -p "Input remote IP: " ip #remote IP read -p "Input ftp username: " user #scp username read -p "Input password: " password #password /usr/bin/expect <<EOF set timeout -1 ; spawn ssh ${user}@${ip} ; expect *password* { send "${password}\r" } ; expect ${user}@* { send "stat ${todir}\r" } ; expect { *File:* { send "rm -rf ${todir}\r" expect ${user}@* { send "mkdir -p ${todir}\r" } } *stat:* { send "mkdir -p ${todir}\r" } } ; send "exit\r" ; expect eof ; EOF /usr/bin/expect <<EOF set timeout -1 ; spawn scp -r ${updir} ${user}@${ip}:${todir} ; expect *password* { send "${password}\r" } ; expect eof ; EOF
脚本中几个实现逻辑:
1、ssh、scp 连接时,不能直接输入 password,所以要用 expect 处理交互命令。
2、expect处理交互命令时可以写expect执行文件,也可以省事,直接写在bash脚本文件中。写入bash脚本中也有两种方式:
- 一种是上面脚本中采用的输入重定向的方式。
- 一种是以可执行命令前置符 expect -c 的方式,把expect 执行命令写到bash脚本中。
#!/bin/bash #upload dir to remote scp server read -p "Input local dir: " updir #localdir read -p "Input remote dir: " todir #remote dir read -p "Input remote IP: " ip #remote IP read -p "Input ftp username: " user #scp username read -p "Input password: " password #password expect -c " set timeout -1 ; spawn scp -r ${updir} ${user}@${ip}:${todir} ; expect *password* { send \"${password}\r\" } ; expect eof ; "
3、在判断文件目录是否存在时,正常在本机执行的 shell 中一般用 test -d 命令判断,但是在 expect 交互时,不便使用 shell 命令,改成使用 linux 命令 stat 。根据目录存在与否的不同输出,作为判断条件,选择执行后续代码。
改善版比第一版好在:改善版能指定B机器的任意目录作为接受路径,并对路径判断,存在-->先删再建,不存在直接建。支持多级目录。
注意:
shell中插入expect脚本的执行,注意第二个EOF所在行前面不能留空格
du命令用来查看目录或文件所占用磁盘空间的大小。常用选项组合为:du -sh