当前位置:   article > 正文

linux篇-文件传输_scp 保留权限

scp 保留权限

在不同主机间传输文件,常用的有三个命令:sftp、scp、rsync。

sftp、scp 与 ssh 这三个命令默认都使用 22 端口。

sftp/scp/rsync 三者连接远程主机时,使用的格式都相同:

  1. [username@]{hostname|ip}:destination
  2. username:
  3. 若指定 username,表示以【username】帐号名登入到远程主机,若省略 username,表示以当前本地用户身份登入;
  4. hostname|ip:
  5. 可通过【hostname】或【IP】登入远程主机
  6. destination:
  7. 是指远程主机上文件位置 或 要将本地文件放到远程主机上的哪个目录下;

传输过程中文件权限与属性变化:

  • 当将本地文件传输到远程主机时,该文件【属主与属组】会发生变化,并改成登入远程主机的 username 的属主与属组;
  • 当从远程主机下载文件到本地时,该文件【属主与属组】也会发生变化,并改成当前本地用户的属主与属组;
  • 也就是说,本地与远程主机之间传输文件时,文件 user 与 group 属性会改变,且始终是【与登入主机的用户】的属性保持一致,除非用 root;
  • 另外除了 user/group 会改变外,【权限属性】也有可能会改变,这个主要是由【文件是否存在】决定;

1、scp

scp 与 cp 指令类似,但 cp 只能是本地拷贝,而 scp 能在不同主机间进行复制,且 scp 传输是加密的。

scp 基本不影响系统正常使用,而 rsync 会导致硬盘 I/O 变高。

  1. scp [-rp] [-l 速率] source destination 从本地复制到远程主机
  2. scp [-rp] [-l 速率] destination source 从远程主机复制到本地
  3. 选项:
  4. -p:保留原文件或目录权限属性
  5. -r:用于复制目录
  6. -l:可限制传输速度,单位为 Kbits/s,如 -l 800 代表传输速度为 100KB
  7. 如:
  8. [root@www ~]# scp root@172.25.0.11:/root/file1 /root #从远程主机上复制文件
  9. [root@www ~]# scp /root/file1 /root/file2 root@172.25.0.11:/root/ #从本地复制多个文件到远程主机
  10. [root@www ~]# scp -r root@172.25.0.11:/root/dir1 /root #从远程主机上复制某个目录到本地

2、rsync

rsync 是一个远程数据同步工具,用于同步不同主机间的文件。

它与 scp 区别是,如果两个系统间的两个文件或目录相似,rsync 仅传输两个文件或目录不同部分,而 scp 会复制所有内容。

