Script - Easy way to go to a given port's directory

I created the below script to put me in a given port's directory under /usr/ports and thought I'd share with the community. It's easy to use - just save the file with the name goport, chmod it to be executable, toss it somewhere in your PATH (I used /usr/local/sbin), and then type something like [cmd=]goport postfix[/cmd] and you'll be thrown into the /usr/ports/mail/postfix directory in a new shell. (The shell used is the one you're currently running.) This way, you can do what you need, then control-D out to where you were and continue with what you were doing.

It's not 100% because the whereis command is not 100% on the locating of specific ports, at least on 8.0. (Example: [cmd=]whereis unzip[/cmd] provides the paths executable files, but not /usr/ports/archivers/unzip. I know not why, but the ports it doesn't work on seem to be few and far between. The same command on 7.1 works perfectly, showing the executable paths and the /usr/ports/archivers/unzip hit.)

Code:
#!/usr/bin/perl

###############################################################################
#                                                                             #
# Perl script to spawn a shell in the port directory (under /usr/ports) of    #
# the given port.                                                             #
#                                                                             #
# Parameter 1:                                                                #
#   Pass in the name of the port you wish to go to.                           #
#                                                                             #
###############################################################################
#                                                                             #
# Ruler's Common-Sense License:                                               #
#                                                                             #
#   You may use this script however you want to, but I don't warrant it to    #
#   be good for anything in particular, though it happens to work well for    #
#   me.  (I hate putting BS like this in, but I hate more being sued.)  If    #
#   you use this script, you must keep this license and credit to me in it    #
#   in the form of this block, even if you modify it for your own use.  If    #
#   you want to send me money for it, fantastic!  Send me a private message   #
#   on the freebsd.org forums and I'll give you my PayPal address. :-)  Even  #
#   just a simple 'thank you' would be nice.  If not, that's fine too.  All   #
#   hate mail/spam is sent directly to /dev/null                              #
#                                                       - Jim, AKA Ruler2112  #
#                                                                             #
###############################################################################
#                                                                             #
# History:                                                                    #
#                                                                             #
#   2010-01-20 by Ruler2112       Wrote initial version.                      #
#   2010-01-20 by Ruler2112       Released on freebsd.org forums.             #
#                                                                             #
###############################################################################

use strict;

my $portname = shift;

if($portname eq "")
  {
  print "You must specify a port name to go to.\n";
  }
else
  {
  my ($workstr, $cutpos);
  $workstr = `/usr/bin/whereis $portname`;
  $cutpos = index($workstr, "/usr/ports/");
  if($cutpos < 0)
    {
    print "Port $portname not found!!!\n";
    }
  else
    {
    my ($portloc);
    $workstr = substr($workstr, $cutpos);
    $cutpos = index($workstr, " ");
    if($cutpos < 0)
      {
      $portloc = $workstr;
      }
    else
      {
      $portloc = substr($workstr, 0, $cutpos);
      }
    chomp($portloc);
    print "Spawning shell at $portloc...\n";
    print "Control-D or exit to return to your present directory.\n";
    chdir($portloc);
    exec $ENV{SHELL};
    }
  }
exit;
 
