COPYTREE_BIN/COPYTREE_SHARE does not work as expected
Mikolaj Golub
trociny at FreeBSD.org
Sat Jul 5 12:05:04 UTC 2014
Hi,
It looks like COPYTREE_BIN/COPYTREE_SHARE does not work as it is documented in
bsd.port.mk:
# Example use:
# cd ${WRKSRC}/doc && ${COPYTREE_SHARE} . ${DOCSDIR} "! -name *.bak"
#
# Installs all directories and files from ${WRKSRC}/doc
# to ${DOCSDIR} except sed backup files.
If there is a "*.bak" file in . directory (e.g. test.bak), "*.bak" is
expanded to this name, the condition "! -name *.bak" becomes "! -name test.bak",
and other *.bak files are ignored.
Worse, if there are several "*.bak" files, "*.bak" is expanded to the
list and COPYTREE_SHARE fails.
Below is a test that demonstrates this:
[golub at zhuzha ~/freebsd/ports/test]$ cat Makefile
TESTDIR= /tmp/test_COPYTREE_SHARE
all: test1 test2
test1:
${RM} -rf ${TESTDIR}
${MKDIR} ${TESTDIR}/src/1
${TOUCH} ${TESTDIR}/src/1.bak
${TOUCH} ${TESTDIR}/src/1/1.bak
${TOUCH} ${TESTDIR}/src/1/2.bak
(cd ${TESTDIR}/src && ${COPYTREE_SHARE} . ${TESTDIR}/dst "! -name *.bak")
@echo "=> Listing destination (no *.bak files are expected):"
@${FIND} ${TESTDIR}/dst
@${RM} -rf ${TESTDIR}
test2:
${RM} -rf ${TESTDIR}
${MKDIR} ${TESTDIR}/src
${TOUCH} ${TESTDIR}/src/1.bak
${TOUCH} ${TESTDIR}/src/2.bak
-(cd ${TESTDIR}/src && ${COPYTREE_SHARE} . ${TESTDIR}/dst "! -name *.bak")
@${RM} -rf ${TESTDIR}
.include <bsd.port.mk>
[golub at zhuzha ~/freebsd/ports/test]$ make
/bin/rm -rf /tmp/test_COPYTREE_SHARE
/bin/mkdir -p /tmp/test_COPYTREE_SHARE/src/1
/usr/bin/touch /tmp/test_COPYTREE_SHARE/src/1.bak
/usr/bin/touch /tmp/test_COPYTREE_SHARE/src/1/1.bak
/usr/bin/touch /tmp/test_COPYTREE_SHARE/src/1/2.bak
(cd /tmp/test_COPYTREE_SHARE/src && /bin/sh -c '(/usr/bin/find -d $0 $2 | /usr/bin/cpio -dumpl $1 >/dev/null 2>&1) && /usr/bin/find -d $0 $2 -type d -exec chmod 755 $1/{} \; && /usr/bin/find -d $0 $2 -type f -exec chmod 444 $1/{} \;' -- . /tmp/test_COPYTREE_SHARE/dst "! -name *.bak")
=> Listing destination (no *.bak files are expected):
/tmp/test_COPYTREE_SHARE/dst
/tmp/test_COPYTREE_SHARE/dst/1
/tmp/test_COPYTREE_SHARE/dst/1/2.bak
/bin/rm -rf /tmp/test_COPYTREE_SHARE
/bin/mkdir -p /tmp/test_COPYTREE_SHARE/src
/usr/bin/touch /tmp/test_COPYTREE_SHARE/src/1.bak
/usr/bin/touch /tmp/test_COPYTREE_SHARE/src/2.bak
(cd /tmp/test_COPYTREE_SHARE/src && /bin/sh -c '(/usr/bin/find -d $0 $2 | /usr/bin/cpio -dumpl $1 >/dev/null 2>&1) && /usr/bin/find -d $0 $2 -type d -exec chmod 755 $1/{} \; && /usr/bin/find -d $0 $2 -type f -exec chmod 444 $1/{} \;' -- . /tmp/test_COPYTREE_SHARE/dst "! -name *.bak")
find: 2.bak: unknown primary or operator
find: 2.bak: unknown primary or operator
*** Error code 1 (ignored)
In my case I workarounded this by using -regex instead of -name.
One way to fix this is to disable pathname expansion in the find shell:
-COPYTREE_SHARE= ${SH} -c '(${FIND} -d $$0 $$2 | ${CPIO} -dumpl $$1 >/dev/null \
+COPYTREE_SHARE= ${SH} -fc '(${FIND} -d $$0 $$2 | ${CPIO} -dumpl $$1 >/dev/null \
But then it will break cases like below, when expansion of the first
argumemt is desirable:
${COPYTREE_SHARE} "*" ${TESTDIR}
--
Mikolaj Golub
More information about the freebsd-ports
mailing list