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



## Ruler2112 (Jan 20, 2010)

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.)


```
#!/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;
```


----------



## bjs (Jan 20, 2010)

I just usually use:

```
cd /usr/ports/*/some-port
```
Works most of the time but the spawning of a new shell could be handy.


----------



## phoenix (Jan 21, 2010)

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.


----------



## Ruler2112 (Jan 21, 2010)

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:


```
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...


----------



## Business_Woman (Jan 25, 2010)

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?


----------



## Ruler2112 (Jan 26, 2010)

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.


----------



## roddierod (Jan 26, 2010)

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.


----------



## kpedersen (Jan 26, 2010)

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 

Cheers!

jk


----------



## Ruler2112 (Jan 26, 2010)

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...


```
#!/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);
  }
```


----------



## Ruler2112 (Jan 26, 2010)

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.


```
#!/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;
```


----------



## kpedersen (Jan 26, 2010)

Ruler2112:

haha Error checking - "arse not accessible"

Your scripts certainly seem robust enough


----------



## ohauer (Jan 31, 2010)

hm, why not use the second column from ports/INDEX? instead 
	
	



```
$workstr = `/usr/bin/whereis $portname`;
```
This way you can get the port directory even after a fresh update.


----------



## Ruler2112 (Feb 1, 2010)

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:


```
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.)


```
#!/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;
```


----------

