web-dev-qa-db-de.com

So prüfen Sie, ob ein Shell-Befehl vorhanden ist PHP

Ich brauche so etwas in PHP:

If (!command_exists('makemiracle')) {
  print 'no miracles';
  return FALSE;
}
else {
  // safely call the command knowing that it exists in the Host system
  Shell_exec('makemiracle');
}

Gibt es Lösungen?

32
mimrock

Unter Linux/Mac OS Versuchen Sie Folgendes:

function command_exist($cmd) {
    $return = Shell_exec(sprintf("which %s", escapeshellarg($cmd)));
    return !empty($return);
}

Dann verwenden Sie es im Code:

if (!command_exist('makemiracle')) {
    print 'no miracles';
} else {
    Shell_exec('makemiracle');
}

Update: Wie von @ camilo-martin vorgeschlagen, können Sie einfach Folgendes verwenden:

if (`which makemiracle`) {
    Shell_exec('makemiracle');
}
45
docksteaderluke

Windows verwendet where, UNIX-Systeme which, um einen Befehl lokalisieren zu können. Beide geben in STDOUT eine leere Zeichenfolge zurück, wenn der Befehl nicht gefunden wird.

PHP_OS ist derzeit WINNT für jede von PHP unterstützte Windows-Version.

Also hier eine tragbare Lösung:

/**
 * Determines if a command exists on the current environment
 *
 * @param string $command The command to check
 * @return bool True if the command has been found ; otherwise, false.
 */
function command_exists ($command) {
  $whereIsCommand = (PHP_OS == 'WINNT') ? 'where' : 'which';

  $process = proc_open(
    "$whereIsCommand $command",
    array(
      0 => array("pipe", "r"), //STDIN
      1 => array("pipe", "w"), //STDOUT
      2 => array("pipe", "w"), //STDERR
    ),
    $pipes
  );
  if ($process !== false) {
    $stdout = stream_get_contents($pipes[1]);
    $stderr = stream_get_contents($pipes[2]);
    fclose($pipes[1]);
    fclose($pipes[2]);
    proc_close($process);

    return $stdout != '';
  }

  return false;
}
12
Dereckson

Sie können is_executable verwenden, um zu prüfen, ob es ausführbar ist. Sie müssen jedoch den Pfad des Befehls kennen. Sie können den Befehl which verwenden, um ihn zu erhalten.

4
xdazz

Plattformunabhängige Lösung:

function cmd_exists($command)
{
    if (\strtolower(\substr(PHP_OS, 0, 3)) === 'win')
    {
        $fp = \popen("where $command", "r");
        $result = \fgets($fp, 255);
        $exists = ! \preg_match('#Could not find files#', $result);
        \pclose($fp);   
    }
    else # non-Windows
    {
        $fp = \popen("which $command", "r");
        $result = \fgets($fp, 255);
        $exists = ! empty($result);
        \pclose($fp);
    }

    return $exists;
}
3
srcspider

Basierend auf @jcubic und dem "was" sollte vermieden werden , ist dies die Cross-Plattform, die ich mir ausgedacht habe:

function verifyCommand($command) :bool {
  $windows = strpos(PHP_OS, 'WIN') === 0;
  $test = $windows ? 'where' : 'command -v';
  return is_executable(trim(Shell_exec("$test $command")));
}
1
botris

Basierend auf der Antwort von @xdazz, arbeitet unter Windows und Linux. Sollte auch auf MacOSX funktionieren, da es Unix ist.

function is_windows() {
  return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
}

function command_exists($command) {
    $test = is_windows() ? "where" : "which";
    return is_executable(trim(Shell_exec("$test $command")));
}
0
jcubic