Detect if executable exists on system path with node - windows

Question
Is there a simple way to tell if a system executable is available on the system path using node? For example if a user has python installed at /usr/bin/python and /usr/bin is in $PATH how can I detect that in Node? And conversely detect when something isn't installed or is just not on path, i.e. /usr/opt/local/mycustompath/python? Ideally hoping their is an npm package available ...
I'm sure this is a quick google search with the right search term, but I'm failing due to the fact where and which are pretty generic search terms.
Background
I'm working on some dev config for a node tool and would like to be able to detect whether python (or pip) is already available on path, and if not, ask the user to tell install it or tell us where to find it. I'm currently planning on doing this with where on windows machines and which on *nix machines, but was hoping there might be a single cross platform way of doing this.

Package hasbin has since been published to the npm registry, which provides this functionality:
Install it (as part of your project) with npm install hasbin
To test the availability of Python, use it as follows (do not append .exe to the executable file name):
var isPyAvailable = require('hasbin').sync('python')
The package has various other helpful methods, such as the ability to find the first available binary among several - see its GitHub repository.

Zero dependencies+ simple + stupid == 👇🏻
const { execSync } = require('child_process');
const shell = (cmd) => execSync(cmd, { encoding: 'utf8' });
function executableIsAvailable(name){
try{ shell(`which ${name}`); return true}
catch(error){return false}
}
// Then use it
executableIsAvailable('docker-compose') // true
executableIsAvailable('python') // true
executableIsAvailable('mvn') // false
Suppose no one run nodejs in windows at this era!

You have to find a way to do it, as there is no "generic" or "out-of-box" way to do it.
One way is, you can use check if the desired package/binary is installed via your package manager then you can use utility whereis which attempts to locate the desired program in a list of standard Linux places, listed in $PATH.
Of course you can use also the utility which but whereis provides a bit more information. You can check about the difference of which and whereis here.
Generally speaking, as in your example, user might has manually installed some package at some random location, but not listed in $PATH.
In this way there is no way to check if the package is installed at all, rather than to try to find the binary name or related files in complete tree of file system.

Related

Consistent builds / remove personal information from binaries

I've now realized that Go saves absolute paths to source code in binaries for the purpose of printing stack-traces and the likes. I don't want to completely remove this information, however, this also means that every developer building the same program will produce an executable with a different checksum. Before I try to reimplement the build using chroot or something like that: isn't there any way to tell Go not to use absolute paths for this purpose?
I know it doesn't directly address what you asked, but #JimB's suggestion does indicate a class of solutions to the problem you seem to be having.
One of the easier ones (I think) would be to have your developers install Docker and create an alias so that the go command runs:
docker run --rm --tty --volume $GOPATH:/go golang:1.7.1(-$YOUR_PLATFORM) go
Then, every build (and test and run) thinks it's using a GOPATH of /go and your developers' checksums won't disagree based on that.
See here for more info.
isn't there any way to tell Go not to use absolute paths for this purpose?
Nowadays there is: -trimpath.
https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies explains:
-trimpath
remove all file system paths from the resulting executable.
Instead of absolute file system paths, the recorded file names
will begin either a module path#version (when using modules),
or a plain import path (when using the standard library, or GOPATH).

Installing AUBit4GL via binary package

I am trying to experiment with AUBIT4GL, an Informix clone. I am running into a problem with the process as the steps outlined in the manual and the instructions given in the ./etc/aubitrc file seem to be a tad incomplete.
My questions are:
What is the purpose of the ./configure and ./make scripts in the distribution directory given that the software is distributed as a binary package and the install instructions make not reference to them?
Where is the env TARGET_OS set and why is there no reference to this setting in the install instructions when failing to define it causes the aubit program to fail?
Is anyone else besides me using this software or has attempted to?
If you're running on Linux - always trying compiling from source.
If you must run from binary - you dont need to do anything with the ./configure or make.
Just point $AUBITDIR to the code.
set PATH to include $AUBITDIR/bin
set LD_LIBRARY_PATH to include $AUBITDIR/lib
and you should be good to go.
For Windows - its pretty much the same - except compiling from source is a massive pain - so use the binary ;)
There - you need to have PATH include both %AUBITDIR%/bin and %AUBITDIR%/lib
In both cases - you'll likely need to make some configuration settings (what type of database, what UI etc etc)
If you're using Informix on Linux, setting :
export A4GL_UI=TUI
export A4GL_SQLTYPE=esql
will probably be enough (if they are not defaulted in the $AUBITDIR/etc/aubitrc)

