How do I compose pipes?

Ali Çehreli acehreli at yahoo.com
Thu Jan 28 17:18:46 UTC 2021


On 1/28/21 2:16 AM, Anthony wrote:

 > auto p = pipeProcess("ls");
 > auto q = pipeProcess("cat", stdin = p.stdout); //it would be good to do

That would work if `cat` received the *contents* of the files (and with 
a "-" command line switch). Since `ls` produces file names, you would 
have to make the complete `cat` command line from `ls`'s output.

 > Do I need to manually extract the output from pipes.stdin.readln

Seems to be so for the `ls | cat` case. But the following `find | grep` 
example shows how two ends of pipes can be connected:

import std.stdio;
import std.process;
import std.range;

// BONUS: Enable one of the following lines to enjoy an issue.
// version = bonus_bug;
// version = bonus_bug_but_this_works;

void main() {
   // Writes to 'a':
   auto a = pipe();
   auto lsPid = spawnProcess([ "find", "."], stdin, a.writeEnd);
   scope (exit) wait(lsPid);

   // Reads from 'a', writes to 'b':
   auto b = pipe();
   auto catPid = spawnProcess([ "grep", "-e", `\.d$` ], a.readEnd, 
b.writeEnd);
   scope (exit) wait(catPid);

   version (bonus_bug) {
     // Fails with the following error.
     //
     // "/usr/include/dmd/phobos/std/typecons.d(6540): Error:
     // `"Attempted to access an uninitialized payload."`"
     writefln!"Some of the D source files under the current 
directory:\n%-(  %s\n%)"(
       b.readEnd.byLine);

   } else version (bonus_bug_but_this_works) {
     // Note .take at the end:
     writefln!"Some of the D source files under the current 
directory:\n%-(  %s\n%)"(
       b.readEnd.byLine.take(1000));

   } else {
     // The results are read from 'b':
     writeln(b.readEnd.byLine);
   }
}

I've discovered a strange issue, which can be observed by uncommenting 
the 'version = bonus_bug;' line above. But comment that one back in and 
uncomment the next line, now it works. (?)

Ali



More information about the Digitalmars-d-learn mailing list