赞
踩
在不同主机间传输文件,常用的有三个命令:sftp、scp、rsync。
sftp、scp 与 ssh 这三个命令默认都使用 22 端口。
sftp/scp/rsync 三者连接远程主机时,使用的格式都相同:
- [username@]{hostname|ip}:destination
-
- username:
- 若指定 username,表示以【username】帐号名登入到远程主机,若省略 username,表示以当前本地用户身份登入;
- hostname|ip:
- 可通过【hostname】或【IP】登入远程主机
- destination:
- 是指远程主机上文件位置 或 要将本地文件放到远程主机上的哪个目录下;
传输过程中文件权限与属性变化:
scp 与 cp 指令类似,但 cp 只能是本地拷贝,而 scp 能在不同主机间进行复制,且 scp 传输是加密的。
scp 基本不影响系统正常使用,而 rsync 会导致硬盘 I/O 变高。
- scp [-rp] [-l 速率] source destination 从本地复制到远程主机
- scp [-rp] [-l 速率] destination source 从远程主机复制到本地
-
- 选项:
- -p:保留原文件或目录权限属性
- -r:用于复制目录
- -l:可限制传输速度,单位为 Kbits/s,如 -l 800 代表传输速度为 100KB
-
- 如:
- [root@www ~]# scp root@172.25.0.11:/root/file1 /root #从远程主机上复制文件
- [root@www ~]# scp /root/file1 /root/file2 root@172.25.0.11:/root/ #从本地复制多个文件到远程主机
- [root@www ~]# scp -r root@172.25.0.11:/root/dir1 /root #从远程主机上复制某个目录到本地
rsync 是一个远程数据同步工具,用于同步不同主机间的文件。
它与 scp 区别是,如果两个系统间的两个文件或目录相似,rsync 仅传输两个文件或目录不同部分,而 scp 会复制所有内容。
rsync 优点是,首次传文件时,整个文件复制过去,而从第二次开始,只把“修改过内容”或“不同部分”同步过去,即增量传输。
- rsync [-arvtogp] source destination 从本地同步到远程主机
- rsync [-arvtogp] destination source 从远程主机同步到本地
-
- 选项:
- -r:以递归方式同步整个目录
- -v:显示详细信息
- -t:保留文件修改时间信息
- -l:用于同步 softlink 文件,不加该选项,默认会拒绝同步,提示“skipping non-regular file”
-
- --list-only:
- 仅仅是列出同步的文件有哪些,实际不会执行同步操作,显示格式类似于 ll 命令
- -I, --ignore-times:
- 默认在同步时,若文件大小及修改时间没有变化,与原来一致,则rsync不会同步该文件
- 该选项表示在同步时,即使文件大小及修改时间一致,也要同步该文件
- -z,--compress:
- 在传输文件时进行压缩处理,压缩技术与 gzip 一样
- -p:perserve permission,保留文件权限
- 若不加该选项,rysnc 默认处理权限方式是:
- 如果目的端没有此文件,则在同步后会将目的端文件的权限保持与源端一致;
- 如果目的端已存在此文件,则只会同步文件内容,权限保持原有不变;
- 若使用了 -p,则无论如何,rysnc 都会让目的端保持与源端的权限一致的
-
- -o:保留文件属主(owner)
- -g:保留文件属组(group)
- -D:perserve devices(root only) 保持设备文件的原始信息
-
- -a:归档模式,表示以递归方式传输文件,并尽可能的保持各方面的一致性,等于 -【 r l p t g o D】 一堆命令组合
- 但 -a 无法同步“硬链接”情况,需加上 -H 选项
-
- --delete:删除 DST 端中“SRC端”没有的文件,若使用该选项,必须结合 -r 使用
- --delete-excluded:删除 DST 端中被该选项指定的文件
- --delete-after:传输结束后再删除要清除的文件,默认情况下,rsync是先清理目的端的文件再开始数据同步;
- --exclude=PATTERN:过滤掉指定文件,可使用正则表达式
-
- -n:用于测试哪些文件会被传输,不是真实去执行。也可结合 delete 相关命令测试
-
- 如:
- [root@desktop0 ~]# rsync -azv file1 172.25.0.11:/tmp/dir1 #一般使用av即可
- [root@desktop0 ~]# rsync -r student@172.25.0.11:/home/student /root
sftp 与 ftp 类似,但 sftp 传输的所有信息都使用 ssh 加密,比 ftp 更安全。
- sftp [user@]host[:file ...]
- sftp [user@]host[:dir[/]]
-
- [root@www ~]# sftp root@124.172.235.134 #登入远程主机,并进入到 root 工作目录
- [root@www ~]# sftp root@124.172.235.134:/tmp #登入远程主机,并进入到 /tmp 目录
-
- 远程主机操作命令:
- sftp> pwd #查看当前工作目录
- sftp> cd path #切换工作目录
- sftp> mkdir path #创建目录
- sftp> rename oldpath newpath #重命名文件名
- sftp> ln oldpath newpath #建立文件软连接
- sftp> rm path #删除文件
- sftp> rmdir path #删除目录
- sftp> ls [-1aflnrSt] [path] #查看文件
- sftp> chgrp grp path #修改文件属组
- sftp> chown own path #修改文件属主
- sftp> chmod mode path #修改文件权限
-
- 本机操作命令:
- sftp> lpwd
- sftp> lcd path
- sftp> lls [ls-options [path]]
- sftp> lmkdir path
- sftp> !command #Execute 'command' in local shell
- sftp> ! #Escape to local shell(暂时跳到本地shell模式下执行命令,执行exit命令回到sftp模式下)
-
- 上传与下载:
- sftp> get [-P] remote-path [local-path] #下载文件,若不指定位置,会下载到本地当前工作位置
- sftp> put [-P] local-path [remote-path] #上传文件,若不指定位置,会上传到远程主机当前工作位置
expect 是一个用来处理交互的命令。它的作用是,当我们在 SHELL 脚本中使用 ssh、scp、rsync 等交互式命令时,能免去我们手动输入密码的步骤,expect会自动填入我们预先设置好的密码信息。
安装:
yum install -y expect
语法:
- expect [[ -c cmds ] cmdfile]
-
- cmds:
- send: 向程序发送字符串(Sends string to the current process)
- expect: 等待并接收程序返回的字符串(waits until one of the patterns matches the output of a spawned process)
- spawn:给程序传递交互指令(creates a new process running program args)
- interact:执行完成后保持交互状态,把控制权交回给用户,此时用户可进行手动输入操作(gives control of the current process to the user)
-
- set timeout {second|-1}:
- 设置超时时间,单位是秒,默认为10秒,-1为永不超时
- 若设为30秒,则表示在这30秒期间,都未能成功匹配expect命令定义的字符串,则将跳过该expect判断,执行后续内容
-
- $argv n:
- expect脚本可接收从bash传递过来的参数
- 其中通过 [lindex $argv n] 可获得第 n 个参数的值,通过 [lrange $argv a b] 可获取 a~b 的参数值
示例:
- 语法:send [-flags] string
-
- [root@alihost7 ~]$ expect
- expect1.1> send "hello world\n"
- hello world
- expect1.2> send "123456\n"
- 123456
-
- [root@alihost7 ~]$ expect -c 'send "hello world\n"'
- hello world
- 语法:expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]
-
- 1)基础用法
- [root@alihost7 ~]$ expect
- expect1.1> expect "abc" {send "your input is a letter\n"} #若接收到的字符串为'abc',则执行后面send语句
- abc #手动输入
- youe input is a letter #匹配expect后面定义的字符串,并输出结果
-
- [root@alihost7 ~]$ expect -c 'expect "abc" {send "your input is a letter\n"}'
- abc
- youe input is a letter
-
- [root@alihost7 ~]$ expect -c 'expect "abc*" {send "your input is a letter\n"}'
- abcdefg
- youe input is a letter
-
-
- 2)两个特殊变量
- $expect_out(buffer):存储了所有对expect的输入
- $expect_out(0,string):存储了匹配到expect定义的字符串的输入
-
- [root@alihost7 ~]$ expect -c 'expect "end" {send "all input str: $expect_out(buffer)"}'
- aaaaa
- bbbbb
- ccccc
- end
- all input str: aaaaa
- bbbbb
- ccccc
- end
-
- [root@alihost7 ~]$ expect -c 'expect "end" {send "only match str: $expect_out(0,string)"}'
- aaaaa
- bbbbb
- ccccc
- end
- only match str: end
-
- 3)多个条件分支
- expect最常用的语法是来自tcl语言的pattion-action。
-
- [root@alihost7 ~]$ expect -c 'expect "a" {send "apple"} "b" {send "banana"}'
- b
- banana
- 示例1:通过expect完成ftp交互密码的输入
-
- [root@alihost7 ~]$ cat << EOF > exp_ftp.sh
- #!/usr/bin/expect
- spawn ftp 192.168.100.128 23235
- expect "Name*"
- send "fashion01\r"
- expect "Password:"
- send "fashion01\r"
- expect "ftp> "
- send "binary\r"
- expect "ftp> "
- send "get file\r"
- expect "ftp> "
- send "exit"
- EOF
-
- 执行脚本,自动完成交互过程中的所有输入,输出结果如下:
- [root@alihost7 ~]$ expect exp_ftp.sh
- spawn ftp 192.168.100.128 23235
- Connected to 192.168.100.128 (192.168.100.128).
- Connected to 192.168.100.128 (192.168.100.128).
- 220 (vsFTPd 2.2.2)
- Name (192.168.100.128:root): fashion01
- 331 Please specify the password.
- Password:
- 230 Login successful.
- Remote system type is UNIX.
- Using binary mode to transfer files.
- ftp> binary
- 200 Switching to Binary mode.
- ftp> get file
- local: file remote: file
- 227 Entering Passive Mode (192,168,100,128,243,141).
- 150 Opening BINARY mode data connection for file (4 bytes).
- 226 Transfer complete.
- 4 bytes received in 5.9e-05 secs (67.80 Kbytes/sec)
- 示例:
- [root@alihost7 ~]$ cat << EOF > exp_ftp.sh
- #!/usr/bin/expect
- spawn ftp 192.168.100.128 23235
- expect "Name*"
- send "fashion01\r"
- expect "Password:"
- send "fashion01\r"
- interact
- EOF
-
- 执行脚本,登入进ftp后,就交由用户来操作:
- [root@alihost7 ~]$ expect exp_ftp.sh
- spawn ftp 192.168.100.128 23235
- Connected to 192.168.100.128 (192.168.100.128).
- 220 (vsFTPd 2.2.2)
- Name (192.168.100.128:root): fashion01
- 331 Please specify the password.
- Password:
- 230 Login successful.
- Remote system type is UNIX.
- Using binary mode to transfer files.
- ftp>
- 示例:
- [root@alihost7 ~]$ cat << FOE > exp_args.sh
- #!/usr/bin/expect
- set username [lindex $argv 0]
- set password [lindex $argv 1]
- set hostname [lindex $argv 2]
- spawn ssh $username@$hostname
- expect {
- "yes/no"
- {send "yes\r";exp_continue;}
- "password:"
- {send "$password\r";}
- }
- expect eof
- FOE
-
- 执行脚本,并传入参数。行脚本后,会自动登入和退出机器,如下:
- [root@alihost7 ~]$ expect exp_args.sh root zjm 192.168.100.128
免密码SSH登录:
- [root@alihost7 ~]$ cat << EOF > exp_ssh.sh
- #!/usr/bin/expect
- set timeout 15
- set hostname [lindex $argv 0]
- spawn ssh -l root $hostname
- expect "password*"
- send "123456\r"
- interact
- EOF
-
- 执行脚本登录机器:
- [root@alihost7 ~]$ ./exp_ssh.sh 192.168.1.100
通过expect脚本方式实现ssh、rsync、scp等命令自动输入密码登录。
expect + scp:
- 示例:
- [root@alihost7 ~]$ cat << EOF > exp_scp.sh
- #!/bin/bash
- filepath=/data/shell/dir/scpfile.txt
- username=root
- password=zjm
- hostname=192.168.100.128
- #写法1
- /usr/bin/expect -c "
- spawn scp ${filepath} $username@$hostname:/tmp
- expect {
- \"yes/no\" {send \"yes\r\"; exp_continue;}
- \"*assword\" {set timeout -1; send \"$password\r\";}
- }
- expect eof
- "
- #写法2
- /usr/bin/expect <<EOF
- spawn scp ${filepath} $username@$hostname:/tmp
- expect {
- "yes/no" {send "yes\r"; exp_continue;}
- "*assword" {set timeout -1; send "$password\r";}
- }
- expect eof
- EOF
-
- 执行脚本:
- [root@alihost7 ~]$ sh exp_scp.sh
说明:
- expect eof:
-
- 如果省略expect eof,那脚本立即就结束了,可能得不到正确结果
-
- 这个是和spawn对应的,当spawn发送指令到终端执行时在返回时被expect捕捉时,在起始会有一个eof,
- 就好比在shell中 cat >>file <<OEF\r\r content \r\r EOF一样,在结束时也要有EOF
-
-
- exp_continue:跟continue含义一样.继续下个最近的循环
-
- timeout:设为-1,表示永不超时,若不指定,当传送大文件时会自动断开
expect + rsync:
- [root@alihost7 ~]$ cat << EOF > exp_rsync.sh
- #!/bin/bash
- filepath=/data/shell/dir/rsyncfile.txt
- username=root
- password=zjm
- hostname=192.168.100.128
- /usr/bin/expect <<EOF
- set timeout -1
- spawn rsync -av ${filepath} $username@$hostname:/tmp
- expect {
- "*yes/no" { send "yes\r"; exp_continue }
- "*assword:" { send "$password\r" }
- }
- expect eof
- EOF
expect + ssh:
- [root@alihost7 ~]$ cat << EOF > sleep1.sh
- #!/bin/bash
- sleep 12
- echo 'this is a output file from sleep1.sh script' | tee /tmp/mydir1/sleep1.txt
- EOF
-
-
- [root@alihost7 ~]$ cat << EOF > exp_ssh.sh
- #!/bin/bash
- username=root
- password=zjm
- hostname=192.168.100.128
- /usr/bin/expect <<EOF
- set timeout 15
- spawn ssh $username@$hostname
- expect {
- "*yes/no" { send "yes\r"; exp_continue }
- "*assword:" { send "$password\r" }
- }
- expect "*#"
- send "cd /tmp/mydir1\r"
- expect "*#"
- send "sh sleep1.sh\r"
- expect "*#"
- send "exit\r"
- expect eof
- EOF
说明:
timeout:由于sleep1.sh脚本执行时间需要12秒,当执行expect时,在10秒内若没反馈信息,则会自动退出,所以要设置timeout
expect + ftp:
- [root@alihost7 ~]$ cat << EOF > exp_ftp.sh
- #!/bin/bash
- host=192.168.100.128
- user=fashion01
- port=23235
- password=fashion01
- localpath=/tmp/mydir2/
- /usr/bin/expect <<EOF
- set timeout -1
- spawn ftp -ivn $host $port
- expect "ftp>"
- send "user $user $password\r"
- expect "ftp>"
- send "lcd $localpath\r"
- expect "ftp>"
- send "binary\r"
- expect "ftp>"
- send "mget file1 file2\r"
- expect "ftp>"
- send "exit\r"
- expect eof
- EOF
expect + sftp:
- [root@alihost7 ~]$ cat << EOF > exp_sftp.sh
- #!/bin/bash
- username=root
- hostname=124.172.235.134
- password=Zjm.339224046
- /usr/bin/expect <<EOF
- set timeout -1
- spawn sftp $username@$hostname
- expect {
- "*yes/no" { send "yes\r"; exp_continue }
- "*assword:" { send "$password\r" }
- }
- expect "sftp>"
- send "cd /data/backup\r"
- expect "sftp>"
- send "lcd /tmp\r"
- expect "sftp>"
- send "get /data/backup/* /tmp/mydir1\r"
- expect "sftp>"
- send "exit\r"
- expect eof
- EOF
expect + mysql:
- [root@alihost7 ~]$ cat << EOF > exp_mysql.sh
- #!/bin/bash
- user=root
- password=admin
- host=127.0.0.1
- dbname=test01
- dbpwd=test01
- /usr/bin/expect <<EOF
- set timeout -1
- spawn /usr/local/mysql/bin/mysql -u${user} -p -h ${host}
- expect {
- "*assword:" { send "$password\r" }
- }
- expect "mysql>"
- send "show databases;\r"
- expect "mysql>"
- send "create database IF not EXISTS ${dbname};\r"
- expect "mysql>"
- send "GRANT ALL PRIVILEGES ON $dbname.* TO '$dbname'@'$host' IDENTIFIED BY '$dbpwd' WITH GRANT OPTION;\r"
- expect "mysql>"
- send "exit\r"
- expect eof
- EOF
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。