2017-03-05 82 views
0

我试图制作一个脚本,ssh到多个服务器并运行它们的备份。服务器有不同的文件夹,应该包含在内。rsync备份bash脚本从另一个文件中读取选项

我试图用2个文件来做到这一点,它指定了应该包含在备份中的主机名和文件夹。

[SERVER] 
HOST=server1 
SOURCE="/home" 
SOURCE="/etc" 

[SERVER] 
HOST=server2 
SOURCE=/home" 
SOURCE="/etc" 
SOURCE="/var" 

[EOF] 

而且有一个文件从该文件读取并执行备份。

while read host 
do 
     for i in 
       rsync -chazP --fake-super --rsync-path="sudo rsync" --stats [email protected]$host:/home /var/backup/$host/ 
     done 
done < /var/backup/testscripts/hosts 

这是脚本的第一个版本,当选项文件只有主机名的时候,它才能工作。

如何让脚本读取主机变量,然后读取1 SOURCE行并执行备份,然后读取下一个SOURCE行并再次运行。当它读取[SERVER]时,它应该重新开始,当涉及到[EOF]时它应该结束。

Iam初学者在脚本编写,所以所有的帮助和解释是值得欢迎的。

+0

我建议看看'dirvish'来用rsync备份服务器。 – Cyrus

回答

0

我建议你从不同的角度攻击这个问题,以使其更简单。

首先,制作/var/backup/testscripts/hosts一个目录,而不是一个文件。然后,为每个主机创建一个名为“SERVERNAME.backup_config”的配置文件。这些文件的内容是这样的:

/home 
/etc 

本质上说,只是一个备份到该主机的目录列表。这将摆脱需要解析配置文件。

config_dir=/var/backup/testscripts/hosts 
for config_file in "$config_dir"/*.backup_config 
do 
    host=${config_file##*/} 
    host=${host%.backup_config} 
    while IFS= read -r dir 
    do 
    rsync -chazP --fake-super --rsync-path="sudo rsync" --stats [email protected]:"$dir" "/var/backup/$host/" 
    done<"$config_file" 
done 

从本质上讲,这个想法是在文件的名称编码您的服务器名称,从而使文件变成只是一个可以在同一时间内读取一行的列表。这可以是一个简单的方法来配置这些简单情况下的文件。如果每个配置项目需要多个列表,则可以再执行一个步骤:使每个服务器成为一个目录,并为需要的各种列表使用多个配置文件(并且可能还有一个配置文件用于所有不是列表,包含分配,可以使用source.读取)。

用于分配host的行是shell扩展,它从文件路径中删除目录名称,然后删除扩展名以确切确定服务器名称。你可以在这里找到它(以及更多):http://wiki.bash-hackers.org/syntax/pe

请注意我还没有检查您的rsync命令是否有效,我认为它适用于您的目的。

+0

could not'host host = $ {config_file%/}被写入host = $ config_file 我在bash模拟器中试了一下,并写了config_file =/var/backup/files/server1.backup_config 并在过滤后得到了server1。 Thans非常感谢您的帮助。真的很好预期。 实际上,rsync脚本存在问题。当脚本以非root用户(如预期的)开始时,备份服务器上的文件将备份服务器用户作为所有者。但是,当被复制回原始服务器时,正确的所有者又回来了。 – DragonRapide

+0

@DragonRapide老实说,'host = $ {config_file%/}'步骤可以被删除:它删除了任何结尾的斜杠,但在你的情况下不能有任何结尾斜杠(如果从我的个人标准“纯Bash” 'basename'替换)。我更新了建议的代码以将其删除(由于删除,以下行需要修改)。 – Fred

0

不可否认,这个解决方案并不能很好地扩展,但是你拥有一个文件中的所有东西,而且你不需要在bash中读取配置文件。

function my_rsync() { 
    rsync -chazP --fake-super --rsync-path="sudo rsync" --stats "$1" "$2" 
} 


declare -a SERVERS=(
    "server1" 
    "server2" 
); 

declare -a SOURCES1=(
    "/home" 
    "/etc" 
); 

declare -a SOURCES2=(
    "/home" 
    "/etc" 
    "/var" 
); 


for SERVER in "${SERVERS[@]}"; do 

    case "$SERVER" in 
     "server1") 
      for SOURCE in "${SOURCES1[@]}"; do 
       my_rsync [email protected]$SERVER:$SOURCE /var/backup/$SERVER/ 
      done 
     ;; 
     "server2") 
      for SOURCE in "${SOURCES2[@]}"; do 
       my_rsync [email protected]$SERVER:$SOURCE /var/backup/$SERVER/ 
      done 
     ;; 
    esac 

done 

另一种解决方案是使用包括使用rsync(--include-from=FILE read include patterns from FILE) 文件和为每个服务器创建一个includefile和例如它们命名server1.txt/server2.txt等 然后,你不会需要开关/大小写块,并可以写这样的东西(未测试!):

for SERVER in "${SERVERS[@]}"; do 

    rsync -chazP --fake-super --rsync-path="sudo rsync" --stats --include-from=/path/to/$SERVER.txt [email protected]$SERVER /var/backup/$SERVER/ 

done