Avoiding unwanted directory while using zip


There are many different ways to compress and collect file on Linux systems. We have several options for doing so: using the command line tools, GUI applications.

However, if we share files with Windows or Mac users, the ZIP file remains the most convenient option. We want to maintain its convenience.

We’ll look at how to organize our files so they aren't cluttered with unnecessary folders. We'll learn some basic file management techniques. These might seem obvious if you're doing them manually, but can get tricky when you're working with scripts.

We'll use the bash shell's built−in push/pop commands to get around that problem.

Zip All the Things with -r

When our friends or colleagues download the ZIP file we send them, we usually wish to preserve the basic folder hierarchy. We can do that by using the zip command's −r option.

Let's say we want to include everything in our twine JS/src/vue folder and everything below it.

~$ ls -R /home/allan/Source/twinejs/src/vue/
codemirror-theme.less directives index.less mixins transitions.less

mouse-scrolling.js mouse-scrolling.less

dom-events.spec.js mount-to.js

That's a lot of files, in three separate directories. If we use `zip` to zip up each directory in the tree, we get this result −

~$ zip -r ~/twine-vue.zip /home/allan/Source/twinejs/src/vue
 updating: home/allan/Source/twinejs/src/vue/ (stored 0%)
   adding: home/allan/Source/twinejs/src/vue/codemirror-theme.less (deflated 73%)
   adding: home/allan/Source/twinejs/src/vue/directives/ (stored 0%)
   adding: home/allan/Source/twinejs/src/vue/directives/mouse-scrolling.less (deflated 37%)
   adding: home/allan/Source/twinejs/src/vue/directives/mouse-scrolling.js (deflated 68%)
   adding: home/allan/Source/twinejs/src/vue/index.less (stored 0%)
   adding: home/allan/Source/twinejs/src/vue/mixins/ (stored 0%)
   adding: home/allan/Source/twinejs/src/vue/mixins/mount-to.js (deflated 31%)
   adding: home/allan/Source/twinejs/src/vue/mixins/dom-events.spec.js (deflated 69%)
   adding: home/allan/Source/twinejs/src/vue/transitions.less (deflated 63%)

We don't want to give him the entire path; then he'd have to walk through several folders to reach the file.

If we had to archive our files manually, we'd be able to go into the directory we wanted to capture (vue) but that would be cumbersome in a shell. If only there was an option or a way to avoid that!

Junk All the Directories with -j

The −J option "junk" the directories of every new files added to the ZIP archive. It's like the basename command: It just keeps the filename of the new files, dropping any directory names from their paths.

Let’s give it a shot, and see if that gets us closer to what we really need.

~$ zip -rj ~/twine-vue.zip /home/a/Source/twinejs/src/vue
   adding: codemirror-theme.less (deflated 73%)
   adding: mouse-scrolling.less (deflated 37%)
   adding: mouse-scrolling.js (deflated 68%)
   adding: index.less (stored 0%)
   adding: mount-to.js (deflated 31%)
   adding: dom-events.spec.js (deflated 69%)
   adding: transitions.less (deflated 63%)

It’s not quite correct. If we unzip this file, it will spill its contents all over our friend‘s Downloads directory. We could use the command line tool “cd” (change directory) instead.

pushd and popd as a Better Kind of cd

By making our scripts less brittle, we can use the pushdir() function from our shell to send us to the directory we wish to be in and keep track of where we started from.

pushd Our Way In

Push d is useful for running scripts from /usr/local/bin. We'll see an example later.

/usr/local/bin$ pushd /home/a/Source/twinejs/src/
~/Source/twinejs/src /usr/local

pushd moves us to the directory we specify, then returns the current working directory. We use it to navigate back to our original location.

We're now in the folder directly above vue and can zip it up with the -r option.

~/Source/twinejs/src$ zip -r ~/twine-vue.zip vue/
   adding: vue/ (stored 0%)
   adding: vue/codemirror-theme.less (deflated 73%)
   adding: vue/directives/ (stored 0%)
   adding: vue/directives/mouse-scrolling.less (deflated 37%)
   adding: vue/directives/mouse-scrolling.js (deflated 68%)
   adding: vue/index.less (stored 0%)
   adding: vue/mixins/ (stored 0%)
   adding: vue/mixins/mount-to.js (deflated 31%)
   adding: vue/mixins/dom-events.spec.js (deflated 69%)
   adding: vue/transitions.less (deflated 63%)

Our ZIP file recipient gets everything nicely organized into one folder when they extract our gift from us.

popd Out Again

When our script needs to return to its original location, we use popdir. We can either do this now or later – no matter where we are in our current working directory, we’ll always end up back at the directory where we started.

~/Source/twinejs/src$ popd

We're back to /usr/local/bin, which is a neat place for us to keep our scripts. Now let's go ahead and run them.


We use a useful shell command to avoid unwanted extra folders in our ZIP archives.

It’ll be a lot easier if we just use a clean method to organize our files.