ncuesta/clinner

命令执行抽象层

1.0.0 2014-05-07 20:36 UTC

This package is not auto-updated.

Last update: 2024-09-14 13:18:02 UTC


README

Build Status

Clinner 是一个 PHP 5.3+ 命令行界面命令执行抽象层。

优点

Clinner 具有以下优点

  • 极简主义。
  • 简单易用。
  • Clinner 使用 Composer
  • 流畅的 API。
  • 高级和面向对象的命令接口。
  • 命令管道,无论底层操作系统是什么
  • 命令可以是实际的命令行可执行文件或 PHP 代码。
  • 是的,你可以以面向对象的方式混合命令和 PHP 代码!
  • 通过接口实现轻松扩展。
  • MIT 许可。

使用方法

简单使用

Clinner 最基本的使用方法是将其作为依赖项通过 Composer 安装,然后在你的代码中包含 Composer 的 autoloader.php 文件。

  1. 创建(如果需要)一个 composer.json 文件或将其添加到现有的文件中
    {
        "name": "my/nifty-project",

        "require": {
            "ncuesta/clinner": "dev-master"
        }
    }
  1. 在代码中包含 Composer 的 autoload.php 文件
    <?php
    
        require_once __DIR__ . '/vendor/autoload.php';
  1. 立即开始使用命令!
    <?php

        /*
         * List current working directory's files
         * and store the list as a string.
         */
        require_once __DIR__ . '/vendor/autoload.php';

        use \Clinner\Command\Command;


        $command = new Command('ls');
        $files = $command
            ->run()
            ->getOutput();
        // Or get them as an array
        $filesArray = $command->getOutputAsArray();
    
        if ($command->getExitCode() === 0) {
            echo 'Everything went fine.';
        } else {
            echo 'Something didn\'t work as expected...';
        }

        // There's also a factory method that allows
        // to make best use of the fluent API
        echo Command::create('ls')
            ->run()
            ->getOutput();

传递参数

命令渴望参数,因此 Clinner 提供了一种满足它们的方式。通过将第二个参数传递给工厂方法或构造函数,或使用专用设置方法 setArguments()

<?php

    use \Clinner\Command\Command;


    // Commands will most certainly take arguments,
    // so let's try something with them
    $command = new Command('cat', array('/etc/hosts'));
    // This will run `cat /etc/hosts`
    $command->run();

    // You might also use its factory method
    // to take even more advantage of the fluent API
    echo Command::create('cat', array('/etc/hosts'))
        ->run()
        ->getOutput();

参数可以是键值对或只是值。键值对将使用 分隔符 连接(有关更多信息,请参阅 选项 部分)。

选项

选项允许自定义不同的 Command 行为。它们可以作为工厂方法或构造函数的第三个参数传递,或通过 setOptions() 方法设置。

目前可以自定义 Command 类的唯一一项是:您可以指定分隔符,这是一个将用于连接参数键值对的 字符串。如果未指定,则默认为等于号(=)。

让我们看看一个例子

<?php

    use \Clinner\Command\Command;


    // `cut` command won't work if key-value pairs of arguments
    // are joined with '=':
    $command = Command::create(
        'cut',
        array(
            '-d' => ':',
            '-f' => 1,
            '/etc/passwd',
        )
    );

    $command->run();
        // => will run `cut -d=: -f=1 /etc/passwd` (WRONG)

    // Change the delimiter to '' (an empty string)
    $command->setOptions(array('delimiter' => ''));

    $command->run();
        // => will run `cut -d: -f1 /etc/passwd` (CORRECT)

高级使用:命令管道

命令可以像在任何 Unix shell 中一样进行管道操作。命令管道的基本原理是,一个命令的输出被发送到管道到其的命令。

例如,如果您想运行 ls -a | grep -i clinner,您可以这样做

<?php

    use \Clinner\Command\Command;


    $grepCommand = Command::create('grep', array('-i', 'clinner'));
    $lsCommand   = Command::create('ls', array('-a'));

    $lsCommand
        ->pipe($grepCommand)
        ->run();

    $pipeOutput = $lsCommand->getOutput();

    // Or the same thing in an uglier but more pro way

    $pipeOutput = Command::create('ls', array('-a'))
        ->pipe(Command::create('grep', array('-i', 'clinner')))
        ->run()
        ->getOutput();

命令管道不仅限于命令数量,您只需要 至少 两个命令。

请参阅下一部分,其中包含涉及管道中 3 个命令的更复杂示例。

高级使用:将 PHP 与命令混合

除了 Command 类之外,Clinner 还提供了一个 Callback 命令类,它允许在命令管道中混合命令和 PHP 代码。非常酷,对吧?

Callback 类只在其构造函数中接受一个 Closure 或函数引用,然后就可以运行了。该 Closure 函数将接收命令的输入作为其第一个参数,并期望返回一个退出代码。函数输出的任何信息(无论是通过 echoprint 还是其他任何输出方法)都将被视为命令输出,并将其发送到管道中的下一个命令,如果有的话。

<?php

    use \Clinner\Command\Command;
    use \Clinner\Command\Callback;


    // Get all the usernames in the system that contain an 'a' in them
    $callbackCommand = new Callback(function($input) {
        foreach (explode("\n", $input) as $line) {
            if (false !== strchr($line, 'a')) {
                echo "$line\n";
            }
        }
    });

    $systemUsers = Command::create('cat', array('/etc/passwd'))
        ->pipe(
            Command::create('grep', array('-v' => '^#'), array('delimiter' => ' '))
        )
        ->pipe(
            Command::create('cut', array('-d' => ':', '-f' => 1), array('delimiter' => ''))
        )
        ->pipe($callbackCommand)
        ->run()
        ->getOutputAsArray("\n");

从字符串创建命令

0.1.2 版本开始,您可以使用字符串创建一个 Command 实例,就像您在 CLI 中编写命令一样。

例如,以下命令可以在CLI上运行:

~$ cat /etc/hosts | grep localhost | tr -s "\t" " "

将输出包含字符串localhost的所有行,其中任何制表符(\t)缩进都被替换为单个空格( )。

这个命令可以作为string传递给\Clinner\Command\Command::fromString(),并返回一个表示此命令链的新的Command实例。

<?php

    use \Clinner\Command\Command;
    
    
    $commandString = 'cat /etc/hosts | grep localhost | tr -s "\t" " "';
    $command = Command::fromString($commandString);
    
    // This is equivalent to:
    $command = Command::create('cat', array('/etc/hosts'))
        ->pipe(
            Command::create('grep', array('localhost'))
        )
        -> pipe(
            Command::create('tr', array('-s', '"\t"', '" "'))
        );

然后您可以像往常一样使用这个新创建的Command实例,并将其与其他Command或甚至Callback进行管道操作。

要求

Clinner的唯一要求是PHP版本>= 5.3。

贡献

请随意fork这个repo并按您认为有用的任何方式改进它——欢迎Pull Requests!