rsync 优点是,首次传文件时,整个文件复制过去,而从第二次开始,只把“修改过内容”或“不同部分”同步过去,即增量传输。

  1. rsync [-arvtogp] source destination 从本地同步到远程主机
  2. rsync [-arvtogp] destination source 从远程主机同步到本地
  3. 选项:
  4. -r:以递归方式同步整个目录
  5. -v:显示详细信息
  6. -t:保留文件修改时间信息
  7. -l:用于同步 softlink 文件,不加该选项,默认会拒绝同步,提示“skipping non-regular file
  8. --list-only:
  9. 仅仅是列出同步的文件有哪些,实际不会执行同步操作,显示格式类似于 ll 命令
  10. -I, --ignore-times:
  11. 默认在同步时,若文件大小及修改时间没有变化,与原来一致,则rsync不会同步该文件
  12. 该选项表示在同步时,即使文件大小及修改时间一致,也要同步该文件
  13. -z,--compress:
  14. 在传输文件时进行压缩处理,压缩技术与 gzip 一样
  15. -p:perserve permission,保留文件权限
  16. 若不加该选项,rysnc 默认处理权限方式是:
  17. 如果目的端没有此文件,则在同步后会将目的端文件的权限保持与源端一致;
  18. 如果目的端已存在此文件,则只会同步文件内容,权限保持原有不变;
  19. 若使用了 -p,则无论如何,rysnc 都会让目的端保持与源端的权限一致的
  20. -o:保留文件属主(owner)
  21. -g:保留文件属组(group
  22. -D:perserve devices(root only) 保持设备文件的原始信息
  23. -a:归档模式,表示以递归方式传输文件,并尽可能的保持各方面的一致性,等于 -【 r l p t g o D】 一堆命令组合
  24. 但 -a 无法同步“硬链接”情况,需加上 -H 选项
  25. --delete:删除 DST 端中“SRC端”没有的文件,若使用该选项,必须结合 -r 使用
  26. --delete-excluded:删除 DST 端中被该选项指定的文件
  27. --delete-after:传输结束后再删除要清除的文件,默认情况下,rsync是先清理目的端的文件再开始数据同步;
  28. --exclude=PATTERN:过滤掉指定文件,可使用正则表达式
  29. -n:用于测试哪些文件会被传输,不是真实去执行。也可结合 delete 相关命令测试
  30. 如:
  31. [root@desktop0 ~]# rsync -azv file1 172.25.0.11:/tmp/dir1 #一般使用av即可
  32. [root@desktop0 ~]# rsync -r student@172.25.0.11:/home/student /root

3、sftp

sftp 与 ftp 类似,但 sftp 传输的所有信息都使用 ssh 加密,比 ftp 更安全。

  1. sftp [user@]host[:file ...]
  2. sftp [user@]host[:dir[/]]
  3. [root@www ~]# sftp root@124.172.235.134 #登入远程主机,并进入到 root 工作目录
  4. [root@www ~]# sftp root@124.172.235.134:/tmp #登入远程主机,并进入到 /tmp 目录
  5. 远程主机操作命令:
  6. sftp> pwd #查看当前工作目录
  7. sftp> cd path #切换工作目录
  8. sftp> mkdir path #创建目录
  9. sftp> rename oldpath newpath #重命名文件名
  10. sftp> ln oldpath newpath #建立文件软连接
  11. sftp> rm path #删除文件
  12. sftp> rmdir path #删除目录
  13. sftp> ls [-1aflnrSt] [path] #查看文件
  14. sftp> chgrp grp path #修改文件属组
  15. sftp> chown own path #修改文件属主
  16. sftp> chmod mode path #修改文件权限
  17. 本机操作命令:
  18. sftp> lpwd
  19. sftp> lcd path
  20. sftp> lls [ls-options [path]]
  21. sftp> lmkdir path
  22. sftp> !command #Execute 'command' in local shell
  23. sftp> ! #Escape to local shell(暂时跳到本地shell模式下执行命令,执行exit命令回到sftp模式下)
  24. 上传与下载:
  25. sftp> get [-P] remote-path [local-path] #下载文件,若不指定位置,会下载到本地当前工作位置
  26. sftp> put [-P] local-path [remote-path] #上传文件,若不指定位置,会上传到远程主机当前工作位置

4、expect

expect 是一个用来处理交互的命令。它的作用是,当我们在 SHELL 脚本中使用 ssh、scp、rsync 等交互式命令时,能免去我们手动输入密码的步骤,expect会自动填入我们预先设置好的密码信息。

安装:

yum install -y expect

 语法:

  1. expect [[ -c cmds ] cmdfile]
  2. cmds:
  3. send: 向程序发送字符串(Sends string to the current process)
  4. expect: 等待并接收程序返回的字符串(waits until one of the patterns matches the output of a spawned process)
  5. spawn:给程序传递交互指令(creates a new process running program args)
  6. interact:执行完成后保持交互状态,把控制权交回给用户,此时用户可进行手动输入操作(gives control of the current process to the user)
  7. set timeout {second|-1}:
  8. 设置超时时间,单位是秒,默认为10秒,-1为永不超时
  9. 若设为30秒,则表示在这30秒期间,都未能成功匹配expect命令定义的字符串,则将跳过该expect判断,执行后续内容
  10. $argv n:
  11. expect脚本可接收从bash传递过来的参数
  12. 其中通过 [lindex $argv n] 可获得第 n 个参数的值,通过 [lrange $argv a b] 可获取 a~b 的参数值

示例:

  • send:用于执行交互动作,向程序发送字符串,代替手动输入,需在结尾处加上换行符。
  1. 语法:send [-flags] string
  2. [root@alihost7 ~]$ expect
  3. expect1.1> send "hello world\n"
  4. hello world
  5. expect1.2> send "123456\n"
  6. 123456
  7. [root@alihost7 ~]$ expect -c 'send "hello world\n"'
  8. hello world
  • expect:用于判断输入内容中,是否匹配expect后面定义的字符串,若匹配,则执行后面的语句体。expect后面指定接收的字符串参数也可使用正则表达式。
  1. 语法:expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]
  2. 1)基础用法
  3. [root@alihost7 ~]$ expect
  4. expect1.1> expect "abc" {send "your input is a letter\n"} #若接收到的字符串为'abc',则执行后面send语句
  5. abc #手动输入
  6. youe input is a letter #匹配expect后面定义的字符串,并输出结果
  7. [root@alihost7 ~]$ expect -c 'expect "abc" {send "your input is a letter\n"}'
  8. abc
  9. youe input is a letter
  10. [root@alihost7 ~]$ expect -c 'expect "abc*" {send "your input is a letter\n"}'
  11. abcdefg
  12. youe input is a letter
  13. 2)两个特殊变量
  14. $expect_out(buffer):存储了所有对expect的输入
  15. $expect_out(0,string):存储了匹配到expect定义的字符串的输入
  16. [root@alihost7 ~]$ expect -c 'expect "end" {send "all input str: $expect_out(buffer)"}'
  17. aaaaa
  18. bbbbb
  19. ccccc
  20. end
  21. all input str: aaaaa
  22. bbbbb
  23. ccccc
  24. end
  25. [root@alihost7 ~]$ expect -c 'expect "end" {send "only match str: $expect_out(0,string)"}'
  26. aaaaa
  27. bbbbb
  28. ccccc
  29. end
  30. only match str: end
  31. 3)多个条件分支
  32. expect最常用的语法是来自tcl语言的pattion-action。
  33. [root@alihost7 ~]$ expect -c 'expect "a" {send "apple"} "b" {send "banana"}'
  34. b
  35. banana
  • spawn:上文的所有例子都是跟shell终端自身的stdin与stdout进行交互。相对于spawn命令,它可以和某一个进程进行交互,当与某个进程交互时,send输出和expect输入的字符串,都是与spawn打开的进程进行交互的。
  1. 示例1:通过expect完成ftp交互密码的输入
  2. [root@alihost7 ~]$ cat << EOF > exp_ftp.sh
  3. #!/usr/bin/expect
  4. spawn ftp 192.168.100.128 23235
  5. expect "Name*"
  6. send "fashion01\r"
  7. expect "Password:"
  8. send "fashion01\r"
  9. expect "ftp> "
  10. send "binary\r"
  11. expect "ftp> "
  12. send "get file\r"
  13. expect "ftp> "
  14. send "exit"
  15. EOF
  16. 执行脚本,自动完成交互过程中的所有输入,输出结果如下:
  17. [root@alihost7 ~]$ expect exp_ftp.sh
  18. spawn ftp 192.168.100.128 23235
  19. Connected to 192.168.100.128 (192.168.100.128).
  20. Connected to 192.168.100.128 (192.168.100.128).
  21. 220 (vsFTPd 2.2.2)
  22. Name (192.168.100.128:root): fashion01
  23. 331 Please specify the password.
  24. Password:
  25. 230 Login successful.
  26. Remote system type is UNIX.
  27. Using binary mode to transfer files.
  28. ftp> binary
  29. 200 Switching to Binary mode.
  30. ftp> get file
  31. local: file remote: file
  32. 227 Entering Passive Mode (192,168,100,128,243,141).
  33. 150 Opening BINARY mode data connection for file (4 bytes).
  34. 226 Transfer complete.
  35. 4 bytes received in 5.9e-05 secs (67.80 Kbytes/sec)
  • interact:如何让人在适当的时候干预这个过程,比如下载完ftp文件时,仍然可以停留在ftp命令行状态,以便手动的执行后续命令,interact可以达到这些目的。
  1. 示例:
  2. [root@alihost7 ~]$ cat << EOF > exp_ftp.sh
  3. #!/usr/bin/expect
  4. spawn ftp 192.168.100.128 23235
  5. expect "Name*"
  6. send "fashion01\r"
  7. expect "Password:"
  8. send "fashion01\r"
  9. interact
  10. EOF
  11. 执行脚本,登入进ftp后,就交由用户来操作:
  12. [root@alihost7 ~]$ expect exp_ftp.sh
  13. spawn ftp 192.168.100.128 23235
  14. Connected to 192.168.100.128 (192.168.100.128).
  15. 220 (vsFTPd 2.2.2)
  16. Name (192.168.100.128:root): fashion01
  17. 331 Please specify the password.
  18. Password:
  19. 230 Login successful.
  20. Remote system type is UNIX.
  21. Using binary mode to transfer files.
  22. ftp>
  • $argv n:expect脚本可接收从bash传递过来的参数,其中通过 [lindex $argv n] 可获得第 n 个参数的值,通过 [lrange $argv a b] 可获取 a~b 的参数值。
  • exp_continue:该命令附加于某个 expect 判断项之后,可以使该项被匹配后,还能继续匹配该 expect 判断语句内的其他项。
  1. 示例:
  2. [root@alihost7 ~]$ cat << FOE > exp_args.sh
  3. #!/usr/bin/expect
  4. set username [lindex $argv 0]
  5. set password [lindex $argv 1]
  6. set hostname [lindex $argv 2]
  7. spawn ssh $username@$hostname
  8. expect {
  9. "yes/no"
  10. {send "yes\r";exp_continue;}
  11. "password:"
  12. {send "$password\r";}
  13. }
  14. expect eof
  15. FOE
  16. 执行脚本,并传入参数。行脚本后,会自动登入和退出机器,如下:
  17. [root@alihost7 ~]$ expect exp_args.sh root zjm 192.168.100.128