I just usually use:
Code:
cd /usr/ports/*/some-port
Works most of the time but the spawning of a new shell could be handy.
 
ports-mgmt/psearch is really handy for this, as well. It doesn't change directories for you, but it can do a very quick search to tell you which directories to go to.

I haven't read your script (I try to avoid Perl as much as humanly possible). How does it handle multiple directories for a port? For example, firefox2 vs firefox30 vs firefox35 vs firefox.
 
That is a sweet idea bjs - I've used the * wildcard to match partial directories (ie - [cmd=]cd /usr/local/etc/co*[/cmd] because I'm too lazy to type out 'courier-imap'), but not ever considered using it as the entire argument in the middle of a command like that.

Phoenix, basically it runs a [cmd=]whereis portname[/cmd] and then strips out the location reported in /usr/ports, if any. If there's not, it tells you it can't find the port name. If there is, it tells you where it's putting you, switches to that directory, and spawns the shell you're currently using. I made it spawn a new shell for two reasons. A) I've frequently wanted to do something with a port and then resume what I was doing, therefore it saves me typing switching back to where I was. B) I couldn't figure out a way for perl to modify the shell that invoked the script. (From what I've found on the topic, it's impossible because a perl script, when invoked, is started in it's own shell space.) It doesn't do anything with multiple port name matches - you supply the full name of the port and either you get a match or not. I intended it to just be a faster way to do what I found myself doing all the time in response to [cmd=]portversion -L =[/cmd] reporting a given port is out of date:

Code:
whereis p5-Test-Exception
cd /usr/ports/devel/p5-Test-Exception

Those two (or more if I make a typo) lines are now [cmd=]goport p5-Test-Exception[/cmd]. Not anything worthy of fireworks, but time-saving and reduces the amount of typing I need to do. :) (I've got the carpal tunnel thing going on and am trying to avoid surgery, so anything in this regard is helpful.) *looks at this post* Nevermind... ;) :D
 
phoenix said:
ports-mgmt/psearch is really handy for this, as well. It doesn't change directories for you, but it can do a very quick search to tell you which directories to go to.

I haven't read your script (I try to avoid Perl as much as humanly possible). How does it handle multiple directories for a port? For example, firefox2 vs firefox30 vs firefox35 vs firefox.

Whats wrong with perl?
 
Business_Woman said:
Whats wrong with perl?

People's attitudes, whether toward a coding language or anything else, are like armpits - everybody has them, but they aren't always appreciated by others. :)

I personally love perl and while I can code in any of a dozen or more languages, it's my current first choice when I need to do something.
 
Ruler2112 said:
People's attitudes, whether toward a coding language or anything else, are like armpits - everybody has them, but they aren't always appreciated by others. :)

This maybe one of the most profound statements I've ever read on here. :)
 
Ruler2112 said:
People's attitudes, whether toward a coding language or anything else, are like armpits - everybody has them, but they aren't always appreciated by others. :)

I personally love perl and while I can code in any of a dozen or more languages, it's my current first choice when I need to do something.

So it's people like you who force me to download perl as a dependency even just to wipe my own arse :p

Cheers!

jk
 
It was actually originally a quote something like "Opinions are like armpits - everybody has them but they should be kept to yourself." I modified it a bit... :)



Just because you asked...

Code:
#!/usr/local/bin/perl
###############################################################################
# TO DO: Error checking (empty roll, arse not accessible, etc                 #
###############################################################################

use strict;

my $myself = shift;
my ($dirtybutt);

$dirtybutt = 1;
while($dirtybutt)
  {
  $dirtybutt = Wipe($myself.Arse)
  }
$myself->FlushToilet();
$myself.Hands->Wash();
$myself.Hands->Dry();
$myself->SprayDeoderizer();
print "All Clean! :)\n";
exit;

sub Wipe()
  {
  my $butt = shift;
  my ($tp, $dirty);
  $tp = new($roll->tearsheets(4));
  $tp->FoldInHalf();
  $tp->FoldInHalf();
  $dirty = $butt->Wipe($tp);
  if(($dirty > 0) and ($dirty < 2))
    {
    $tp->FoldInHalf();
    $dirty = $butt->Wipe($tp);
    }
  $tp->DropInToilet();
  return($dirty);
  }
 
I did update this BTW. Found I'd sometimes do a bunch of stuff in the port directory instead of a simple update, then not remember where I was. This fixes that.

Code:
#!/usr/bin/perl

###############################################################################
#                                                                             #
# Perl script to spawn a shell in the port directory (under /usr/ports) of    #
# the given port.                                                             #
#                                                                             #
# Parameter 1:                                                                #
#   Pass in the name of the port you wish to go to.                           #
#                                                                             #
###############################################################################
#                                                                             #
# Ruler's Common-Sense License:                                               #
#                                                                             #
#   You may use this script however you want to, but I don't warrant it to    #
#   be good for anything in particular, though it happens to work well for    #
#   me.  (I hate putting BS like this in, but I hate more being sued.)  If    #
#   you use this script, you must keep this license and credit to me in it    #
#   in the form of this block, even if you modify it for your own use.  If    #
#   you want to send me money for it, fantastic!  Send me a private message   #
#   on the freebsd.org forums and I'll give you my PayPal address. :-)  Even  #
#   just a simple 'thank you' would be nice.  If not, that's fine too.  All   #
#   hate mail/spam is sent directly to /dev/null                              #
#                                                       - Jim, AKA Ruler2112  #
#                                                                             #
###############################################################################
#                                                                             #
# History:                                                                    #
#                                                                             #
#   2010-01-20 by Ruler2112       Wrote initial version.                      #
#   2010-01-20 by Ruler2112       Released on freebsd.org forums.             #
#   2010-01-26 by Ruler2112       Added reminder of previous directory.       #
#                                                                             #
###############################################################################

use strict;

my $portname = shift;

if($portname eq "")
  {
  print "You must specify a port name to go to.\n";
  }
else
  {
  my ($workstr, $cutpos);
  $workstr = `/usr/bin/whereis $portname`;
  $cutpos = index($workstr, "/usr/ports/");
  if($cutpos < 0)
    {
    print "Port $portname not found!!!\n";
    }
  else
    {
    my ($portloc, $olddir);
    $workstr = substr($workstr, $cutpos);
    $cutpos = index($workstr, " ");
    if($cutpos < 0)
      {
      $portloc = $workstr;
      }
    else
      {
      $portloc = substr($workstr, 0, $cutpos);
      }
    chomp($portloc);
    print "Spawning shell at $portloc...\n";
    print "Control-D or exit to return to your present directory.\n";
    $olddir = $ENV{PWD};
    chdir($portloc);
    system($ENV{SHELL});
    print "Now returning to your regularly scheduled program in $olddir...\n";
    }
  }
exit;
 
hm, why not use the second column from ports/INDEX? instead
Code:
$workstr = `/usr/bin/whereis $portname`;
This way you can get the port directory even after a fresh update.
 
I'd thought of that, but ended up having trouble with the INDEX file listing all the dependencies as well as the port name. I ran the file through cut to output only the first column, but then had to find a way to deal with the version numbers being in there as well, plus more than one port with the given search string in it. For example:

Code:
cat /usr/ports/INDEX | cut -f 1 -d "|" |grep unrar
libunrar-3.6.8,1
unrar-3.60,4
zh-unrar-3.60,4

I also thought of doing an ls -R on /usr/ports, but would have the same problem of multiple directories having a potential match.



I did update this once more. Now, when switching to a port, it'll spit out the ports that depend on the one you're switching to. (This way you can update a port and right away know what others it may affect.)

Code:
#!/usr/bin/perl

###############################################################################
#                                                                             #
# Perl script to spawn a shell in the port directory (under /usr/ports) of    #
# the given port.                                                             #
#                                                                             #
# Parameter 1:                                                                #
#   Pass in the name of the port you wish to go to.                           #
#                                                                             #
###############################################################################
#                                                                             #
# Ruler's Common-Sense License:                                               #
#                                                                             #
#   You may use this script however you want to, but I don't warrant it to    #
#   be good for anything in particular, though it happens to work well for    #
#   me.  (I hate putting BS like this in, but I hate more being sued.)  If    #
#   you use this script, you must keep this license and credit to me in it    #
#   in the form of this block, even if you modify it for your own use.  If    #
#   you want to send me money for it, fantastic!  Send me a private message   #
#   on the freebsd.org forums and I'll give you my PayPal address. :-)  Even  #
#   just a simple 'thank you' would be nice.  If not, that's fine too.  All   #
#   hate mail/spam is sent directly to /dev/null                              #
#                                                       - Jim, AKA Ruler2112  #
#                                                                             #
###############################################################################
#                                                                             #
# History:                                                                    #
#                                                                             #
#   2010-01-20 by Ruler2112       Wrote initial version.                      #
#   2010-01-20 by Ruler2112       Released on freebsd.org forums.             #
#   2010-01-26 by Ruler2112       Added reminder of previous directory.       #
#   2010-02-01 by Ruler2112       Now prints dependencies if port installed.  #
#                                                                             #
###############################################################################

use strict;

my $portname = shift;

if($portname eq "")
  {
  print "You must specify a port name to go to.\n";
  }
else
  {
  my ($workstr, $cutpos);
  $workstr = `/usr/bin/whereis $portname`;
  $cutpos = index($workstr, "/usr/ports/");
  if($cutpos < 0)
    {
    print "Port $portname not found!!!\n";
    }
  else
    {
    my ($portloc, $olddir, $portver, $deps);
    $workstr = substr($workstr, $cutpos);
    $cutpos = index($workstr, " ");
    if($cutpos < 0)
      {
      $portloc = $workstr;
      }
    else
      {
      $portloc = substr($workstr, 0, $cutpos);
      }
    chomp($portloc);
    $portver = `/usr/sbin/pkg_info | /usr/bin/grep $portname | /usr/bin/cut -f 1 -d " "`;
    chomp($portver);
    if($portver ne "")
      {
      $deps = `/usr/sbin/pkg_info -R $portver`;
      }
    print "Spawning shell at $portloc...\n";
    print "$deps\n";
    print "Control-D or exit to return to your present directory.\n";
    $olddir = $ENV{PWD};
    chdir($portloc);
    system($ENV{SHELL});
    print "Now returning to your regularly scheduled program in $olddir...\n";
    }
  }
exit;
 
Back
Top