首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于不展开的循环文件夹列表。

用于不展开的循环文件夹列表。
EN

Unix & Linux用户
提问于 2018-07-03 18:08:21
回答 1查看 165关注 0票数 2

我试图为bash上的备份脚本生成一个命令行。

简单的例子:

代码语言:javascript
复制
EXCLUDES="/home/*/.cache/* /var/cache/* /var/tmp/* /var/lib/lxcfs/cgroup/*"; 
for FOLDER in $EXCLUDES; do printf -- '--exclude %b\n' "$FOLDER" ; done

应导致:

代码语言:javascript
复制
--exclude '/home/*/.cache/*' --exclude '/var/cache/*' --exclude '/var/tmp/*' --exclude '/var/lib/lxcfs/cgroup/*'

但问题是,文件夹是从shell中展开的。我试过很多例子,比如echo / printf /引文/IFS.但没有正确的结果。

有办法解决这个问题吗?

EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2018-07-03 18:22:57

每当您必须用文件名globs指定路径名或路径名的列表时,或者通常只指定要循环的列表和/或将其用作某个命令的参数列表时,请使用数组。

如果不使用数组,而使用字符串,则无法处理其中包含空格的事情(因为您在字符串中使用空格作为分隔符)。它还使您很难循环字符串的内容,因为您将不得不调用单词拆分(通过不引用变量展开)。但是,这也会导致文件名全局化的发生,除非您在set -f中显式地关闭它。

在大多数shell中,即使在普通的/bin/sh中,也要使用数组。在sh中,使用位置参数数组($@)。

对于bash,使用一个引号字符串数组,如

代码语言:javascript
复制
excludes=( '/home/*/.cache/*'
           '/var/cache/*'
           '/var/tmp/*'
           '/var/lib/lxcfs/cgroup/*' )

然后,

代码语言:javascript
复制
rsync_opts=( --verbose --archive )
for excl in "${excludes[@]}"; do
    rsync_opts+=( --exclude="$excl" )
done

后来,

代码语言:javascript
复制
rsync "${rsync_opts[@]}" source/ target

请注意,引号在上述所有变量展开中都很重要。展开"${array[@]}" (以及下面的"$@" )将生成一个单独引用的数组元素列表(但只有在双引用的情况下!)。

对于任何/bin/sh外壳:

代码语言:javascript
复制
set -- '/home/*/.cache/*'  \
       '/var/cache/*'      \
       '/var/tmp/*'        \
       '/var/lib/lxcfs/cgroup/*'

for excl do
    set -- "$@" --exclude="$excl"
    shift
done
set -- --verbose --archive "$@"

rsync "$@" source/ target
票数 5
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/453276

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档