It's a beautiful way to use powerful Linux/Unix tools in PHP

Overview

ShellWrap

What is it?

It's a beautiful way to use powerful Linux/Unix tools in PHP. Easily and logically pipe commands together, capture errors as PHP Exceptions and use a simple yet powerful syntax. Works with any command line tool automagically.

Features

  • Flexible and sexy syntax.
  • Exceptions are thrown if the executable returns an error.
  • Paths to binaries are automatically resolved.
  • All arguments are properly escaped.
  • Callback functions for streaming output.

Examples

 
require_once 'vendor/autoload.php';
use MrRio\ShellWrap as sh;

// List all files in current dir
echo sh::ls();

// Checkout a branch in git
sh::git('checkout', 'master');

// You can also pipe the output of one command, into another
// This downloads example.com through cURL, follows location, then pipes through grep to 
// filter for 'html'
echo sh::grep('html', sh::curl('http://example.com', array(
	'location' => true
)));

// Touch a file to create it
sh::touch('file.html');

// Remove file
sh::rm('file.html');

// Remove file again (this fails, and throws an exception because the file doesn't exist)

try {
	sh::rm('file.html');
} catch (ShellWrapException $e) {
	echo 'Caught failing sh::rm() call';
}


// This throws an exception, as 'invalidoption' is not a valid argument
try {
	echo sh::ls(array('invalidoption' => true));
} catch (ShellWrapException $e) {
	echo 'Caught failing sh::ls() call';
}

// Commands can be written multiple ways
sh::git('reset', array('hard' => true), 'HEAD');
sh::git('reset', '--hard', 'HEAD');
sh::git(array('reset', '--hard', 'HEAD'));

// Arguments passed in are automatically escaped, this expands to
// date --date '2012-10-10 10:00:00'
echo sh::date(array(
	'date' => '2012-10-10 10:00:00'
));

// If arg keys are one letter, is assumes one dash prefixing it
// date -d '2012-10-10 10:00:00'
echo sh::date(array(
	'd' => '2012-10-10 10:00:00'
));


?>

Example: Tailing a file and adding timestamps to output

You can stream the output of a command into a callback function. For example:

sh::tail('-f log', function($in) {
	echo "\033[32m" . date('Y-m-d H:i:s') . "\033[39m " . $in;
});

Make sure the file 'log' exists. This will output a timestamp, and the input. Try echoing into the log file.

The escape codes are to add a little colour to the terminal.

Interactive Shell

ShellWrap also ships with an interactive shell mode. You can access this by typing:

./bin/shellwrap

Warning

Don't use any user inputted data with these commands. Even with very paranoid filtering, you can't know all the potential pitfalls of each command you're using. Use your noggin.

Acknowledgements

Inspired by the Python project sh by Andrew Moffat

Comments
  • Original namespace

    Original namespace

    I'm using this wrapper for myself. I've created a composer package installable from packagist.org. I've created this branch to keep your namespace and contribute my changes. If you want them. Here is what I did:

    • added .gitignore
    • made it psr-0 compatible
    • ready to add to packagist.org
    • passed through php-cs-fixer (minor fixes, indentation, etc)
    • moved ShellWrap.php to src/MrRio for autoloading
    • moved examples to new directory
    • added LC_ALL=en_US to testDate() to avoid error in non-english environment

    NOTE: The diff on ShellWrap is the complete file due to directory changes..

    opened by guumaster 2
  • specify current working directory explicitly when executing shell commands

    specify current working directory explicitly when executing shell commands

    If you use function chdir() to change working directory to a different directory first, following two statements should still return same directories. However, in Travis CI they return different directories back (the 2nd one returns the directory where the PHP script was invoked).

    1. getcwd()
    2. (string) ShellWrap::pwd()

    Thus we need to have the 4th parameter (getcwd()) specified explicitly here, also ideally it's unnecessary.

    opened by deminy 0
  • Magic method __toString() must return a string

    Magic method __toString() must return a string

    In some PHP IDE (e.g., PhpStorm) you may see that method _\MrRio\ShellWrap::_toString() is highlighted with notification saying

    __toString() method must return a string

    This could be triggered with following code piece where no actual shell command invoked:

    <?php
    require_once __DIR__ . '/vendor/autoload.php';
    
    echo (new MrRio\ShellWrap());
    ?>
    

    Although in reality people may not make method calls like that, it's better to get it fix to make variables consistent. Property \MrRio\ShellWrap::$output should be initialized and used as a string but not an array, as in the fix.

    opened by deminy 0
  • Composer >1.3.0 compatibility

    Composer >1.3.0 compatibility

    I've opened an issue against Boris here, however, I am also going open an issue here for anyone else experiencing this. When using shell wrap with a composer version >1.3.0, PHP gets reloaded to disable XDebug and causes an error to be thrown in the terminal. E.g.,

    PHP Warning:  Module 'pcntl' already loaded in Unknown on line 0
    
    Warning: Module 'pcntl' already loaded in Unknown on line 0
    

    As Boris is only used for the interactive debugger, is there any chance of a workaround? Boris hasn't had any commits or changes in years, maybe Psysh would be a good drop-in replacement?

    opened by barchard 1
  • Skip saving output to variable when using callback function

    Skip saving output to variable when using callback function

    My case is currently that I'm streaming use log files using sh::cat() and using a callback closure to pass the data (after a filter) to an PHPExcel object. The log files can easily get over 500MB. Looking through the code it seems that even when using a callback/closure, the output of the cat command still gets saved to a variable, making memory usage go up and up.

    I cannot grep on the log files as it's filled with IDs, possible conflicting with other data in the same line.

    Is this currently possible in a less memory consuming way? Else I'm also willing to submit a PR with some extra functionality on this. Reasoning could be that when streaming through a closure, no need is left to save things to the self::$output variable.

    opened by stefandoorn 0
  • Alternative piping syntax

    Alternative piping syntax

    echo sh::grep('html', sh::curl('http://example.com', array(
        'location' => true
    )));
    

    In current API I don't like 2 things:

    1. inverted order of commands (grep -> curl) when actually curl | grep is intended
    2. "wrap" or functional style a(b(c()))

    It would be nice to have fluid API like this

    sh::curl('http://example.com')->pipe('grep', 'html')->pipe('whatever');
    

    or

    sh::curl('http://example.com')->sh('grep', 'html')->sh('whatever');
    

    or

    sh::curl('http://example.com')->grep('html')->whatever();
    

    @MrRio what do you think?

    opened by Mihailoff 1
