Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

This is my sample code from the platypus tutorial. I am trying to make it work with a command named pymol, and I want it to open .pdb files or open just pymol. I know nothing about perl, but I have basic sh knowledge and can do aliases and modify .zshrc files.

According to CommonMediaInc,

Filling the gap is Platypus, a handy little utility which makes application bundles out of Unix scripts. Notice I didn’t say “Perl” there. Platypus plays nicely with shell scripts, Python, PHP, Ruby, and Tcl just as easily as Perl. As the developer describes it, “this is done by wrapping the script in an application bundle directory structure along with an executable binary that runs the script.”

So hopefully someone here can help with making a small, usable droplet (drag-and-drop icon) to open files dropped to this app (while switching to the path of the file).

#!/usr/bin/perl

use strict;
use File::Basename;

my $cmd = "/usr/bin/tar cvfz";

# Get enclosing folder of first file
my($fn, $directory) = fileparse($ARGV[0]);

# Change to that directory
chdir($directory);

# Archive is created there
my $dest_path = "Archive.tgz";

my $files;
foreach(@ARGV)
{
    my($filename, $directory) = fileparse($_);
    $files .= "'$filename' ";
}

print $cmd . "\n";
system("$cmd $dest_path $files");
share|improve this question
    
Are these "droplets" a MacOS thing? We can move this to Ask Different if so –  Michael Mrozek Jun 10 '11 at 15:11

1 Answer 1

I'm not going to leaves this unanswered, because there are a couple of things seriously wrong with this script. However, because I don't know what the script is supposed to do, this answer isn't going to solve your problem.

  • chdir($directory); can fail. You need to handle the error.

    chdir($directory) or die "chdir($directory): $!";
    
  • $files .= "'$filename' " is not proper quoting for a file name: it'll fail if the file name contains a '. You could prepare the file name with $filename =~ s/'/'\\''/, but there's actually a better way to do this (see the next point).

  • system with a single argument invokes a shell. But you're not using any shell feature, so instead you should use the list form. And that way you don't need to build a string that gathers all the file names: just use the list you already have.

    my @cmd = qw(/usr/bin/tar cvfz);
    system(@cmd, $dest_path, @ARGV);
    
  • You still need to handle errors from system.

    system(@cmd, $dest_path, @ARGV) or die "Call to $cmd[0] failed with status $?";
    

    If this is the last thing your script does, call exec instead.

    exec(@cmd, $dest_path, @ARGV) or die "exec $cmd[0] failed: $!";
    

So far you could do all of this easily in the shell.

#!/bin/sh
set -e
cmd='tar cvzf'
dest_path='Archive.tgz'
cd -- "$(dirname -- "$0")"
echo "$cmd $dest_path $*"
exec $cmd "$dest_path" "$@"
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.