我目前有几个具有不同文件夹结构的应用程序。我正在使用maven
来构建这些应用。我遇到了一些问题。有时主pom.xml
文件位于根目录中,有时则位于子目录中。我只想使用主/最高目录中的主pom.xml
进行maven构建。我从find
运行workspace
命令(下面有更多详细信息)。如何在不依赖文件夹结构的情况下实现这一目标?
Shell命令:
find * -maxdepth 1 -name pom.xml -execdir mvn clean package -Dmaven.test.error.ignore=true -Dmaven.test.failure.ignore=true \;
这适用于此文件夹结构:
workspace
|-- app1
| |-- pom.xml
| |-- abrt.conf
| |-- gpg_keys
| `-- web
| |-- pom.xml
| `-- test.conf
返回:
app1/pom.xml
该命令会返回一些具有此文件夹结构的pom.xml
个文件:
workspace
| |-- pom.xml
| |-- abrt.conf
| |-- gpg_keys
| `-- web
| |-- pom.xml
| `-- test.conf
返回:
web/pom.xml
pom.xml
答案 0 :(得分:2)
因为 find
操作广度优先,除非明确告知不这样做,否则第一个结果将始终是最浅的。因此,您只需要在找到单个POM文件后告诉它退出。
在GNU find
中,有一个 -quit
行动就是为了这个目的:
find。 -name pom.xml \
 -execdir mvn clean package -Dmaven.test.error.ignore = true -Dmaven.test.failure.ignore = true \; \
 -quit



 如果您不能保证GNU 找到
,但是保证有bash,你可以只读取第一个结果并对其进行操作:
如果IFS = read -r -d''pom_filename< <(find。-name pom.xml -print0);然后
 (cd - “$ {pom_filename%/ *}”&& exec mvn clean package -Dmaven.test.error.ignore = true -Dmaven.test.failure.ignore = true)
 fi



 注意使用 -print0
- 这样我们就可以避免恶意命名的目录(带有换行符)通过在列表中注入额外的名称来实现行为。
现在,让我们考虑一个棘手的案例:
&#xA ;&#XA;<代码> A / pom.xml的&#XA; A /分/的pom.xml&#XA; B / pom.xml的&#XA; B /分/的pom.xml&#XA; 代码>&#xA;&#xA;
如果你想运行两个 A和B,而不是A / sub或B / sub,那么事情会变得更多有趣的是:
&#xA;&#xA; find。 \&#XA; -type d -exec test -e'{} /pom.xml'';' \&#XA; -execdir mvn clean pkg ...';' \&#XA; -prune&#xA;
&#xA;&#xA; 请注意,我们使用 -prune
告诉 find
停止递归到存在 pom.xml
的任何目录,但只有在我们已经在那里运行构建之后。
答案 1 :(得分:0)
如果没有find
(在评论中建议替换为*
),只需执行.
,即可从最高目录列到最低目录。管道到head -1
以获取列表中的第一个。将所有这些放入命令替换($(...)
)以分配变量。改为使用您的变量运行相同的命令。由于您现在可能在文件名中包含/
,因此我们不需要-name
,-maxdepth
或*
。
pomxmlfile="$(find . -name pom.xml | head -1)"
find "$pomxmlfile" -execdir mvn clean package -Dmaven.test.error.ignore=true -Dmaven.test.failure.ignore=true \;
答案 2 :(得分:0)
此行找到具有最短路径的pom.xml
(即最接近目录树顶部的pom)并从其目录中执行mvn
:
find . -name pom.xml | awk '{print length($0) " " $0}' | sort -n | cut -d ' ' -f 2- | head -n 1 | xargs -I {} bash -c 'cd $(dirname {}) && mvn clean package -Dmaven.test.error.ignore=true -Dmaven.test.failure.ignore=true \;'
管道分解:
pom.xml
mvn
文件pom.xml
答案 3 :(得分:0)
我不确定。如果主pom.xml
位于目录a/b/c
中且其他pom.xml
位于a
以外的a/b/c
以下的子目录中,那么主pom.xml
必须有最短的路径字符串。所以在这种情况下,我猜这个命令会调出最接近root的pom.xml
,并且可以从a
,a/b
或a/b/c
执行:
find -name pom.xml | awk 'NR==1 || length() < length(s) { s = $0 } END { print s }'