cli2
cli2

Reputation: 249

C# Piping Linux Command Output in Process

I am having trouble with the Process class to pipe a command on a Linux system.

I want to execute the following command: rpm2cpio repo.rpm | cpio -divm

I've tried

process.StartInfo.FileName = "rpm2cpio;
rocess.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.Arguments = "repo.rpm | cpio - idmv";

But the program hangs.

Similarly, I tried saving the output from rpm2cpio to a string or an output file and then pass that as the argument for the cpio command, but it also hangs.

process.StartInfo.FileName = "cpio";
rocess.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;

process.StartInfo.Arguments = "-idvm < output.txt";
// or
process.StartInfo.Arguments = "-idvm < " + rp2cpio_output;

What are some ways I can get this working? I saw this post with a solution, but it is on a Window's system. How do the same thing on Linux?

Upvotes: 4

Views: 1489

Answers (2)

Mintu Paul
Mintu Paul

Reputation: 41

Rather than directly writing to a file, you can simply use a StreamWriter to fetch the output in a stream buffer and then use that to write to the file. If the process still hangs, simply use the timeout command of linux to terminate the process. The following snippet may help after making a few changes:

ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
processStartInfo.FileName = "/bin/bash";
processStartInfo.WorkingDirectory = "/";                
string cmd = "timeout 1 cat > temp.txt";
var escapedArgs = cmd.Replace("\"", "\\\"");
processStartInfo.Arguments = $"-c \"{escapedArgs}\"";
processStartInfo.UseShellExecute = false;
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true;
processStartInfo.StandardErrorEncoding = System.Text.Encoding.UTF8;
processStartInfo.StandardInputEncoding = System.Text.Encoding.UTF8;
processStartInfo.StandardOutputEncoding = System.Text.Encoding.UTF8;
processStartInfo.UseShellExecute = false;                                               
process.StartInfo = processStartInfo;            
process.Start();                
stdIOWriter = process.StandardInput; 
stdIOWriter.WriteLine("Hey Fellas"); 
String error = process.StandardError.ReadToEnd();
String output = process.StandardOutput.ReadToEnd(); ```

Upvotes: 2

Matt Binz
Matt Binz

Reputation: 154

Setting process.StartInfo.RedirectStandardOutput=true will cause the program to redirect standard output to the stream process.StartInfo.StandardOutput. When this happens the program will hang until you read from standard output.

To get the behavior I think you are looking for, you just need to set RedirectStandardOutput=false. That way the pipes and redirects in your command will work as expected.

Upvotes: 1

Related Questions