Releases(0.4.1)
Owner
James Hall
James Hall
A CLI tool to check whether a specific composer package uses imported symbols that aren't part of its direct composer dependencies

A CLI tool to analyze composer dependencies and verify that no unknown symbols are used in the sources of a package. This will prevent you from using "soft" dependencies that are not defined within your composer.json require section.

Matthias Glaub 722 Dec 30, 2022
đź’Ą Collision is a beautiful error reporting tool for command-line applications

Collision was created by, and is maintained by Nuno Maduro, and is a package designed to give you beautiful error reporting when interacting with your

Nuno Maduro 4.2k Jan 5, 2023
Console - The Console component eases the creation of beautiful and testable command line interfaces.

Console Component The Console component eases the creation of beautiful and testable command line interfaces. Sponsor The Console component for Symfon

Symfony 9.4k Jan 7, 2023
Command-Line Interface tools

Aura.Cli Provides the equivalent of request ( Context ) and response ( Stdio ) objects for the command line interface, including Getopt support, and a

Aura for PHP 102 Dec 31, 2022
This bundle provides new generator command line tools for doctrine generator.

GenBundle This bundle provides new generator command line tools for doctrine generator, extending SensioGeneratorBundle. php bin/console gen:generate:

Koldo Picaza 5 Sep 6, 2016
A powerful command line application framework for PHP. It's an extensible, flexible component, You can build your command-based application in seconds!

CLIFramework CLIFramework is a command-line application framework, for building flexiable, simple command-line applications. Commands and Subcommands

Yo-An Lin 428 Dec 13, 2022
Simple but yet powerful library for running almost all artisan commands.

:artisan gui Simple but yet powerful library for running some artisan commands. Requirements Laravel 8.* php ^7.3 Installation Just install package: c

null 324 Dec 28, 2022
Termage provides a fluent and incredibly powerful object-oriented interface for customizing CLI output text color, background, formatting, theming and more.

Termage provides a fluent and incredibly powerful object-oriented interface for customizing CLI output text color, background, formatting, theming and

TERMAGE 75 Dec 20, 2022
PHP Interminal is a command-line tool that gives you access to PHP Internals discussions in your terminal.

PHP Interminal is a command-line tool that gives you access to PHP Internals discussions in your terminal. ??

Nuno Maduro 32 Dec 26, 2022
PHP Reverse Shell > reverse-shell.php

PHP Reverse Shell > reverse-shell.php PHP Cmd Shell > cmd.php JPG cmd Shell > cmd.jpg /etc/passwd Pulling Shell > etc-passwd.php Configuration Pulling

Dark-Network 5 Feb 24, 2022
Web Shell Detector – is a php script that helps you find and identify php/cgi(perl)/asp/aspx shells.

Web Shell Detector – is a php script that helps you find and identify php/cgi(perl)/asp/aspx shells. Web Shell Detector has a “web shells” signature database that helps to identify “web shell” up to 99%. By using the latest javascript and css technologies, web shell detector has a light weight and friendly interface.

Maxim 763 Dec 27, 2022
A REPL for PHP

PsySH PsySH is a runtime developer console, interactive debugger and REPL for PHP. Learn more at psysh.org and in the manual. PsySH manual ?? Installa

Justin Hileman 9.4k Jan 6, 2023
CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due

PHP Cron Expression Parser NOTE This fork has been deprecated and development moved to https://github.com/dragonmantank/cron-expression. More informat

Michael Dowling 4.9k Jan 5, 2023
A tiny REPL for PHP

Boris A tiny, but robust REPL for PHP. Announcement: I'm looking to add one or two additional collaborators with commit access. If you are actively in

null 2.2k Dec 30, 2022
PHP's best friend for the terminal.

Running PHP from the command line? CLImate is your new best bud. CLImate allows you to easily output colored text, special formats, and more. Installa

The League of Extraordinary Packages 1.8k Dec 30, 2022
An Elegant CLI Library for PHP

Commando An Elegant PHP CLI Library Commando is a PHP command line interface library that beautifies and simplifies writing PHP scripts intended for c

Nate Good 793 Dec 25, 2022
Lovely PHP wrapper for using the command-line

ShellWrap What is it? It's a beautiful way to use powerful Linux/Unix tools in PHP. Easily and logically pipe commands together, capture errors as PHP

James Hall 745 Dec 30, 2022
Cilex a lightweight framework for creating PHP CLI scripts inspired by Silex

Cilex, a simple Command Line Interface framework Cilex is a simple command line application framework to develop simple tools based on Symfony2 compon

null 624 Dec 6, 2022
[ABANDONED] PHP library for executing commands on multiple remote machines, via SSH

#Shunt Inspired by Ruby's Capistrano, Shunt is PHP library for executing commands on multiple remote machines, via SSH. Specifically, this library was

The League of Extraordinary Packages 436 Feb 20, 2022