【问题标题】:Bash: need help passing a a variable to rsyncBash:需要帮助将变量传递给 rsync
【发布时间】:2018-11-15 13:17:15
【问题描述】:

我想传递 $home 作为运行 rsync 时要排除的目录列表。文件:

cat backup_system.sh
#!/bin/bash
set -x
home=''
home=$home'"/home/ravas/Documents/*"',
home=$home'"/home/ravas/Downloads/*"',
home=$home'"/home/ravas/pCloudDrive/*"',
home=$home'"/home/ravas/pCloudLocal/*"',
home=$home'"/home/ravas.old/*"'
echo $home
sudo rsync -aAXv / --exclude={$home,"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} /run/media/ravas/system_backup

没有 $home 变量的备份运行良好,但如果我添加它,它没有任何效果。

输出的最后两行显示 $home 中列出的目录没有用 --exclude 展开,而其他的则。

不用说,我不是很擅长 bash,任何帮助将不胜感激!

./backup_system.sh 
+ home=
+ home='"/home/ravas/Documents/*",'
+ home='"/home/ravas/Documents/*","/home/ravas/Downloads/*",'
+ home='"/home/ravas/Documents/*","/home/ravas/Downloads/*","/home/ravas/pCloudDrive/*",'
+ home='"/home/ravas/Documents/*","/home/ravas/Downloads/*","/home/ravas/pCloudDrive/*","/home/ravas/pCloudLocal/*",'
+ home='"/home/ravas/Documents/*","/home/ravas/Downloads/*","/home/ravas/pCloudDrive/*","/home/ravas/pCloudLocal/*","/home/ravas.old/*"'
+ echo '"/home/ravas/Documents/*","/home/ravas/Downloads/*","/home/ravas/pCloudDrive/*","/home/ravas/pCloudLocal/*","/home/ravas.old/*"'
"/home/ravas/Documents/*","/home/ravas/Downloads/*","/home/ravas/pCloudDrive/*","/home/ravas/pCloudLocal/*","/home/ravas.old/*"
+ sudo rsync -aAXv / 
'--exclude="/home/ravas/Documents/*","/home/ravas/Downloads/*","/home/ravas/pCloudDrive/*","/home/ravas/pCloudLocal/*","/home/ravas.old/*"' 
'--exclude=/dev/*' '--exclude=/proc/*' '--exclude=/sys/*' '--exclude=/tmp/*' '--exclude=/run/*' '--exclude=/mnt/*' '--exclude=/media/*' --exclude=/lost+found** /run/media/ravas/system_backup

【问题讨论】:

    标签: bash variables rsync


    【解决方案1】:

    基本问题是 bash 在您的命令中解析各种内容的顺序对于您正在尝试做的事情都是错误的。具体来说,它解析(并应用和删除)引号和转义,然后展开{this,that,theother} 列表,然后展开变量引用(如$home)。最终结果是,当 $home 扩展为以逗号分隔的引用元素列表时,引号或逗号都为时已晚。

    像往常一样,在这种情况下,数组是处理这种情况的最佳方式:

    homearray=()
    homearray+=("/home/ravas/Documents/*")
    homearray+=("/home/ravas/Downloads/*")
    homearray+=("/home/ravas/pCloudDrive/*")
    homearray+=("/home/ravas/pCloudLocal/*")
    homearray+=("/home/ravas.old/*")
    # Alternate short form:
    # homearray=(/home/ravas/{Documents,Downloads,pCloudDrive,pCloudLocal}/"*" "/home/ravas.old/*")
    sudo rsync -aAXv / "${homearray[@]/#/--exclude=}" --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} /run/media/ravas/system_backup
    

    解释:"${homearray[@]/#/--exclude=}" 做了三件事;首先,[@] 使其扩展到数组的所有元素;然后/#/--exclude=用“--exclude=”“替换”每个元素的开头(本质上,它在每个元素前面加上“--exclude=”),最后它周围的双引号保留通配符(“* ") 从扩大和造成严重破坏。

    【讨论】:

      【解决方案2】:

      几乎所有多参数相关问题的解决方案都是使用数组:

      exclusions=(
        --exclude "/home/ravas/Documents/*"
        --exclude "/home/ravas/Downloads/*"
        --exclude "/home/ravas/pCloudDrive/*"
        --exclude "/home/ravas/pCloudLocal/*"
        --exclude "/home/ravas.old/*"
        --exclude "/dev/*"
        --exclude "/proc/*"
        --exclude "/sys/*"
        --exclude "/tmp/*"
        --exclude "/run/*" 
        --exclude "/mnt/*"
        --exclude "/media/*"
        --exclude "/lost+found"
      )
      
      sudo rsync -aAXv / "${exclusions[@]}" /run/media/ravas/system_backup
      

      如果您没有将标准输入用于其他任何内容,您可以使用带有此处文档的--exclude-from 选项来缩短此时间:

      sudo rsync -aAXv / --exclude-from - /run/media/ravas/system_backup <<EOF
      /home/ravas/Documents/*
      /home/ravas/Downloads/*
      /home/ravas/pCloudDrive/*
      /home/ravas/pCloudLocal/*
      /home/ravas.old/*
      /dev/*
      /proc/*
      /sys/*
      /tmp/*
      /run/* 
      /mnt/*
      /media/*
      /lost+found
      EOF
      

      【讨论】:

      • 不错的答案,您也可以使用文件来执行此操作。
      【解决方案3】:

      Bash 中的字符串处理很少是简单的,但这里有一些工作......

      ( list=abc,'"def\ ghi"',jkl ; eval echo --exclude={$list} )
      

      输出:

      --exclude=abc --exclude=def\ ghi --exclude=jkl
      

      eval command in Bash and its typical uses

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-03
      • 2020-02-29
      相关资源
      最近更新 更多