Create an empty directory structure that exactly duplicates an existing set of directories, but without any of the files from the original directory structure.
#Linux #DFIR #CommandLine #Trivia
Chiasm likes this.
Hal Pomeranz reshared this.
Create an empty directory structure that exactly duplicates an existing set of directories, but without any of the files from the original directory structure.
#Linux #DFIR #CommandLine #Trivia
Chiasm likes this.
Hal Pomeranz reshared this.
D C Ross
in reply to Hal Pomeranz • • •The simplest version would be
$ find . -type d -exec mkdir -p ${dest}{} \;
That will reproduce the directory names, but the ownership and permissions would all be the default so it's not "exactly duplicated". I could mess around with copying the directory instead of creating it, or build a subshell to try to extract the stat information from the original and pass that to mkdir, but there's another way.
First, construct a list of directories which we want to duplicate:
# cd ${SOURCE} ; find . -type d -print0
This will create a list of directories relative to ${SOURCE}, such as ".", "./moresource" and so on. If we gave find an absolute directory to start at, it would try to create a list of absolute paths instead. Now, feed that into a "tar" command to create an archive of all the directories complete with ownership and permissions:
# cd ${SOURCE} ; find . -type d -print0 | xargs -0 tar cf ${OUTPUT} --no-recursion
The "--no-recursion" flag means that tar will include the directory, but none of the files inside of it, which is what we want. The final step is to take that ${OUTPUT} file, copy it to wherever you need it, and run "tar xf' on it. If you're trying to do the whole thing on a single system you can shortcut the whole thing with a pipe:
# cd ${SOURCE} ; find . -type d -print0 | xargs -0 tar cf - --no-recursion | tar -C ${DESTINATION} -xf -
This removes the ${OUTPUT} file entirely and sends the archive to stdout. A second tar process reads from stdin and unpacks the archived data in the directory ${DESTINATION}.
If you need to recreate the directory structure on a remote server you can still do this in a single line by running the final tar command remotely:
# cd ${SOURCE} ; find . -type d -print0 | xargs -0 tar cf - --no-recursion | ssh ${REMOTE_SERVER} tar -C ${DESTINATION} -xf -
apgarcia
in reply to Hal Pomeranz • • •lamitpObuS
in reply to Hal Pomeranz • • •find "${src_dir}" -type d -printf "./%P\n" \
| cpio -D "${src_dir}" -p "${dest_dir}"
Tim Magee
in reply to Hal Pomeranz • • •Is rsync allowed? Like:
rsync -r --dirs -f'+ **/' -f'- *' FROM/ TO/
silverwizard
in reply to Hal Pomeranz • •like this
Chiasm, Levi Sauerbrei and Dave like this.
Chiasm
in reply to silverwizard • • •silverwizard
in reply to Chiasm • •find src -type d -exec mkdir -p dest/{}
, but a bunch of people already did versions that seem to have solved the minor bugs you'd find in that, so I went with the shitpostHal Pomeranz
in reply to silverwizard • • •silverwizard likes this.
truekonrads
in reply to Hal Pomeranz • • •furicle
in reply to Hal Pomeranz • • •ooh wait! I remember something.... (Scurries away.... Comes back)
Find . -type d -print0 | cpio --null -pvd newDir
Hal Pomeranz
in reply to Hal Pomeranz • • •Yesterday's Linux DFIR command line trivia again saw folks showing up with multiple different approaches.
First is the straightforward "find ... | xargs mkdir" or "find ... -exec mkdir" approach. I'll give @prograhamer credit for being the first to check in with this idea.
cd /orig/directory
find . -type d -print0 | (cd /target/dir; xargs -0 mkdir)
The subshell here lets us take the directory list output from the find command and execute "xargs mkdir" in the target directory location. We use "-print0" and "xargs -0" just in case we're dealing with directory names that contain spaces.
Then @apgarcia went all old-school and suggested "find ... | cpio":
cd /orig/directory
find . -type d | cpio -pdm /target/dir
cpio in passthru mode ("-p") takes a list of paths, one per line (no need for -print0) and copies them to the target destination. "-d" means make directories as needed and "-m" preserves last modified times.
@uriy jumped in with the rsync version:
rsync -r --dirs -f'+ **/' -f'- *' /orig/directory/ /target/directory/
rsync is recursively ("-r") copying the entire directory contents, making directories as needed ("--dirs"). However, the first filter matches just the directory names (paths ending in slash) and the second filter suppresses the other directory contents. The rsync solution has the advantage that you don't need to do a cd command at any point.
Finally, @silverwizard suggested simply doing a "cp -r" and then going back and deleting everything that wasn't a directory. I shall treat this solution with the seriousness it deserves...
#Linux #DFIR #CommandLine #Trivia
apgarcia
in reply to Hal Pomeranz • • •@prograhamer @uriy @silverwizard
just a footnote, it occurred to me that symlinks are often found within directory structures. perhaps an exercise for the reader could be to also copy only those symlinks that point to directories...
Tim Magee
in reply to apgarcia • • •For that case I'd use a slightly modified version of your sweet cpio solution:
cd /PATH/TO/FROM; find . -type d -o -xtype d | cpio -pdm /PATH/TO/DEST
so the test part of the find is now "is a directory, or is a symlink and what it points at is a directory"
AMS
in reply to Hal Pomeranz • • •smoot
in reply to Hal Pomeranz • • •Hm, dont only the last 2 get the permissions & owner/group right?
I couldnt figure out a way in one pass to do both create and chmod/own (having forgotten rsync and never used cpio).
Hal Pomeranz
in reply to smoot • • •smoot
in reply to Hal Pomeranz • • •Hal Pomeranz
in reply to smoot • • •smoot
in reply to Hal Pomeranz • • •