addOption("list-filters", null, InputOption::VALUE_NONE, "List the defined filters"); $this->addOption("input", "i", InputOption::VALUE_REQUIRED, "Input file or fd, for reading from", 0); $this->addOption("output", "o", InputOption::VALUE_REQUIRED, "Output file or fd, for writing to", 1); $this->addOption("error", "e", InputOption::VALUE_REQUIRED, "Error file or fd, for progress report and status", 2); $this->addArgument("filter", InputArgument::OPTIONAL, "Pipe filter"); $this->addArgument("args", InputArgument::OPTIONAL|InputArgument::IS_ARRAY, "Arguments to the script"); $this->registerDefaultFilters(); $this->setHelp(self::$HelpText); } private function registerDefaultFilters() { register_filter("base64encode", "base64_encode"); register_filter("base64decode", "base64_decode"); register_filter("passwordhash", function ($in) { $trimmed = rtrim($in, "\n\r"); $hashed = password_hash($trimmed, PASSWORD_BCRYPT); return str_replace($trimmed, $hashed, $in); }); register_filter("progress", ProgressFilter::class); } protected function execute(InputInterface $input, OutputInterface $output) { $env = $this->getEnvironment(); if ($input->getOption("list-filters")) { $output->writeln(join(" ", get_registered_filters())); return Command::SUCCESS; } $fdin = $input->getOption("input"); $fdout = $input->getOption("output"); $fderr = $input->getOption("error"); $filterargs = $input->getArgument('args'); $args = []; foreach ($filterargs as $arg) { if (str_contains($arg, '=')) { [$k,$v] = explode("=", $arg, 2); $args[$k] = $v; } else { if (str_starts_with($arg, 'no-')) { $args[substr($arg,3)] = false; } else { $args[$arg] = true; } } } $filtername = $input->getArgument("filter"); if ($filtername) { $filter = get_filter($filtername, $args); } else { $filter = null; } $pipeline = new Pipeline(); $pipeline->setInputFile($fdin); $pipeline->setOutputFile($fdout); if ($filter) { $pipeline->addFilter($filter); } $pipeline->run(); /* $fin = fopen($fdin, "rb"); $fout = fopen($fdout, "wb"); while (!feof($fin)) { $buf = fgets($fin); if (is_callable($filter)) $buf = $filter($buf); fputs($fout, $buf); } */ return Command::SUCCESS; } } PipeCommand::$HelpText = <<pipe command is used to filter data, or to track piping of data. \$ echo "mypassword" | spark pipe hashpassword > hashedpassword.txt \$ cat file.sql | spark pipe sqlinfo | mysql \$ cat input | spark pipe progress sizefrom=input | somecommand Registering filters To register a new filter, use the register_filter helper function: register_filter("myfilter", function (\$in) { return strtolower(\$in); }); The filter will be available like any built-in: \$ cat file | spark pipe myfilter > outfile HELP;