免密码SSH登录:

  1. [root@alihost7 ~]$ cat << EOF > exp_ssh.sh
  2. #!/usr/bin/expect
  3. set timeout 15
  4. set hostname [lindex $argv 0]
  5. spawn ssh -l root $hostname
  6. expect "password*"
  7. send "123456\r"
  8. interact
  9. EOF
  10. 执行脚本登录机器:
  11. [root@alihost7 ~]$ ./exp_ssh.sh 192.168.1.100

 

5、综合案例

通过expect脚本方式实现ssh、rsync、scp等命令自动输入密码登录。

expect + scp:

  1. 示例:
  2. [root@alihost7 ~]$ cat << EOF > exp_scp.sh
  3. #!/bin/bash
  4. filepath=/data/shell/dir/scpfile.txt
  5. username=root
  6. password=zjm
  7. hostname=192.168.100.128
  8. #写法1
  9. /usr/bin/expect -c "
  10. spawn scp ${filepath} $username@$hostname:/tmp
  11. expect {
  12. \"yes/no\" {send \"yes\r\"; exp_continue;}
  13. \"*assword\" {set timeout -1; send \"$password\r\";}
  14. }
  15. expect eof
  16. "
  17. #写法2
  18. /usr/bin/expect <<EOF
  19. spawn scp ${filepath} $username@$hostname:/tmp
  20. expect {
  21. "yes/no" {send "yes\r"; exp_continue;}
  22. "*assword" {set timeout -1; send "$password\r";}
  23. }
  24. expect eof
  25. EOF
  26. 执行脚本:
  27. [root@alihost7 ~]$ sh exp_scp.sh

