Unzip über stdin

DasArne

Grünschnabel
Hallo zusammen,
ich habe immer das gleiche Problem:
Source runterladen, auspacken und dann das runtergeladene Paket wegwerfen.
Ich würde gerne einfach direkt auspacken.

Mit Tar geht das ganz einfach:
Hier werden z.B. die Sourcen vom Apache runtergeladen und entpackt
Code:
curl http://artfiles.org/apache.org/httpd/httpd-2.2.14.tar.gz | tar xvzf -

Aber wie sieht das mit einem zip-file aus? unzip hat irgendwie keine Möglichkeit über stdin Daten anzunehmen. Gibt es einen Trick?

Viele Grüße
Arne
 
Hi!

Leider geht das momentan nicht:
man unzip hat gesagt.:
Archives read from standard input are not yet supported
.Leider ist es auch nicht möglich einfach /dev/stdin als Dateinamen anzugeben.
Auch wenn es nicht unbedingt die beste Lösung ist - das Perl-Skript unten erledigt den Job. Du kannst es z.b. unter /usr/local/bin/unzip ablegen, dann fungiert es automatisch als Wrapper für /usr/bin/unzip:
Perl:
#!/usr/bin/perl

use strict;
use warnings;

my($ok, @command)= qw(1 /usr/bin/unzip);

sub usage {
    print STDERR `/usr/bin/unzip -h`;
    print STDERR <<"EOT;";

Anstelle des Dateinamens kann genau ein mal "--" verwendet werden.
In diesem Fall wird die Standard-Eingabe (STDIN) gelesen.
EOT;
    exit shift;
}

for(@ARGV) {
    usage 0 if $_ eq "-h";
    if($_ eq "--") {
        usage -1 unless $ok--;
        my $filename = `whoami`;
        chomp $filename;
        $filename = "/tmp/$filename.". time() .".zip";
        binmode STDIN or die $!;
        open FILE, ">", $filename or die $!;
        binmode FILE or die $!;
        while(my $line = <STDIN>) {
            print FILE $line;
        }
        push @command, $filename;
        close FILE;
    } else {
        push @command, $_;
    }
}

exec @command;
Das schaut dann etwa so aus:
Code:
lenny:~/test$ ls
unzip.pl  picknik-am-wegesrand.txt
lenny:~/test$ su
Passwort: 
lenny:/home/enum/test# ln -s `pwd`/unzip.pl /usr/local/bin/unzip
lenny:/home/enum/test# exit
exit
lenny:~/test$ zip test.zip picknik-am-wegesrand.txt 
  adding: picknik-am-wegesrand.txt (deflated 62%)
lenny:~/test$ ls
unzip.pl  picknik-am-wegesrand.txt  test.zip
lenny:~/test$ rm picknik-am-wegesrand.txt 
rm: reguläre Datei „picknik-am-wegesrand.txt“ entfernen? y
lenny:~/test$ unzip -- < test.zip 
Archive:  /tmp/enum.1265635053.zip
  inflating: picknik-am-wegesrand.txt  
lenny:~/test$ ls
unzip.pl  picknik-am-wegesrand.txt  test.zip
lenny:~/test$
Das Skript kann jetzt genauso wie unzip selbst verwendet werden, inklusive aller Argumente und anstelle eines Dateinamens kann jetzt "--" übergeben werden.
Einziger Nachteil ist das interaktive Benutzereingaben unterdrückt werden wenn wirklich von STDIN gelesen wird (z.B. die Frage nach dem überschreiben von Dateien).

Gruß
Enum
 
@deepthroat:

Klar, File::Temp, vor allem wenn's um Portabilität geht. Doch wir sind im Linux/Unix Forum...
So, genug gerechtfertigt :p - jetzt mal im Ernst:
Ich wollte das ursprünglich als Shellskript regeln, bin aber am "binmode" gescheitert und habe das einfach stumpf in Perl übersetzt.
Kennst Du eine Möglichkeit, das doch ohne Perl zu schaffen?

Gruß
Enum
 
@deepthroat:

Klar, File::Temp, vor allem wenn's um Portabilität geht. Doch wir sind im Linux/Unix Forum...
Wie meinst du das? Was hat das mit Linux/Unix zu tun wenn man aus Sicherheitsgründen File::Temp verwendet was ja auch unter Windows etc. funktioniert? Ich verstehe deine Aussage irgendwie nicht...
Ich wollte das ursprünglich als Shellskript regeln, bin aber am "binmode" gescheitert und habe das einfach stumpf in Perl übersetzt.
Kennst Du eine Möglichkeit, das doch ohne Perl zu schaffen?
Naja, mit Python ;)

Oder Bash
Bash:
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
cat > "$tmp" && unzip "$@" "$tmp" || (echo "failed."; exit 1)
Gruß
 
Zuletzt bearbeitet:
Was hat das mit Linux/Unix zu tun wenn man aus Sicherheitsgründen File::Temp verwendet was ja auch unter Windows etc. funktioniert?
Das Nicht-verwenden von File::Temp hat was mit Linux/Unix zu tun sondern wenn man es trotz Kenntnis einfach außer acht lässt. Der Grund? Ich bin im Linux & Unix Forum auf ein einigermaßen interessantes Problem gestoßen, hab' es auf meinem BSD-Läppi kurz ausprobiert, später auf dem Linux-Rechner noch ein wenig 'rumgespielt und bin nicht einmal auf die Idee gekommen, dass das mickrige Skript irgendwann mal auf einem anderen System landet. :p

Ich muss mich doch bedanken, wieder einmal bin ich dank Dir ein wenig schlauer...
Ich weiß jetzt, dass cat ohne Argumente von der Standard-Eingabe liest und im Gegensatz zu einer while-read-do-echo-Schleife (*schäm*) Binärdaten nicht verstümmelt.
Danke!
 
Zurück