Reputation: 879
I need to create a shell script wherein I will unzip a password protected zip file. I know the password, and need to automate the unzip process.
How can I achieve this using Unix shell scripting?
Upvotes: 86
Views: 252621
Reputation: 53245
This also answers the question, "How do you extract a .zip file into a subdirectory or nested subdirectories, automatically creating them if they don't exist?"
unar
(un-archive) works well. So, you can use unar
or unzip
, like this. Note that it is a lowercase -p
with unar
, but it is an uppercase -P
with unzip
:
# (my preference) Unzip all contents of myfile.zip into a directory it creates
# which it names `myfile`, after the `myfile.zip` file itself
unar -p my_password path/to/myfile.zip
# Unzip all contents of myfile.zip into a directory it creates which is named
# `some_other_dir/myfile`, where `some_other_dir` is a name you choose, and
# `myfile` is a directory it automatically names based on the `myfile.zip` zip
# file.
# - Note that neither `some_other_dir` *nor* directory `myfile` have to exist
# for this to work. If they don't exist, `unar` creates them automatically
# for you!
unar -p my_password path/to/myfile.zip -o some_other_dir
# Unzip all contents of myfile.zip directly into the current directory, rather
# than into a sub-directory
unzip -P my_password path/to/myfile.zip
# Unzip myfile.zip into dir myfile/
unzip -P my_password -d myfile path/to/myfile.zip
I learned about the -d some/directory
option with unzip
here: How to extract a zip file to a specific folder?.
I prefer unar
over unzip
simply because unar
automatically unzips the contents into a folder by the same name as the file, which is convenient and prevents me from misplacing the extracted files. It also has the -o some_other_dir
option, as explained above, which is really nice to extract a ton of zip files into their own unique folders inside some_other_dir
.
find
, xargs
, and unar
If you're unzipping hundreds or even thousands of files at once, you can parallelize the operation with xargs
to spawn one process per CPU core you have (as shown by nproc
) until all files are done. This makes it much much faster! Here is how:
# Unzip many password-protected files at once, assuming they all have the same
# password
# GENERALLY WHAT I USE:
# - Note: `-maxdepth 1` causes this to only unzip *top-level* .zip files within
# your current directory
time find . -maxdepth 1 -type f -iname "*.zip" -print0 | xargs -0 -I{} \
-n 1 -P $(nproc) unar -p my_password -f {}
# Or, remove `-maxdepth 1` to unzip *all* .zip files, recursively, which are
# found within your current directory or lower.
time find . -type f -iname "*.zip" -print0 | xargs -0 -I{} \
-n 1 -P $(nproc) unar -p my_password -f {}
# You can also output ALL extracted folders into their own unique output dir
# named `some_other_dir`, with the `-o` flag.
# - `some_other_dir` does *not* have to exist before-hand!--it will
# automatically create it for you!
time find . -maxdepth 1 -type f -iname "*.zip" -print0 | xargs -0 -I{} \
-n 1 -P $(nproc) unar -p my_password -f {} -o some_other_dir
# or (without `-maxdepth 1`)
time find . -type f -iname "*.zip" -print0 | xargs -0 -I{} \
-n 1 -P $(nproc) unar -p my_password -f {} -o some_other_dir
# ALSO VERY USEFUL!
# To extract all .zip files at path `some_dir/*.zip` into dir
# `some_dir/some_other_dir/*/[all files]`, you must do this:
# 1. Pass `some_dir` to `find`, and
# 2. Pass `-o some_dir/some_other_dir` to `unar`:
time find some_dir -maxdepth 1 -type f -iname "*.zip" -print0 | xargs -0 -I{} \
-n 1 -P $(nproc) unar -p my_password -f {} -o some_dir/some_other_dir
# or (without `-maxdepth 1`)
time find some_dir -type f -iname "*.zip" -print0 | xargs -0 -I{} \
-n 1 -P $(nproc) unar -p my_password -f {} -o some_dir/some_other_dir
The first command above just unzipped 93 similar ~2 MB files for me in 1.084 seconds. That's 1.084 sec/93 files = 0.012 sec per file. nproc
shows that I have 20 cores.
If I run it single-threaded/single-process, all in serial instead of parallel, by changing -P $(nproc)
to -P 1
instead, I end up with this command (time find . -type f -iname "*.zip" -print0 | xargs -0 -I{} -n 1 -P $(nproc) unar -p my_password -f {}
) which takes 9.246 sec instead. That's 9.246 sec/93 files = 0.099 sec per file, which is 0.099/0.012 = 8.25x slower.
Just for fun, I also ran a serial unzip command, time unzip -o -P my_password '*.zip'
(note that -o
is dangerous and means "overwrite" existing files), as a speed comparison. It took 8.196 sec on my 93 files, also much slower than the multi-process unar
command above which took 1.084 seconds, and even worse, it created a massive, unusable mess of extracted files piled up on top of each other everywhere in the same directory.
So, use the parallel forms above where I pipe find
to xargs
and unar
.
unzip -P my_password path/to/myfile.zip
in the main answer here.find
to xargs
and unar
for parallel extracting operations.Upvotes: 1
Reputation: 2217
After banging my head on the wall many times, here's my two-cent.
If the password you received contains special characters such as $ ; \ etc, your shell terminal might interpret it as part of the shell special symbol and not exactly the password string that you intended it to be.
Solution is simple, enclosed the password in a single quote!
7z x [yourzipfile] -P'your$pass;word!'
I hope this help save your time when suddenly it seems like your zip/unzip encrypted password did not work!
Upvotes: 5
Reputation: 201
Please follow bellow instruction, i have solved same problem by following these steps.
sudo apt install p7zip-full
7z x example.zip
Visit the following URL: For more details
Upvotes: 5
Reputation: 177
To unzip multiple password protected files, this command WILL NOT WORK
unzip -P PASSWORD *.zip
To make it work, you need to include the *.zip
in quotes because whenever you use a wildcard (*), the shell itself will expand that and pass the results to the program. This is because, unlike most programs in UNIX, unzip cannot take more than one file at a time.
Read more here https://chrisjean.com/unzip-multiple-files-from-linux-command-line/.
Therefore, to unzip multiple protected files, use this
unzip -P PASSWORD '*.zip'
Upvotes: 13
Reputation: 3582
I ran into problem using unzip
saying need PK compat. v5.1 (can do v4.6)
.
Installed p7zip
instead and unzipped using following command:
7z x archive.zip -ppassword
Upvotes: 28
Reputation: 2767
In Ubuntu, I've to install 7zip (7z) archive tool using following command:
sudo apt-get install p7zip-full
Then, you can use Ubuntu's default Archive Manager to unzip the password protected zip files
Upvotes: 42
Reputation: 10450
unzip -P your-password zipfile.zip
-P password
use password to decrypt encrypted zipfile entries (if any). THIS IS INSECURE! Many multi-user operating systems provide ways for any user to see the current command line of any other user; even on stand-alone systems there is always the threat of over-the-shoulder peeking. Storing the plaintext password as part of a command line in an automated script is even worse. Whenever possible, use the non-echoing, interactive prompt to enter passwords. (And where security is truly important, use strong encryption such as Pretty Good Privacy instead of the relatively weak encryption provided by standard zipfile utilities.)
Upvotes: 111