Using shasum along with compression in MAC OS-X [duplicate] - macos

I can run:
echo "asdf" > testfile
tar czf a.tar.gz testfile
tar czf b.tar.gz testfile
md5sum *.tar.gz
and it turns out that a.tar.gz and b.tar.gz have different md5 hashes. It's true that they're different, which diff -u a.tar.gz b.tar.gz confirms.
What additional flags do I need to pass in to tar so that its output is consistent over time with the same input?

tar czf outfile infiles is equivalent to
tar cf - infiles | gzip > outfile
The reason the files are different is because gzip puts its input filename and modification time into the compressed file. When the input is a pipe, it uses an empty string as the filename and the current time as the modification time.
But it also has a --no-name option, which tells it not to put the name and timestamp into the file. So if you write the expanded command explicitly, instead of using the -z option to tar, you can make use of this option.
tar cf - testfile | gzip --no-name > a.tar.gz
tar cf - testfile | gzip --no-name > b.tar.gz
I tested this on OS X 10.6.8 and it works.

For MacOS:
In man tar we can look at --options section and there we will find !timestamp option, which will exclude timestamp from our gzip archive. Usage:
tar --options '!timestamp' -cvzf archive.tgz filename
It will produce same md5 sum for same files with same names

Related

Unpack .tar.gz and modify result files

I wanted to write a bash script that will unpack .tar.gz archives and for each result file it will set an additional attribute with the name of the original archive. Just to know what the origin is of the unpacked file.
I tried to store the inside files in an array and then for-loop them.
for archive in "$1"*.tar.gz; do
if [ -f "${archive}" ]
then
readarray -t fileNames < <(tar tzf "$archive")
for file in "${fileNames}"; do
echo "${file}"
tar xvzf "${archive}" -C "$1" --no-wildcards "${file}" &&
attr -s package -V "${archive}" "${file}"
done
fi
done
The result is that only one file is extracted and no extra attribute is set.
#! /bin/bash
for archive in "$1"*.tar.gz; do
if [ -f "${archive}" ] ; then
# Unpack the archive into subfolder $1
tar xvf "$archive" -C "$1"
# Assign attributes
tar tf "$archive" | (cd "$1" && xargs -t -L1 attr -s package -V "$archive" )
fi
done
Notes:
Script is unpacking each archive with a single 'tar'. This is more efficient than unpacing one file at a time. It also avoid issues with unpacking folders, which will lead to unnecessary repeated work.
Script is using 'attr'. Will be better to use 'setfattr', if supported on target file system to set attributes on multiple files with a few calls (using xargs, with multiple files per command)
It is not clear what is the structure of the output folder. From the question, it looks as if all archives will be placed into the same folder "$1". The following solution assume that this is the intended behavior, and that each archive will have distinct file names. If each archive is to be placed into different sub folder, it will be easier/more efficient to implement.

Extract from tar file to different directory in Bash

I'm new to Bash and trying to unzip a tarball. Code so far:
#!/bin/bash
tar="/cdrom/java/jre1-8u181-x64tar.gz"
# Unpack tarball
gunzip < $tar | tar xf -
This extracts the archive in current directory. How can I specify a location?
Using Solaris 10, Bash 3.2.51
This works pretty well everywhere - including Solaris, and as you only change directory in a sub-shell, it doesn't affect your location in the current session:
gunzip < $tar | ( cd /some/where/else && tar xf -)
To extract the file to a specific directory
gunzip < $tar | tar -xf - --directory /path/to/extract/to
or
gunzip < $tar | tar -xf - -C /path/to/extract/to
As you wrote your command is unpacking in the current directory:
gunzip < $tar | tar xf -
Add the "-C" option to give it an alternate target directory:
gunzip < $tar | tar xf - -C /another/target/directory
Note that the Solaris tar does not understand the --directory option.
See the Solaris tar manpage.
Just for the sake of completeness if you have Gnu-Tar (which is available for Solaris too) you can use this simpler command (which unzips and unpacks in one go):
tar xzf $tar -C /another/target/directory
On a side note:
many people use a leading dash for the tar command parameters. That is redundant.
See the answers to this question if you are interested.
The -xf part of tar means to extract into the "f" file. try changing the tar command to something like
Edit
...| tar -xf - -C /path/to/your/desired/result/folder
sorry, #pitseeker is correct. The -C option tells tar to change directory then do the extract

