Skip to content

Instantly share code, notes, and snippets.

@zwetan
Created May 10, 2015 08:55
Show Gist options
  • Save zwetan/5700da82e0f2983fe135 to your computer and use it in GitHub Desktop.
Save zwetan/5700da82e0f2983fe135 to your computer and use it in GitHub Desktop.
implementation of the shell utility "which"
#!/usr/bin/as3shebang --
import C.stdlib.*; // getenv, exit, EXIT_SUCCESS, EXIT_FAILURE
import C.unistd.*; // access, X_OK, getlogin
import C.sys.stat.*; // stat, status, S_ISREG, S_IXUSR, S_IXGRP, S_IXOTH
/* NOTE:
Inside Bash scripts you often encounter
svn = ${`which svn`}
to get the full path of an executable
Based on the $PATH
$ echo $PATH
/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
which basically iterates trough all those paths
to find the executable
/opt/local/bin
/opt/local/sbin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
code ported from
http://www.opensource.apple.com/source/shell_cmds/shell_cmds-170/which/which.c
*/
/**
* which - locate a program file in the user's path
*
* The which utility takes a command name and searches the path
* for each executable file that would be run had this
* command actually been invoked.
*
* @param name program name to look for.
* @param all if <code>true</code> list all instances of executables found.
* @return the full path of the program or the empty string if not found.
*/
var which:Function = function( name:String, all:Boolean = false ):String
{
var PATH:String = getenv( "PATH" );
if( PATH == "" ) { return ""; }
var paths:Array = PATH.split( ":" );
paths.push( "." );
var is_there:Function = function( candidate:String ):Boolean
{
var fin:* = new status();
/* Note:
getlogin() != "root"
should be
getuid() != 0
*/
if( (access( candidate, X_OK ) == 0) &&
(stat( candidate, fin ) == 0) &&
S_ISREG( fin.st_mode ) &&
( (getlogin() != "root") ||
((fin.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0) ) )
{
return true;
}
return false;
}
var found:String = "";
var i:uint;
var len:uint = paths.length;
var candidate:String;
for( i = 0; i < len; i++ )
{
candidate = paths[i] + "/" + name;
if( is_there( candidate ) )
{
if( all )
{
found += (found == "" ? "": " ") + candidate;
}
else
{
return candidate;
}
}
}
return found;
}
//testing
trace( "which bash = " + which( "bash" ) );
trace( "which svn = " + which( "svn", true ) );
trace( "which hg = " + which( "hg" ) );
trace( "which git = " + which( "git" ) );
trace( "which as3shebang = " + which( "as3shebang" ) );
trace( "which java = " + which( "java", true ) );
//example of output
/*
which bash = /bin/bash
which svn = /opt/local/bin/svn /usr/bin/svn
which hg = /opt/local/bin/hg
which git = /opt/local/bin/git
which as3shebang = /usr/bin/as3shebang
which java = /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/bin/java /usr/bin/java
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment