Best way to know if a command line tool is installed?

If have done very little with the shell class or command line tools, so my knowledge n that area is lacking.

I have an app that will handle things different bases on if a command line tool is available.

This is to run on both mac and Windows… What is the best (easiest, quickest) way (hopeful X-Platform) to determine in code if the tool is installed?

Thanks

  • Karen

in Linux I use (to see if it is installed and where it is)

dim sh as new shell sh.Execute ("which ffmpeg") if sh.Result = "" then MsgBox "ffmpeg not found" else MsgBox "ffmpeg found at " + sh.Result.Replace(EndOfLine, "") end if

In OSX ‘which’ does not work in a Xojo Shell, I don’t know why

maybe you can use ‘locate’

OSX “locate” requires the the files in question be “pre-located” using

sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist

which can take a LONG time…

most command tools should (in OSX at least) be in usr/bin or one of its branches

FUNCTION find_app(app_name as string) as folderitem
  Dim f As FolderItem
  #If TargetMacOS Then 
    f=Volume(0).child("developer")
    If f<>Nil Then f=f.child("usr")
    If f<>Nil Then f=f.child("bin")
    If f<>Nil Then f=f.child(app_name)
    If f<>Nil Then
      If Not f.Exists Then f=Nil
    End If
    //
    //
    If f=Nil Then
      f=Volume(0)
      If f<>Nil Then f=f.child("usr")
      If f<>Nil Then f=f.child("bin")
      If f<>Nil Then f=f.child(app_name)
    End If
    If f<>Nil Then
      If Not f.Exists Then f=Nil
    End If
    //
    //
    If f=Nil Then
      f=SpecialFolder.Applications
    End If
    If f<>Nil Then
      If Not f.Exists Then f=Nil
    End If
    //
    //
  #Else
    f=Nil
  #EndIf
  Return f
END FUNCTION

this is what I use to find things the XCODE, SWIFT, SIPS and other command line tools

[/code]

Try ‘command -v ffmpeg’

Sweet… dang Marco you have taught me TWO things today… :smiley:

Well, I’ve learned so much from your posts so only 287 things to go. :slight_smile:

Thanks All
Marco’s suggestion works on OSX.

anyone knows how to check on Windows?

Thanks

  • Karen

Use the full path
/usr/bin/which

This uses the same rules and API that cmd.exe uses to find executables by name:

Function LocateOnPath(ProgramName As String) As FolderItem
  Soft Declare Function PathResolve Lib "Shell32" (Path As Ptr, StartDir As Ptr, Flags As Integer) As Boolean
  Const PRF_REQUIREABSOLUTE = &h0010
  Const PRF_VERIFYEXISTS = &h0001
  Dim resolv As New MemoryBlock(255)
  resolv.WString(0) = ProgramName
  If Not PathResolve(resolv, Nil, PRF_REQUIREABSOLUTE Or PRF_VERIFYEXISTS) Then Return Nil
  Return GetFolderItem(resolv.WString(0), FolderItem.PathTypeAbsolute)
End Function

[quote=278766:@Norman Palardy]Use the full path
/usr/bin/which[/quote]
This is the way that I’ve always done it, it’s harder for a nefarious application to replace core system apps; but by using a ‘search’ function you may not get the correct version or even the correct tool.

AFAIK, ‘command -v’ is the Posix way and should always work.
I’m not sure ‘which’ is available in all Shells.

edit: http://unix.stackexchange.com/questions/85249/why-not-use-which-what-to-use-then

Sub findCLI(cli as string)
  dim sh as new shell
  sh.Execute ("if command -v " + cli + " > /dev/null 2>&1; then   echo " + cli + " is available; else   echo " + cli + " is not available; fi")
  MsgBox (sh.Result)
End Sub

findCLI(what_you_want_to_find)

[quote=278819:@Axel Schneider] dim sh as new shell
sh.Execute (“if command -v " + cli + " > /dev/null 2>&1; then echo " + cli + " is available; else echo " + cli + " is not available; fi”)
MsgBox (sh.Result)[/quote]
sorry… it seems to suffer the same issue as “Which” in that is doesn’t look in /usr/local
but thanks

Maybe it is an OSX problem or does not work with newer Xojo versions?

I use 2016R4.1 and there it works in Linux

Xojo Example

For macOS you can use “whereis”.

if TextField1.Text.Len > 0 then
dim MyShell as new shell
dim cmd as string
dim MyResult as string

cmd ="whereis " + TextField1.Text
MyShell.Execute(cmd)
MyResult = MyShell.Result
if MyResult.len > 0 then
MsgBox “CMD «” + TextField1.Text + “» is available”
TextField2.Text = MyResult
else
MsgBox “CMD «” + TextField1.Text + “» is NOT available”
TextField2.Text = “”
end if
end if