combine multiple gzip compressed files in a tar file

I have a really large tar file containing many gzip files. I would like to combine all the gzip files into one gzip file and place in another directory. To view the contents of the tar file I use:
tar -zxvf Big.tar
which gives:
Big/FileA.gz
Big/FileB.gz
Big/FileC.gz
Big/FileD.gz
To normally combine multiple gzip files I would move to that directory and use:
cat FileA.gz FileB.gz FileC.gz FileD.gz > BigFile.gz
However the BigFile.gz would remain in that directory. I'm just not sure how to do this within a tar file and how to have the combined file be written to another directory.
With GNU tar, you can do:
tar -Oxf Big.tar --wildcards 'Big/*.gz' > /tmp/your_file.gz
With OS X tar, you have to list the files individually:
tar -Oxf Big.tar Big/FileA.gz Big/FileB.gz > /tmp/your_file.gz
The salient feature in both is -O, which writes the files to stdout.
Here's an example transcript on a GNU system:
$ pwd
/home/me
$ tar tf Big.tar
Big/
Big/foo.txt.gz
Big/bar.txt.gz
$ tar -Oxf Big.tar --wildcards 'Big/*.gz' > /tmp/your_file.gz
$ zcat /tmp/your_file.gz
This is the contents of foo.txt
This is the contents of bar.txt
Using tar and assuming folder Big has FileA.gz, FileB.gz, etc.:
tar -czv -f /path/to/final/BigFile.gz -C Big .

How to untar all tar files in current directory using Putty

How can I untar all tar files in one command using Putty.
I Tried the following but its not un-tarring (all files start with alcatelS*)
tar -xfv alcatelS*.tar
It is not working i don't get no errors and it is not un-tarring.
Thank you,
-xfv is wrong since v is being referred as the file instead. Also, tar can't accept multiple files to extract at once. Perhaps -M can be used but it's a little stubborn when I tried it. Also, it would be difficult to pass multiple arguments that were extracted from pathname expansion i.e. you have to do tar -xvM -f file1.tar -f file2.tar.
Do this instead:
for F in alcatelS*.tar; do
tar -xvf "$F"
done
Or one-line: (EDIT: Sorry that -is- a "one"-liner but I find that not technically a real one-liner, just a condensed one so I should haven't referred to that as a one-liner. Avoid the wrong convention.)
for F in alcatelS*.tar; do tar -xvf "$F"; done
You can use following command for extract all tar.gz files in directory in unix
find . -name 'alcatelS*.tar.gz' -exec tar -xvf {} \;
Following is my favorite way to untar multiple tar files:
ls *tar.gz | xargs -n1 tar xvf
Can be done in one line:
cat *.tar | tar -xvf - -i

Why does my shell script create a file named pipe?

I have this simple set up:
pwd
/home/abc/pipetest
ls
mydir pipetest.sh
Now I do:
./pipetest.sh
And then I get
ls
file.tar.bz2 mydir pipe pipetest.sh
My question is: Why did the file named pipe get created? It contains some characters that could not be seen using vi. What's going on?
pipetest.sh contains:
#!/bin/sh
directory_name=mydir
tar cf pipe $directory_name
bzip2 -c < pipe > file.tar.bz2
tar cf pipe $directory_name writes the tar file to a file named pipe.
What you want to do is using the actual pipe:
tar c $directory_name | bzip2 > file.tar.bz2
Or simply use
tar cjf file.tar.bz2 $directory_name
tar -cf pipe
creates a tar file named "pipe" in the current directory.

Resources