tags:

views:

268

answers:

11

How can I quickly check if Linux unzip is installed using Perl?

+1  A: 
perl -e 'if (-e "/usr/bin/unzip") { print "present\n"; } else { print "not present\n"; }'
Brian Showalter
It could be in `/usr/local/bin`. Right?
innaM
Yup, it could. I was assuming a standard installation from a packaged distribution.
Brian Showalter
+11  A: 
`which unzip`

If there's output, it points to unzip's location. If there isn't output, then nothing will show up. This relies on unzip being on your path.

Zach
im assuming which is standard on all linux systems?
It's been on every Unix and Linux system that I've used.
molecules
also, if it is not found, it returns a non-zero exit code (1 on Ubuntu 8.04) while if it is found it returns 0
HalfBrian
`which` is neither part of POSIX, nor the Single Unix Specification, not the Linux Standard Base Specification. It's not installed on at least one of the Linux systems I'm using right now. I can remember several other Linux systems I have used in the past that didn't have it.
Jörg W Mittag
`which which` will tell you if `which` is installed :) On most modern systems, yes. On systems 2007 or earlier, its touch and go.`which` only searches your path anyway .. so a portable work around is to do that yourself.
Tim Post
`command -v` was added to both the Single Unix Specification and the Linux Standard Base Specification as a replacement for `which`.
Jörg W Mittag
okay so best bet would be to do a `unzip -v` and check for non 'command not found' output?
No, do `command -v unzip`.
dreamlax
This won't work if unzip is installed in a non $PATH location, for example "/usr/local/unzip", so it's not recommended. Also, on Solaris if not found, it will still return exit code 0.
Anders
+6  A: 

This verifies if unzip command is on your path and also if it is executable by current user.

print "unzip installed" if grep { -x "$_/unzip"}split /:/,$ENV{PATH}
catwalk
+1  A: 

Any particular unzip? Linux systems I use have Info-Zip's unzip and if that is what you want to check for, you can do

if ( (`unzip`)[0] =~ /^UnZip/ ) {
# ...
}

If you want this to be a little safer, you would do:

#!/usr/bin/perl -T

use strict; use warnings;

$ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';

use File::Spec::Functions qw( catfile path );

my @unzip_paths;

for my $dir ( path ) {
    my $fn = catfile $dir, 'unzip';
    push @unzip_paths, $fn if -e $fn;
}

if ( @unzip_paths > 1 ) {
    # further narrow down by version etc
}

See also my multi-which script.

Sinan Ünür
+2  A: 

Taken from Module::Install::Can:

sub can_run {
  my ($self, $cmd) = @_;

  my $_cmd = $cmd;
  return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd));

  for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') {
    next if $dir eq '';
    my $abs = File::Spec->catfile($dir, $_[1]);
    return $abs if (-x $abs or $abs = MM->maybe_command($abs));
  }

  return;
}

Then:

my $is_it_there = can_run("unzip");
tsee
+11  A: 
Jörg W Mittag
yeeeeeeeeeeeeeeee sup!~
+1  A: 

Perhaps you should step back and ask why you need the unzip command from Perl. Is it because you want to unzip something? If so, then you should consider doing this programmatically with one of the many modules available, e.g. Archive::Zip.

Ether
Sometimes, you want to unzip stuff quickly. Then, Archive::Zip is the wrong choice.
tsee
Why the downvote? It's a valid answer in many cases.
tsee
+2  A: 

I just use Archive::Extract and configure it to prefer binaries to Perl modules. If unzip is there, it uses it. Otherwise, it falls back to pure Perl.

brian d foy
A: 

File::Which

hillu
+1  A: 

why do you want to call system command when using Perl.? use an unzip module such as Archive::Extract, (or others in CPAN)

A: 

You could try this script (Tested). It utilizes the which command.

#!/usr/bin/perl -w

use strict;

my $bin = "unzip";
my $search = `which $bin 2>&1`;
chomp($search);
if ($search =~ /^which: no/)
{
    print "Could not locate '" . $bin . "'\n";
    exit(1);
} else {
    print "Found " . $bin . " in " . $search . "\n";
    exit(0);
}

Cheers,

Brad