说明:

  1. expect eof:
  2. 如果省略expect eof,那脚本立即就结束了,可能得不到正确结果
  3. 这个是和spawn对应的,当spawn发送指令到终端执行时在返回时被expect捕捉时,在起始会有一个eof,
  4. 就好比在shell中 cat >>file <<OEF\r\r content \r\r EOF一样,在结束时也要有EOF
  5. exp_continue:跟continue含义一样.继续下个最近的循环
  6. timeout:设为-1,表示永不超时,若不指定,当传送大文件时会自动断开

expect + rsync:

  1. [root@alihost7 ~]$ cat << EOF > exp_rsync.sh
  2. #!/bin/bash
  3. filepath=/data/shell/dir/rsyncfile.txt
  4. username=root
  5. password=zjm
  6. hostname=192.168.100.128
  7. /usr/bin/expect <<EOF
  8. set timeout -1
  9. spawn rsync -av ${filepath} $username@$hostname:/tmp
  10. expect {
  11. "*yes/no" { send "yes\r"; exp_continue }
  12. "*assword:" { send "$password\r" }
  13. }
  14. expect eof
  15. EOF

expect + ssh:

  1. [root@alihost7 ~]$ cat << EOF > sleep1.sh
  2. #!/bin/bash
  3. sleep 12
  4. echo 'this is a output file from sleep1.sh script' | tee /tmp/mydir1/sleep1.txt
  5. EOF
  6. [root@alihost7 ~]$ cat << EOF > exp_ssh.sh
  7. #!/bin/bash
  8. username=root
  9. password=zjm
  10. hostname=192.168.100.128
  11. /usr/bin/expect <<EOF
  12. set timeout 15
  13. spawn ssh $username@$hostname
  14. expect {
  15. "*yes/no" { send "yes\r"; exp_continue }
  16. "*assword:" { send "$password\r" }
  17. }
  18. expect "*#"
  19. send "cd /tmp/mydir1\r"
  20. expect "*#"
  21. send "sh sleep1.sh\r"
  22. expect "*#"
  23. send "exit\r"
  24. expect eof
  25. EOF

