I want to set the file modification times of files stored in a zip file.
I think I could work out how to unzip the files to a temporary location, hit
them with touch to modify their timestamps, and then store them back in a
new zip file that overwrites the original. I then have to clean-up the
temporary files. Obviously my method would involve a series of commands.
Okay, can any sneaky shell gurus think of a single command line that unzips
the files, pipes them through touch, and then pipes the results to zip to
replace the original archive?
Muz.
> Murray R. Van Luyn. wrote:
>
>> Okay, can any sneaky shell gurus think of a single command
>> line that unzips the files, pipes them through touch, and then
>> pipes the results to zip to replace the original archive?
>
> What is the reason it must be a oneliner? Just curious.
Good question. If, for some weird reason, there can't be
any newlines within the script, he can use semi-colons instead.
line 1 ; line 2 ; line 3 ...
Sid
Hi houghi,
That I wish to perform the task as a 'one liner' is purely of academic
interest. I'm just curious about how the piping mechanism works, and whether
it can be used to pass whole files between programs.
Muz.
Hi Sidney,
Ah, that's one solution I hadn't thought of, but is interesting to note.
Thanks for that useful tip.
Yeah, it's really the elegance of piping whole files that I'm most curious
about.
Muz.
I can relate to that, Murray, but I think you better choose
something other than touch for your experiments, because
I don't think it takes piped input.
Here's a couple of relevant scripts you might find enlightening.
They are used to send a bunch of files to a remoted machine
using netcat (nc). "1234" is the port number:
Send tar cfp - /some/dir | compress -c | nc -w 3 othermachine 1234
Receive nc -l -p 1234 | uncompress -c | tar xvfp -
Sid
Hi Sidney,
Thanks very much for the good examples of piping files that you posted. Yes,
that's the sort of thing I was hoping to achieve, yet with different
commands.
Hmm...I've played with the -p option for unzip and the - option for zip long
enough tonight, and I'm no closer to the objective. If it's not immediately
obvious to anyone what I'm trying to achieve, then I might suggest that it's
not worth anyone particularly bothering with. I'll just use the conventional
series of commands solution instead of holding out for an elegant and
unnecessary 'one liner'.
Thanks again for all suggestions and feedback, guy's. Very much appreciated!
Muz.
> Hmm...I've played with the -p option for unzip and the - option for zip long
> enough tonight, and I'm no closer to the objective. If it's not immediately
> obvious to anyone what I'm trying to achieve, then I might suggest that it's
> not worth anyone particularly bothering with. I'll just use the conventional
> series of commands solution instead of holding out for an elegant and
> unnecessary 'one liner'.
>
The touch command is for "files", then you need files to touch them.
You can think about a substitution of the string time of the file transiting across the pipe,
but the job is complex, unless you find one tool done to this purpose.
If you already do the task, you know how.
Put these commands in a function and all is solved.
For example:
rezip(){
[ $1 ]&&[ -e $1]||return
#here you list your comands...
mkdir tmp
cd tmp
unzip $1
touch files
rezip
rename zip file
remove tmp dir
if all is ok remove old zipfile
etc...
}
#Now you have a very small and elegant one liner:
rezip file.zip
#if you prefer create a micro script instead a function, no problem...
You can do things as that to all your repetitive and tediously tasks.
you need to differentiate between the "contents of files" and the and
the information kept in the inode/disk structures associated with the
file names (mtime,ctime....). "touch" manipulates the later, not the
former.
pipes can pass the entire contents of a file, but the time stamps
aren't part of that information. that being the case, "touch"ing the
piped contents won't alter the dates associate with the files
Hi Mop2,
Well, I've definitely struck the right newsgroup for this one. Thanks very
much for providing your solution to my query, mop2..
Golly, I know next to nothing about Unix shell commands. I'm just trying to
get a zipfile download preparation script in PHP to work on my website. The
idea is just to touch the payload timestamps of my zipfile downloads, as a
means of having then uniquely traceable to individual microcontroller
software purchasers. I've lost tens of thousands of dollars in sales as a
result of people uploading my code to 'free' software download sites. It's
next to impossible to get software removed from circulation once it's there,
but if I can trace uploaded files to an individual abuser, then maybe
there's a shot at claiming compensation for the losses.
> rezip(){
> [ $1 ]&&[ -e $1]||return
I'm fascinated by this snippet, mop2. What sort of language is that function
written in? I may have to resort to some form of function loaded shell
script for my command sequence, as I'm having trouble getting PHP's exec()
function to run 'zip' consistently. It might be handy if I could fire-off a
shell script with something like exec("rezip file.zip");
Anyway, thanks very much for taking the time to answer my query, mop2. This
is certainly a very gentlemanly and helpful newsgroup.
Muz.
Hi OldSchool,
Yes, I'm starting to see the difference. Had I persevered with zip and
unzip, then I might have managed to pipe decompressed files straight back
into zip for re-compression (?). Touch appears not to be a suitable
candidate for interstitial processing, however. Never mind. I can quite
happily go the multi-statement command sequence route instead.
Thanks also for your perspective of the situation, OldSchool. I'm very
pleased to have found a very helpful group with lots of good ideas to share.
Muz.
>> rezip(){
>> [ $1 ]&&[ -e $1]||return
>
> I'm fascinated by this snippet, mop2. What sort of language is that function
> written in? I may have to resort to some form of function loaded shell
> script for my command sequence, as I'm having trouble getting PHP's exec()
> function to run 'zip' consistently. It might be handy if I could fire-off a
> shell script with something like exec("rezip file.zip");
That is a shell function.
Now what your need is more clear.
Well, for dating your files, your case is more simple. Your files can be stored
in a private directory and a script touch and zip them to a public directory, so:
####your script (for zipping) is just:
touch /files/tozip/yourprg-1.0.0/*
/usr/bin/zip < /files/tozip/yourprg-1.0.0 >/your/download/area/yourprg-1.0.0.zip
######
You only need control the condition of only one download per time stamp.
Your php interpreter can run a shell script (I think), as above, or perhaps just:
exec("line 1; line 2");
Sorry, I don't know nothing about php.
That's part of a shell function, written in POSIX shell language. It
could be bash or ksh or one of several other shells.
The function returns if the first argument is empty or isn't the name of
an existing file or directory. $1 should be in double quotes in case it
contains whitespace.
Hi Mop2,
Don't worry Mop2, I don't know nothing about PHP either. :-) The searchable
documentation and examples are fabulous, however, and inspired cut & paste
seems to get one a very long way.
Hmm...what I really need is to write a tiny shell script that can
iteratively work through a set of zip files, expanding, touching and
re-compressing the contents of each. The idea would be to call it with a PHP
command like exec("touchzipfilepayloads zipfile1.zip zipfile2.zip
zipfile3.zip");
I'll have to search for a simple shell script example that illustrates the
control structure required to process a command line specified list of zip
files. Once I have that, it will be a simple matter of substituting my
unzip, touch, zip, rm command sequence.
Gee, I hope the shell program 'zip' works a little better for me when called
from a shell script. Otherwise, I'm no better off. Golly, isn't it a
stimulating exercise, to battle through the maze of possible solutions and
dead-ends, and finally arrive at working result? I'm having too much fun!
Muz.
Does this look rational to anyone?
#!/bin/sh
while [ $# -ge 1 ]; do
unzip ./Secure/$1 -d ./Secure/Temp > /dev/null 2>&1
touch ./Secure/Temp/* > /dev/null 2>&1
zip -j ./Secure/$1 ./Secure/Temp/* > /dev/null 2>&1
rm ./Secure/Temp/* > /dev/null 2>&1
shift
done
exit 0
Called with something like:
./touchzipfilepayloads zipfile1.zip zipfile2.zip zipfile3.zip
Muz.
> "Murray R. Van Luyn." <va...@email.address> wrote in message
> news:vsednRKwVb5_NqDW...@westnet.com.au...
>
>> "mop2" <inv...@mail.address> wrote in message
>> news:op.u5tpileof8ly3v@k7...
>>
>>> On Thu, 31 Dec 2009 19:30:10 -0200, Murray R. Van Luyn.
>>> <va...@email.address> wrote:
>>>
>>>> Golly, I know next to nothing about Unix shell commands. I'm
>>>> just trying to get a zipfile download preparation script in
>>>> PHP to work on my website. The idea is just to touch the
>>>> payload timestamps of my zipfile downloads, as a means of
>>>> having then uniquely traceable to individual microcontroller
>>>> software purchasers.
>>>
>>>
>>>>> rezip(){ [ $1 ]&&[ -e $1]||return
>>>>
>>>> I'm fascinated by this snippet, mop2. What sort of language
>>>> is that function written in? I may have to resort to
>>>> some form of function loaded shell script for my command
>>>> sequence, as I'm having trouble getting PHP's exec()
>>>> function to run 'zip' consistently. It might be handy
>>>> if I could fire-off a shell script with something like
>>>> exec("rezip file.zip");
>>>
>>> That is a shell function Now what your need is more clear .
Looks like it would probably work. I don't know zip very
well.
(How come you are using what is essentially a Windows tool?
Why not tar?)
(> /dev/null 2>&1 instead of that, I use &> /dev/null.)
The thing to do is make some throwaway zip files and the
necessary dirs and test it.
Sid
Hi Sidney,
Yes, the code that I make available to customers is usually downloaded by
Windows users. I've always distributed zip files that I create with WinZip,
so I thought using the Unix zip command would give me the best compatibility
with those.
Okay, I've tried it out and am starting to get a handle on the problem. When
initiated with PHP's exec() function I couldn't get any textural feedback
from running the zip command. When I ran zip in a shell script I was able to
redirect the results of the execution attempt to a file for post-mortem
analysis. The output reads "./touchzipfilepayloads: line 6: zip: command not
found". I now have this important clue as to what's going wrong. Once in a
while the OS can find the zip executable, though most frequently it fails
to.
I'll see what my ISP has to say about the apparent, predominately
un-locatable zip executable. They're not known for their fabulous customer
service, so I fear this may be where the current avenue of exploration ends.
I'll try to let you all know what happens.
Muz.
Any reason you don't cd into Secure?
Zip will create "Temp" if it doesn't exist, but the second
time you run touchzipfilepayloads it will exist. Consider
adding a check that you can rwx the Temp dir if it exists.
If there is a chance that the original zipfiles contained
subdirectories, should the final zip also use the -r option?
You probably should be quoting all instances of $1 just in case.
Throwing away all error messages?
Using the -j option will flatten all directory structure.
If the original zipfile contained "a" and "b/c", the final
zipfile will contain "a" and "c", no indication of directory "b".
Duplicate names in subdirs will be a possible problem.
Actually, as you reuse the zipfile, i.e. don't remove or rename it,
the final zipfile in my above example would probably contain an
updated "a", a new "c", and an unchanged "b/c".
Does your PHP installation have the zip functions? It is not as
simple as a script, but it will get the job done if your hosting
company won't install a zip executable.
<snip>
--
Ben.
>>> "Murray R. Van Luyn." <va...@email.address> wrote in message
>>> #!/bin/sh
>>>
>>> while [ $# -ge 1 ]; do
>>> unzip ./Secure/$1 -d ./Secure/Temp > /dev/null 2>&1
>>> touch ./Secure/Temp/* > /dev/null 2>&1
>>> zip -j ./Secure/$1 ./Secure/Temp/* > /dev/null 2>&1
>>> rm ./Secure/Temp/* > /dev/null 2>&1
>>> shift
>>> done
>>>
>>> exit 0
> initiated with PHP's exec() function I couldn't get any textural feedback
You can try, in the while loop:
while
here
remove
the redirections
done >>./Secure/touchzipfilepayloads.log 2>&1
In your browser you open an other window to follow (and refresh the view) rezip.log
Perhaps be more dynamic, as first try, speak with the servers.
If you can upload your zip script, possibly you can upload others.
For example:
#!/bin/sh
{
echo ----------- find zip
which zip ||
whereis zip ||
find /usr -name zip
echo -----------
} >>./Secure/touchzipfilepayloads.log 2>&1
The server will answer in the log file and, if zip is found,
you can try supply the absolute path to it in your zip script.
This can additionally reduce the reply time when running the script.
Of course, even if it was not found, the zip command can be available in an
absolutely non predictable place.
Exactly, and its dependency is very simple:
$ which zip
/usr/bin/zip
$ ldd /usr/bin/zip
linux-gate.so.1 => (0xb7713000)
libbz2.so.1 => /lib/libbz2.so.1 (0xb76f2000)
libc.so.6 => /lib/libc.so.6 (0xb7592000)
/lib/ld-linux.so.2 (0xb7714000)
Well, in principle, the same dir of the script seems good, since
libraries are in the correct place,then zip in the script will be just
./zip
or
${0%/*}/zip
I don't know if the ISP's server isn't a linux machine (a *bsd, for example)
this simple approach is applicable.