动态创建的 'zip' 命令未正确排除目录
Dynamically-created 'zip' command not excluding directories properly
我是一个实用程序的作者,它使使用 zip
压缩项目变得更容易一些,尤其是当您必须定期压缩时,例如更新提交到应用程序商店的项目(如 Chrome 的网上商店)。
我正在尝试进行一些改进,但 运行 遇到了一个问题,如下所述。
快速概览
我的实用程序的命令格式类似于 command OPTIONS DEST DIR1 {DIR2 DIR3 DIR4...}
。它由 运行ning zip -r DEST.zip DIR1
工作;一个相当简单的过程。然而,我的实用程序的好处是能够使用预先确定的文件(想想 .gitignore
)来忽略特定的 files/directories 或匹配模式的 files/directories。
这很简单——如果 "ignorefile" 存在于目标目录(DIR1、DIR2、DIR3 等)中,我的实用程序将使用模式 [=] 添加排除项到 zip -r DEST.zip DIR1
命令16=] 或 -x some_dir/*
.
问题
然而,我 运行 遇到目录排除问题,我不太明白为什么(这可能是因为我仍然是 sh 新手) .我将 运行 通过一些示例:
假设我想忽略项目目录中的两件事:.git/*
和 .gitignore
。 运行 command foo.zip project_dir
构建以下命令:
zip -r foo.zip project -x project/.git/\* -x project/.gitignore
哇哦!成功!嗯...不完全是。
在此示例中,.gitignore
未添加到压缩输出文件 foo.zip
。目录 .git/*
及其所有子目录(和文件) 添加到压缩输出文件中。
手动运行命令:
zip -r foo.zip project_dir -x project/.git/\* -x project/.gitignore
当然,按预期工作,所以我很自然地很困惑为什么我的相同但动态构建的命令不起作用。
尝试的解决方案
我尝试了几种不同的方法来解决这个问题,但都无济于事:
从命令中删除-x project/.git/\*
,而是在该目录中添加每个子目录和文件,例如-x project/.git/config -x project/.git/HEAD
等(包括子目录的子目录)
删除星号前的反斜杠,以便命令中生成的排除选项为 -x project/.git/*
焦虑地用头敲击键盘(我真的很惊讶这不起作用,它通常起作用)
一些笔记
我的实用程序使用 /bin/sh
;我宁愿保持这种方式以获得最大的兼容性。
我知道 git archive
功能——我在上面的例子中使用 .git/*
和 .gitignore
只是作为一个例子;我的实用程序不依赖于 git,也不专门用于 git 存储库的项目。
我怀疑问题出在对生成的命令的评估中,因为你说直接执行相同的命令是正确的。
正如评论区所说,我想你已经找到了正确的解决方案。发生这种情况是因为如果您直接 运行 该变量,则可以直接扩展诸如 globs 之类的东西,而不是传递给命令。论据可能会乱七八糟,视情况而定。
是的,在那种情况下:
eval $COMMAND
是必经之路。
我是一个实用程序的作者,它使使用 zip
压缩项目变得更容易一些,尤其是当您必须定期压缩时,例如更新提交到应用程序商店的项目(如 Chrome 的网上商店)。
我正在尝试进行一些改进,但 运行 遇到了一个问题,如下所述。
快速概览
我的实用程序的命令格式类似于 command OPTIONS DEST DIR1 {DIR2 DIR3 DIR4...}
。它由 运行ning zip -r DEST.zip DIR1
工作;一个相当简单的过程。然而,我的实用程序的好处是能够使用预先确定的文件(想想 .gitignore
)来忽略特定的 files/directories 或匹配模式的 files/directories。
这很简单——如果 "ignorefile" 存在于目标目录(DIR1、DIR2、DIR3 等)中,我的实用程序将使用模式 [=] 添加排除项到 zip -r DEST.zip DIR1
命令16=] 或 -x some_dir/*
.
问题
然而,我 运行 遇到目录排除问题,我不太明白为什么(这可能是因为我仍然是 sh 新手) .我将 运行 通过一些示例:
假设我想忽略项目目录中的两件事:.git/*
和 .gitignore
。 运行 command foo.zip project_dir
构建以下命令:
zip -r foo.zip project -x project/.git/\* -x project/.gitignore
哇哦!成功!嗯...不完全是。
在此示例中,.gitignore
未添加到压缩输出文件 foo.zip
。目录 .git/*
及其所有子目录(和文件) 添加到压缩输出文件中。
手动运行命令:
zip -r foo.zip project_dir -x project/.git/\* -x project/.gitignore
当然,按预期工作,所以我很自然地很困惑为什么我的相同但动态构建的命令不起作用。
尝试的解决方案
我尝试了几种不同的方法来解决这个问题,但都无济于事:
从命令中删除
-x project/.git/\*
,而是在该目录中添加每个子目录和文件,例如-x project/.git/config -x project/.git/HEAD
等(包括子目录的子目录)删除星号前的反斜杠,以便命令中生成的排除选项为
-x project/.git/*
焦虑地用头敲击键盘(我真的很惊讶这不起作用,它通常起作用)
一些笔记
我的实用程序使用
/bin/sh
;我宁愿保持这种方式以获得最大的兼容性。我知道
git archive
功能——我在上面的例子中使用.git/*
和.gitignore
只是作为一个例子;我的实用程序不依赖于 git,也不专门用于 git 存储库的项目。
我怀疑问题出在对生成的命令的评估中,因为你说直接执行相同的命令是正确的。
正如评论区所说,我想你已经找到了正确的解决方案。发生这种情况是因为如果您直接 运行 该变量,则可以直接扩展诸如 globs 之类的东西,而不是传递给命令。论据可能会乱七八糟,视情况而定。
是的,在那种情况下:
eval $COMMAND
是必经之路。