说明:

timeout:由于sleep1.sh脚本执行时间需要12秒,当执行expect时,在10秒内若没反馈信息,则会自动退出,所以要设置timeout

expect + ftp:

  1. [root@alihost7 ~]$ cat << EOF > exp_ftp.sh
  2. #!/bin/bash
  3. host=192.168.100.128
  4. user=fashion01
  5. port=23235
  6. password=fashion01
  7. localpath=/tmp/mydir2/
  8. /usr/bin/expect <<EOF
  9. set timeout -1
  10. spawn ftp -ivn $host $port
  11. expect "ftp>"
  12. send "user $user $password\r"
  13. expect "ftp>"
  14. send "lcd $localpath\r"
  15. expect "ftp>"
  16. send "binary\r"
  17. expect "ftp>"
  18. send "mget file1 file2\r"
  19. expect "ftp>"
  20. send "exit\r"
  21. expect eof
  22. EOF

expect + sftp:

  1. [root@alihost7 ~]$ cat << EOF > exp_sftp.sh
  2. #!/bin/bash
  3. username=root
  4. hostname=124.172.235.134
  5. password=Zjm.339224046
  6. /usr/bin/expect <<EOF
  7. set timeout -1
  8. spawn sftp $username@$hostname
  9. expect {
  10. "*yes/no" { send "yes\r"; exp_continue }
  11. "*assword:" { send "$password\r" }
  12. }
  13. expect "sftp>"
  14. send "cd /data/backup\r"
  15. expect "sftp>"
  16. send "lcd /tmp\r"
  17. expect "sftp>"
  18. send "get /data/backup/* /tmp/mydir1\r"
  19. expect "sftp>"
  20. send "exit\r"
  21. expect eof
  22. EOF

expect + mysql:

  1. [root@alihost7 ~]$ cat << EOF > exp_mysql.sh
  2. #!/bin/bash
  3. user=root
  4. password=admin
  5. host=127.0.0.1
  6. dbname=test01
  7. dbpwd=test01
  8. /usr/bin/expect <<EOF
  9. set timeout -1
  10. spawn /usr/local/mysql/bin/mysql -u${user} -p -h ${host}
  11. expect {
  12. "*assword:" { send "$password\r" }
  13. }
  14. expect "mysql>"
  15. send "show databases;\r"
  16. expect "mysql>"
  17. send "create database IF not EXISTS ${dbname};\r"
  18. expect "mysql>"
  19. send "GRANT ALL PRIVILEGES ON $dbname.* TO '$dbname'@'$host' IDENTIFIED BY '$dbpwd' WITH GRANT OPTION;\r"
  20. expect "mysql>"
  21. send "exit\r"
  22. expect eof
  23. EOF

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

闽ICP备14008679号