0

我对以下 ksh 脚本有疑问:

#! /usr/bin/ksh 

EXCLUDE+=" --exclude '/bin/a*' "
echo $EXCLUDE
tar --preserve-permissions --create  $EXCLUDE --file tar.tar /bin

由于将模式传递给排除目标需要单引号。(我想排除 /bin 文件夹中以“a”开头的所有文件)。

Echo 行还显示了正确且未更改的结果(模式没有扩展,单引号仍然存在)。但是,此排除目标无效。

但是,如果我输入实际值而不是 $EXCLUDE,它就起作用了!

#! /usr/bin/ksh 

tar --preserve-permissions --create  --exclude '/bin/a*' --file tar.tar /bin

这一定是我遇到的一些引用问题,但是什么?

4

2 回答 2

1

EXCLUDE=' --exclude /bin/a* '足够的。您的代码排除了'/bin/a*'(引号''是模式的一部分)模式,但您真正想要的是排除/bin/a*模式。

于 2011-08-13T12:50:12.053 回答
0

概括

是的,您的问题与引用有关。

讨论

在调试这类问题时,我发现echo每行打印一个参数的变体是非常宝贵的。我为它使用的名称是al(用于“参数列表”)。将其用作tar脚本中命令的前缀,使用 ' ksh -x tartest.ksh' 运行,跟踪输出为:

+ EXCLUDE+=$' --exclude \'/bin/a*\' '
+ echo --exclude $'\'/bin/a*\''
--exclude '/bin/a*'
+ al tar --preserve-permissions --create --exclude $'\'/bin/a*\'' --file tar.tar /bin
tar
--preserve-permissions
--create
--exclude
'/bin/a*'
--file
tar.tar
/bin

请注意 shell 是如何花费大量时间来确保tar命令(或al命令)看到单引号的。当您遵循John的建议时,您会看到不同的输出:

+ EXCLUDE+=' --exclude /bin/a* '
+ echo --exclude '/bin/a*'
--exclude /bin/a*
+ al tar --preserve-permissions --create --exclude '/bin/a*' --file tar.tar /bin
tar
--preserve-permissions
--create
--exclude
/bin/a*
--file
tar.tar
/bin

请注意,这一次,tar( al) 准确地看到/bin/a*而不是'/bin/a*'


al您可以在 C 或 shell 中简单地编写:

for arg; do echo "$arg"; done

#include <stdio.h>
int main(int argc, char **argv)
{
    while (*++argv != 0)
        puts(*argv);
    return 0;
}

在 MacOS X 10.7 上执行的测试/bin/ksh,其标识为:

$ ksh --version
  version         sh (AT&T Research) 1993-12-28 s+
$
于 2011-08-13T13:44:09.490 回答