linux - 让 bash 将带有空格的变量作为单个文件名传递给 tar 时出现问题

标签 linux bash shell tar

用这个把我的头撞在墙上。我正在使用 bash 脚本将目录名文件(每行一个名称,没有字符转义)读入一个变量,并使用该变量在这些目录上调用 tar。如果其中一个目录中有空格,我无法将其正确传递给 tar(将其固定为两个单独的项目不会保留我添加的转义)。我已经尝试了很多变体,但下面是最新的。真正令人沮丧的部分是 echo 显示命令采用我期望的确切形式并按预期手动运行。预先感谢您的帮助。

脚本

#!/bin/bash

#build list of directories to backup from backup_dirs.txt
BACKUP_DIRS=
while read dir; do
    #create escaped version of string to handle spaces, etc...
    esc_line=$(printf '%q' "${dir}")

    echo "###### adding dir '${esc_line}'"

    #add new dire to list
    BACKUP_DIRS=${BACKUP_DIRS}\ "${esc_line}"
done < backup_dirs.txt


echo tar -cjvPf backup.tar.bz2 ${BACKUP_DIRS}

#run backup    
tar -cjvPf backup.tar.bz2 ${BACKUP_DIRS}

示例 backup_dirs.txt 内容

my_stuff
My Stuff

观察输出

###### adding dir 'my_stuff'
###### adding dir 'My\ Stuff'
tar -cjvPf backup.tar.bz2 my_stuff My\ Stuff
my_stuff/
tar: My\\: Cannot stat: No such file or directory
tar: Stuff: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

最佳答案

我会使用 mapfilebackup_dirs.txt 读入 bash 数组:

    mapfile -t BACKUP_DIRS <backup_dirs.txt

然后像这样将它传递给 tar:

    tar -cjvPf backup.tar.bz2 "${BACKUP_DIRS[@]}"

如果您有很多备份目录,我建议您使用命令行选项 -T 直接指定一个文本文件:

    tar -cjvPf backup.tar.bz2 -T backup_dirs.txt

关于linux - 让 bash 将带有空格的变量作为单个文件名传递给 tar 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54282709/

相关文章:

c++ - std::ios_base::Init::Init() 和 std::string::assign(std::string const&) 上的 SIGILL

c++ - eclipse 中的 unique_ptr 自动完成

linux - 通用 ELF 中的重定位 (EM : 62) while cross-compiling from linux to openwrt

linux - 如何检查提供的路径是符号链接(symbolic link)还是常规路径

linux - bash 通过 ssh 连接列出 postgresql 数据库

bash - 如何格式化 emacs 组织模式表中的一列数字?

bash - 在单个程序中监督多个命令

bash - 使用 sed 在捕获组内替换

linux - 两个整数之间的 Bash 值,不是 float

linux - 如何在shell脚本生成的文件顶部写标题