【问题标题】:Linux script variables to SCP and delete filesLinux 脚本变量到 SCP 和删除文件
【发布时间】:2018-02-17 07:28:31
【问题描述】:

我希望设置一个脚本来执行以下操作:

1st:每月第一天将目录SCP到另一台服务器

2nd:传输成功后删除目录

我需要移动的目录总是有不同的名称,编号最小的总是需要移动的目录:

2018/files/02/

2018/files/03/

所以我想写的是这样的:

scp /2018/files/% user@host:/backups/2018/files/
{where % = lowest num} && 
rm -rf /2018/files/%
{where % = lowest num} &&
exit

感谢您的建议

【问题讨论】:

  • 您具体尝试了什么?你的结果是什么?
  • 您愿意使用 Ruby 语言吗? Ruby(或 Python,或其他脚本语言)会更容易用于这样的事情。
  • @KeithBennett +1 对于查找目录的基本问题,它可以在紧凑的纯 shell 中完成。在下面检查我的答案。它确实取决于非常具体的shell行为,必须很好地理解这一点。
  • @HenkLangeveld 我毫不怀疑这可以在纯 shell 中完成(我向你致敬!),但对我来说,使用 Ruby 中的非平凡脚本更有效率。 Ruby 以 Rails 中的 Web 开发而闻名,但我发现它是通用的超级语言。

标签: linux shell centos


【解决方案1】:

如果您愿意使用 Ruby,您可以通过以下方式完成它:

def file_number(filespec)
  filespect.split('/').last.to_i
end

directories = Dir['/2018/files'].select { |f| File.directory?(f) }
sorted_dirs = directories.sort_by do |dir1, dir2|
  file_number(dir1) <=> file_number(dir1)
end

dir_to_copy = sorted_dirs.first
destination_dir = File.join('/', 'backups', dir_to_copy)

`scp #{dir_to_copy} user@host:#{destination_dir}`
`rm -rf #{dir_to_copy}`

我没有对此进行测试,但是如果您有任何问题,请告诉我它们是什么,我可以与您一起解决。

虽然使用 shell 脚本消除了对 Ruby 解释器的需求,但对我来说,代码并不是那么简单。

在非常大的目录列表(可能有 10,000 个?)中,排序可能慢得令人无法忍受,需要另一种方法来优化速度。

我会提醒你不要在备份后做无条件的rm -rf——这对我来说似乎真的很冒险。

【讨论】:

    【解决方案2】:

    这里最大的挑战是实际找到要复制的正确文件,然后颤抖删除。所以让我们称之为步骤 0。

    让我们从一些样板开始

    sourceD=/2018/files/ 
    targetD=/backups/2018/files/
    

    还有一个little assertion,如果$1 不等同于目录,它将退出脚本。

    assert_directory() { (cd ${1:?directory name}) || exit; }
    

    步骤 0:识别目录:

    assert_directory $sourceD
    to_be_archived=$(
      # source must be two characters, hence "??"
      # source must a directory, hence trailing "/"
      # set -- sorts its arguments
      # First match must be our source
      set -- $sourceD/??/ &&
        assert_directory "$1"
        echo ${1:?nothing found}
    ) || exit
    

    这只是几行压缩代码。请注意,这可能 如果您(不小心)连续运行多次,则会造成麻烦。

    第 1 步,复制文件现在看起来很简单。

    scp -r ${to_be_archived:?} user@host:${targetD:?}
    

    这是一种复制文件的简单方法,但速度慢且风险大。 在ssh 上查找rsync 以查找替代方案。

    第 2 步,删除

    rm -fr 行可以完成这项工作,但我不会在此处包含它。 我们错过了一个重要的步骤,因为我们需要确保我们的 文件已安全到达。同样,rsync 有这方面的选择。


    总结:

    assert_directory() { (cd ${1:?directory name}) || exit; }
    
    assert_directory $sourceD
    to_be_archived=$(
      set -- $sourceD/??/ &&
        assert_directory "$1"
        echo ${1:?nothing found}
    ) || exit
    

    这将为您提供sourceD 中的第一个两个字符名称目录(如果存在)或中止正在运行的脚本。如果$sourceD 包含空格,它将中断。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多