adambrett / php-shell-wrapper Goto Github PK
View Code? Open in Web Editor NEWA high level object-oriented wrapper over the program execution functions in PHP.
License: BSD 3-Clause "New" or "Revised" License
A high level object-oriented wrapper over the program execution functions in PHP.
License: BSD 3-Clause "New" or "Revised" License
Hey there,
I was wondering how I could do an argument with a = instead of a space?
--arg=value
vs --arg value
I suggest add FakeRunner
which will be emulate running the command.
It must be used in unit and integration tests.
Also i suggest add EchoFakeRunner
which will be not execute command but prints the command. It will be used when application runs with --dry-run
argument
If application wrote with IOC principle it will be easy to substitute real runner to fake runner.
Hi Adam!
Do you have anything that will connect output of one command to input of another?
Something like pipeline in bash?
echo 123 | grep 2 | cat
Or can you suggest how to better extend your lib to add such thing?
Hi,
Is it possible to get the exit code of the executed command?
I know it's hard, I tried it myself, and there didn't seem to be a reliable way to do that. But php-shellcommand seems to have solved this problem somehow.
use AdamBrett\ShellWrapper\Runners\Exec;
use AdamBrett\ShellWrapper\Command\Builder as CommandBuilder;
$shell = new Exec();
$command = new CommandBuilder('echo');
$command->addParam('Hello World');
$shell->run($command);
Running this throws the error:
Argument 1 passed to AdamBrett\ShellWrapper\Runners\Exec::run() must be an
instance of AdamBrett\ShellWrapper\Command, instance of
AdamBrett\ShellWrapper\Command\Builder given, called in test.php
I found a solution to add multiple arguments with the same name.
$arg = new Argument($name, [$val1, $val2]);
But there is too hard to find out this approach without reading documentation. There is no apparent that second argument must be an array.
Let me show another possible way:
$cmd = new Command(‘docker build’);
$cmd->addArgument(new Argument(‘tag’, ‘latest’);
$cmd->addArgument(new Argument(‘tag, ‘3.5.0’);
The typical way to use multiple arguments are loops. Let me add some example
First way
$cmd = new Command(‘docker build’);
foreach($tags as $tag) {
$cmd->addArgument(new Argument(‘tag’, $tag->getVersion());
}
Second way
$cmd = new Command(‘docker build’);
$attr = [];
foreach($tags as $tag) {
$attr[] = $tag->getVersion();
}
$cmd->addArgument(new Argument(‘tag’, $arrt);
in my opinion In this case the first way is more object oriented. In another case second way is preferable. Because i suggest add another way for multiple attributes and save “old” way.
How we can fix this?
As easy as ABC
ArgumentCollection
file now:
public function addArgument(Argument $argument)
{
$this->arguments[$argument->getName()] = $argument;
}
I suggest replace it to something like this:
public function addArgument(Argument $argument)
{
$this->arguments[md5((string) $argument] = $argument;
}
Also it will need to fix some unit-tests.
Will you approve this proposal? If yes i will create merge request.
Thanks a lot!
Hi,
In webserver context, environment variable are often skipped or wrong, because forced by the webserver process itself.
So it's necessary to prefix any executed command line by a set of environment variable assignments.
eg: the environment variable 'HOME' is missing when php is run under Apache.
A function like addEnvironmentVariable('HOME', '/home/username')
could prefix any command line with:
$> HOME="/home/username" ....
So, could you add this support ?
Many thanks
Is there a way to add a timeout to the execution of commands or set them to run asynchronously?
Moving files with the mv command and a wildcard fails because of added quotes. Here's an example:
$moveCommand = new CommandBuilder('mv');
$moveCommand
->addParam('/my/source/*')
->addParam('/my/destination');
$shell = new ShellExec();
$shell->run($moveCommand);
The command that is actually run is this:
mv '/my/source/*' '/my/destination'
Which throws this error:
mv: rename /my/source/* to /my/destination/*: No such file or directory
I guess what's happening is the single quotes are disabling the wildcard interpretation. I think a way to fix this is to allow developers to disable escaping when adding a param.
Hi,
I'm trying to run the unit tests for your library here. However, I'm having some difficulty, as many of them fail, like so:
1) AdamBrett\ShellWrapper\Tests\CommandTest::testCanAddArgument
Command should have arguments
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'ls --test 'value''
+'ls --test "value"'
This is because the escapeshellargs()
function you use on argument values escapes them differently on Windows. Particularly, it surrounds the values with double quotes instead of single.
Also, I've had trouble running tests at all, since the bootstrap seems to require an autoload.php
file in a rather strange location. Temporarily got around this by modifying the required path.
Currently missing documentation on how to capture the output. I can see a table; https://github.com/adambrett/php-shell-wrapper/#runners that touches the subject, but I would like an example in code.
Hi,
I try to use your wrapper for generating a pdf(la)tex command, but, in fact, pdftex mix arg, flag, param...
pdflatex -synctex=1 -interaction=nonstopmode -output-directory=path_to_dir somelatexfile.tex
So, I can't use your wrapper ; it generate, for example :
pdflatex -synctex '1' -interaction 'nonstopmode' -output-directory 'path_to_dir' 'somelatexfile.tex'
I see you provide interfaces for Command only ; is it possible to do it for other elements (Value, Flag, Argument...) ? -> it will be easy to create a "non-standard" behavior like in my case, like :
Value::__toString()
use escapeshellarg
or not...Anyways, your lib is very usefull ! =)
Thanks
Case: somecommand -a 5 -b 6 --something 's t r i n g'
I would like to use your package to send scripts to the background. This way I can keep executing the php script without the shell script blocking. Normally I use > /dev/null 2>/dev/null &
. Anyway to achieve this?
Is there any way to get output during execution of long running command?
The Arguments collection stores the arguments in an associative array where the argument name is the key. This causes that if I try to set a second argument with a name that has already been set, the first argument value will be overridden by the second.
Any reason why only one argument per each name can be added? Or is there a way to set multiple arguments with the same name in the current implementation?
I think there are many cases when you need to add multiple arguments with the same name, for example:
rsync -avz --exclude '.git*' --exclude 'cache' source/ destination/
curl --header 'Accept-Charset: utf-8' --header 'Content-Type: application/x-www-form-urlencoded' http://www.domain.com
raspistill --output 'image.jpg' --exif 'IFD0.Artist=Boris' --exif 'GPS.GPSAltitude=1235/10'
I am confused when i using Runner interface. I try to explain the problem.
My code is:
public function showFileList(Runner $runner)
{
$cmd = new Command('ls')
$exitCode = $this->runner->run($cmd);
if (0 != $exitCode) {
throw ExecutionCommandException::executionFauled($cmd, $runner->getStandardOut());
}
}
If execution failed i wanna get output and error string. But Runner
Interface does't contains this methods. And this is true way.
But how can i gets this messages? Obvious way is public function showFileList(StandardOut $runner)
but it does't contains method run()
. And Does't contains getStandardError
too.
I offer add hierarchy of Runners:
interface ReturnedValueRunner extends Runner { ...
interface ReturnedValueRunnerWithStandardOutput extends ReturnedValueRunner { ...
interface ReturnedValueRunnerWithStandardAndErrorOutput extends ReturnedValueRunnerWithStandardOutput { ...
I know, this is not graceful solution, but i dont know another way. May be i missed something?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.