使用 zip 命令的脚本不能使用通配符

使用 zip 命令的脚本不能使用通配符

我创建了一个 bash shell 脚本来压缩与模式匹配的所有文件,如下所示:

#!/bin/bash
zip $1 $2

当我使用 运行上述脚本时./myScript.sh myzip test*,只有一个以该名称开头的文件测试即使我的目录有 2 个与该模式匹配的文件(test1 和 test2),它也会添加到 zip 中。

如果我zip直接从 shell 运行该命令,它会按预期工作并添加两者测试1测试2到 myzip。但是当我使用脚本来执行此操作时,它仅添加 1 个文件。

我缺少什么?

答案1

当你像这样调用你的脚本时

./myScript.sh myzip test*

您为脚本提供参数myziptest1和。在实际调用脚本之前,shelltest2会从模式中扩展最后两个参数。请注意将在 中可用,但您的脚本永远不会使用。test*test2$3$3

您可以通过两种方式解决这个问题:

  1. 从参数列表中选取存档名称,然后移动列表以从位置参数列表中删除存档名称,最后"$@"在调用中使用(剩余的参数)zip

    #!/bin/sh
    
    archive=$1
    shift
    
    zip "$archive" "$@"
    

    由于所有变量都被引用,这还意味着您可以使用包含空格等的文件名。

    对于bash,这可能会写得更难读,如

    #!/bin/bash
    
    zip "$1" "${@:2}"
    
  2. zip实用程序知道如何扩展 shell 通配模式本身。使用这个事实给脚本一个图案而不是文件名列表:

    #!/bin/sh
    
    zip "$1" "$2"
    

    这个脚本应该被称为

    ./myScript.sh myzip 'test*'
    

    引用test*会阻止 shell 扩展模式(这就是我们所要的)依靠在第一种选择中)。

相关内容