how to set path in bashrc for multiple locations

I am installing same library (maybe with different release versions) at two different locations. Now I am exporting the path in bashrc for both. In linux which one is taken if I call the library in some program?
For example:
mylib_version1 is installed in /home/PATH1/lib ,
mylib_version2 is installed in /home/PATH2/lib
in bashrc I do,
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/PATH1/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/PATH2/lib
which path is actually taken by some other program when calling this library? How does the ordering work in bashrc?
Similarly what happens when PATH1 is just /usr/local/lib (which I don't export in bashrc)
and PATH2 is some user define path.
What I experience for some program is, if I install it in /usr/local/bin
and if I install using some prefix like /home/PATH/bin and export it in bashrc like
export PATH=$PATH:/home/PATH/bin
it always takes from /usr/local/bin.
If I understand you correctly, you have library.so with 2 versions and you have a binary that might use library.so version 1 or 2.
To deal with that problem you must first understand the meaning of libraries version mechanism. All libraries should be placed in the same place and you might have something like that:
/usr/lib/library.so.1.0.0
/usr/lib/library.so.2.0.0
Your binary would be linked to the correct library based on the API used and linking during the build process.
Please read more information regarding libraries here

Making a configuration file in linux

I am making a configure.ac file for a tool i made and i need to check whether pdflatex is installed in the users system. How do i do it ? For checking for other libraries i simply included the test programs using AC_COMPILE_IFELSE, but i dont know if pdflatex can be invoked from the program.
Also is it regular practise to install all the required packages automatically using some script or i can just specify in the readme file which packages are required and then its upto user to install those packages.
You can use AC_CHECK_PROG([have_pdflatex], [pdflatex], [yes], [no]) to simply check if it exists and set have_pdflatex to yes if so. It's more likely that you'll want to use AC_PATH_PROG([PDFLATEX], [pdflatex]) to find the actual path of the program if it exists and store it in PDFLATEX.
I think it's best to let the user install the prerequisites themself. You don't know how they install their software (apt? yum? pacman? emerge? source?) and it wouldn't be worth the effort to try to cover all cases. It's sufficient to just mention them in the README and to test for them with Autoconf macros.

Creating .deb to install bash script program

I was wondering if the following is possible.
I have a BASH script that I want to make available for some people but I wanted them to only have to "install" the program and not messing around with terminal, so I thought a .deb would be cool.
So what would the "install" do?
Simple. I want to move the script and an icon to a folder (any folder, but I was wondering some hidden folder in Home) and then run a script that creates a launcher in the Applications menu for the first script. It seems there isn't much to it, but for what I've searched, there doesn't seem to be a lot of info...
How can I accomplish this?
By the way, I'm using Ubuntu 11.04.
Basically (install and) run dh-make to set up the debian/ directory, edit the generated files (mainly remove the many you do not need, and fill in a package description and any dependencies in debian/control), then debuild-us -uc -b.
You may also have to set up a simple Makefile for debian/rules to call; it probably only needs an install target to copy the binary to $(DESTDIR)/usr/bin.
Binaries install into /usr/bin and you should not try to override that. The way to have a menu is to add a .desktop file.
Once you have a good .deb you will need to set up a repo for distributing it. The simplest solution is probably to set up a launchpad.net account and create a personal PPA there.
It's not hard to find more information on these topics, but of course, you need to know what to look for. The canonical documentation is the Debian New Maintainer's Guide.
Found this video on youtube that explains IN FULL the process of creating a *.deb for a script or program and even mentions how to do it for a C program.
Full guide in how to build simple *.deb package
Has one bug, btw, that the author, during the making of the *.deb, didn't notice. The path in the *.desktop file for the EXEC parameter is wrong in the example.

Resources