Check if command exists from PHP
Knowing if a command exists before trying to call it from a PHP script is a useful way to prevent errors; testing if a command exists can be done using the command -v utility in linux, and where in Windows.
By. Jacob
Edited: 2021-03-14 19:05
A command is a small program that is available on a system, and that can be called from a command prompt. For example, when on a Windows system commands may be called from cmd.exe, while on Linux, commands may be called from a terminal.
Sometimes you may want to invoke a command from within a PHP script using a function like shell_exec, but what if a command does not exist on the system? The problem is that it can be hard to know which commands are available to be used. In many cases it is simply best to find PHP-alternatives; if you need to convert an image, you might be able to use the GD library extension.
It is not that there is anything wrong with calling external commands, you should just be careful, and always validate user input before sending it to shell_exec and related functions.
How do you check if a command exists?
It turns out you can use the command -v [command name] utility to check if other commands exists on the system, and this is the "standard" way of doing it in Linux and bash scripting. I even used it in project humanize.
The command utility can be used to execute a command, but also to return the path for an existing command.
A path to the executable file will be returned when you use it with the -v parameter, or NULL if the utility did not produce any output.
Knowing this, we can now create our own command_exists() function:
/**
* Checks if a command exist on a typical Linux system
* @param mixed $command_name
* @return bool
*/
public function command_exists($command_name)
{
return (null === shell_exec("command -v $command_name")) ? false : true;
}
This function can then be used as any other *_exists function in PHP:
if (false === command_exists('convert')) {
throw new Exception("The required command 'convert' does not appear to exist on the system.");
}
$command = "convert this.jpeg that.avif";
$result = shell_exec(escapeshellcmd($command));
Cross platform compatibility
For this to work on both Linux and Windows, we should examine the PHP_OS constant variable. This constant contains the operating system that PHP is running under, which we can use to determine a method to tell if a command is available.
Windows systems used the where utility, while Linux typically uses the command -v utility.
Here is one way to determine which method to use:
if (false === stripos(PHP_OS, 'linux')) {
$test_method = 'command -v';
} else if (false === stripos(PHP_OS, 'win')) {
throw new Exception('This OS is not supported.');
} else {
$test_method = 'where';
}
if (null === shell_exec("$test_method $command_name")) {
echo 'Command not found!';
exit();
} else {
echo 'Command was found.';
exit();
}
This can be shortened to:
/**
* Checks if a command exist. Works for both Windows and Linux systems
* @param mixed $command_name
* @return bool
*/
public function command_exists($command_name)
{
$test_method = (false === stripos(PHP_OS, 'win')) ? 'command -v' : 'where';
return (null === shell_exec("$test_method $command_name")) ? false : true;
}
However, testing for cross platform compatibility is almost completely irrelevant in this case, since you are not going to have the same commands available for Windows that you do for your typical Linux distribution anyway.
Knowing if a command is executable
Of course, knowing whether a command is also executable may be important, but unfortunately that is not possible from PHP alone. My guess is that knowing whether a command is also executable is going to be irrelevant for most uses, but if needed, you could just use a helper .sh helper script.
The PHP is_executable only works under some circumstances; indeed, it might return false even for commands that are executable.
I used a similar technique in project humanize:
#!/bin/bash
#
# Helper script to check for dependencies
#
# This script can be placed in /usr/local/bin/
#
# script author: JacobSeated
# |>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>|
# |>>>>>>>Execute>>>>>>>>>>>>>>>>>>>>>>>>|
# |>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>|
if [ "$1" = "" ]
then
printf "\n Error: Missing required command line parameter: [command name]\n\n"
exit 1
fi
if [ ! -x "$(command -v $1)" ]
then
printf "\n This script requires \"$1\" to be installed. Exiting.\n\n"
# Exit with 2 = Missing keyword or command, or permission problem...
# See also: http://www.tldp.org/LDP/abs/html/exitcodes.html
# A zero code indicates success, while a value higher than zero indicates an error
exit 2
fi
Links
- shell_exec - php.net
Tell us what you think: