bash pipes - I am trying to call script from c# - c#

I have a cygwin bash scripts that works:
#!/bin/sh
cd myc
cp Stats.txt Stats.txt.cpy;
cat Stats.txt.cpy | sort -n -k1 | gawk '{sum+=$2; print $0,sum}' > Stats.txt
I want to "call" it from C#:
string cmd="myscript.sh";
System.Diagnostics.Process proc = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo psi =
new System.Diagnostics.ProcessStartInfo(#"C:\Cygwin\bin\bash.exe");
psi.Arguments = cmd;
psi.WorkingDirectory = "C:\\cygwin\\home\\Moon";
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
proc.StartInfo = psi;
proc.Start();
string error = proc.StandardError.ReadToEnd();
string output = proc.StandardOutput.ReadToEnd();
this.textBox1.AppendText(error);
this.textBox1.AppendText(output);
It works fine from cygwin terminal BUT from C# I get:
Input file specified two times.
I suspect this is a pipes thing - can anyone help?

It was a path issue.
You need to set path in the script - otherwise it uses a different "non-cygwin" path and gets wrong commands.

Related

How to run vbs file c#

help me please! I've script which displays the windows activation key. When i use this:
Process scriptProc = new Process();
scriptProc.StartInfo.FileName = #"cscript";
scriptProc.StartInfo.WorkingDirectory = #"C://....";
scriptProc.StartInfo.Arguments = "//B //Nologo name_of_script";
scriptProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
scriptProc.Start();
Nothing happens, but if i run VBS file from cd, like this:
ProcessStartInfo cmdStart = new ProcessStartInfo();
cmdStart.FileName = "cmd.exe";
cmdStart.WindowStyle = ProcessWindowStyle.Normal;
cmdStart.Arguments = #"/k cd C://.... && start wininfo.vbs";
Process.Start(cmdStart);
I get an error that the registry key cannot be opened for reading
P.S. the script works if I just run it on the desktop

How to get the cmd.exe output as a string in C#?

I tried to get the output of passed argument in the cmd.exe via c# code. But when the code string outw = cmd.StandardOutput.ReadToEnd().ToString(); executing takes more and more time. Here my command prompt arguments work perfectly.
Here is my code
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
cmd.StandardInput.WriteLine("git init && git remote add gitlab https://gitlab.company.com/test2.git && git push gitlab --delete branchname");
cmd.StandardInput.WriteLine("git remote remove gitlab");
string outw = cmd.StandardOutput.ReadToEnd().ToString();//Here my code strucks
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
Where I made the mistake? I waited for more than 30 min but I did not get the output in the string outw. How could I get the output test as a string in string outw?

Run Bash Commands from Mono C#

I am trying to make a directory using this code to see if the code is executing but for some reason it executes with no error but the directory is never made. Is there and error in my code somewhere?
var startInfo = new
var startinfo = new ProcessStartInfo();
startinfo.WorkingDirectory = "/home";
proc.StartInfo.FileName = "/bin/bash";
proc.StartInfo.Arguments = "-c cd Desktop && mkdir hey";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start ();
Console.WriteLine ("Shell has been executed!");
Console.ReadLine();
This works best for me because now I do not have to worry about escaping quotes etc...
using System;
using System.Diagnostics;
class HelloWorld
{
static void Main()
{
// lets say we want to run this command:
// t=$(echo 'this is a test'); echo "$t" | grep -o 'is a'
var output = ExecuteBashCommand("t=$(echo 'this is a test'); echo \"$t\" | grep -o 'is a'");
// output the result
Console.WriteLine(output);
}
static string ExecuteBashCommand(string command)
{
// according to: https://stackoverflow.com/a/15262019/637142
// thans to this we will pass everything as one command
command = command.Replace("\"","\"\"");
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = "-c \""+ command + "\"",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
proc.WaitForExit();
return proc.StandardOutput.ReadToEnd();
}
}
This works for me:
Process.Start("/bin/bash", "-c \"echo 'Hello World!'\"");
My guess is that your working directory is not where you expect it to be.
See here for more information on the working directory of Process.Start()
also your command seems wrong, use && to execute multiple commands:
proc.StartInfo.Arguments = "-c cd Desktop && mkdir hey";
Thirdly you are setting your working directory wrongly:
proc.StartInfo.WorkingDirectory = "/home";

System.Diagnostics.Process pipe (vertical bar) not accepted as argument

I'm trying to execute this code using System.Diagnostics.Process. It works fine in command line. But in C# it's failing on the | character.
var myProcess = new Process();
var p = new ProcessStartInfo();
var sArgs = " -i emp.mp3 -f wav - | neroAacEnc -ignorelength -q 0.5 -if - -of emp.mp4";
p.FileName = "ffmpeg.exe";
p.CreateNoWindow = false;
p.RedirectStandardOutput = false;
p.UseShellExecute = false;
p.Arguments = sArgs;
myProcess.StartInfo = p;
myProcess.Start();
myProcess.WaitForExit();
It gives the following error:
Unable to find a suitable output format for '|': Invalid argument
I've looked around on stackoverflow and found the following hint but it is also not working:
var psi = new ProcessStartInfo("ffmpeg.exe");
psi.Arguments =
"\"-i emp.mp3 -f wav -\" | \"neroAacEnc -ignorelength -q 0.5 -if - -of emp.mp4\"";
psi.CreateNoWindow = false;
psi.UseShellExecute = false;
var process = new Process { StartInfo = psi };
process.Start();
process.WaitForExit();
gives the following error:
Unrecognized option 'i emp.mp3 -f wav -'
Failed to set value '|' for option 'i emp.mp3 -f wav -'
Thanks to Lee his comments, the problem has been resolved. Just invoke cmd.exe and pass it the full command:
var myProcess = new Process();
var p = new ProcessStartInfo("cmd.exe");
var sArgs = "/C ffmpeg.exe -i emp.mp3 -f wav - | neroAacEnc -ignorelength -q 0.5 -if - -of emp.mp4";
p.CreateNoWindow = false;
p.RedirectStandardOutput = false;
p.UseShellExecute = false;
p.Arguments = sArgs;
myProcess.StartInfo = p;
myProcess.Start();
myProcess.WaitForExit();

What is wrong in how I start the process?

When I run the following from cmd it runs ok
>mysql -h 134.86.157.132 -u sas vm < c:\vm.sql
When I try to do the same from code it does not work
ProcessStartInfo info = new ProcessStartInfo("mysql");
info.Arguments = #"-h 134.86.157.132 -u sas vm < c:\vm.sql";
info.Domain = "134.86.157.132";
info.UserName = "sas";
info.Arguments = #"vm < c:\vm.sql";
info.UseShellExecute = false;
Process.Start(info);
What am I doing wrong here? It does not work and I get some wrong password exception?
Edit:
I run it like this now
ProcessStartInfo info = new ProcessStartInfo("mysql");
info.UseShellExecute = false;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
info.Arguments = #"-h 134.86.157.132 -u sas vm < c:\vm.sql";
Process.Start(info);
and get following error The system cannot find the file specified
"-h 134.86.157.132 -u sas vm" are the arguments, don't use domain and username.
You also need to redirect the standard input stream to pass your vm.sql file in. See this example: ProcessStartInfo.RedirectStandardInput Property
Try it like this:
ProcessStartInfo info = new ProcessStartInfo("mysql");
info.Arguments = #"-h 134.86.157.132 -u sas vm < c:\vm.sql";
info.UseShellExecute = false;
Process.Start(info);
You're setting UseShellExecute to false, but it's the shell that interprets the "<" part to redirect stdin from a file.
Unless there's a specific reason why you need UseShellExecute to be false, set it to true. Alternatively, redirect standard input for the new process, and give it the data directly.
EDIT: As specified in other answers, keep the original arguments, and don't set Domain/UserName on the ProcessStartInfo. Those refer to Windows usernames and domains, not MySQL ones.
At that point you'll be able to set UseShellExecute to true with no ill effects, with any luck.
How about something like from this post:
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "cmd.exe";
info.RedirectStandardInput = true;
info.UseShellExecute = false;
p.StartInfo = info;
p.Start();
using (StreamWriter sw = new StreamWriter(p.StandardInput))
{
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("mysql -h 134.86.157.132 -u sas vm < c:\vm.sql");
}
}

Categories

Resources