how to run bash cmd in dot.net core - bash

i am using dotnet-core 1.1. centos bash
any way to run the grep or wget and retrieve the result?
like cmd in windows, but i need grep realtime log files
System.Diagnostics.Process.Start("notepad.exe")

You can start a process to grep and retrieve the result, you can refer the following code.
System.Diagnostics.ProcessStartInfo procStartInfo;
procStartInfo = new System.Diagnostics.ProcessStartInfo("/bin/bash", "-c \"cat myfile.log | grep -a 'dump f'\"");
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
// Get the output into a string
result = proc.StandardOutput.ReadToEnd();

I believe System.Diagnostics.Process.Start(..) which is in the System.Diagnostics.Process nuget package can take a ProcessStartInfo type as one of the overloads. That type has the following properties when set to true will redirect the logs to a stream in the Process type that is returned by System.Diagnostics.Process
var proc = System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo() {
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true
} );
proc.StandardError //stream with stderror
proc.StandardInput //stream with stdin
proc.StandardOutput //stream with stdout
Shameless plug, I also made a package that easily abstracts opening things on mac/win/linux basically abstracting xdg-open (ubuntu), open (mac), cmd.exe (win) so you don't have to think about it
https://github.com/TerribleDev/Opener.Net

Related

Running bash script from Deno

Let’s say I’ve got this super useful and advanced bash script:
#!/usr/bin/env bash
echo What is your name?
read name
echo What is your age?
read age
When I try to run it from Deno with a simple script like this:
const process = Deno.run({
cmd: [`./bash.sh`],
stdin: "piped",
stdout: "piped",
});
const decoder = new TextDecoder();
const output = await process.output()
const parsed = decoder.decode(output);
console.log(parsed);
It returns nothing, but if I simplify the Deno script to the first line of the bash script it returns the output just fine
const process = Deno.run({
cmd: [`echo`, `What is your name?`],
stdin: "piped",
stdout: "piped",
});
const decoder = new TextDecoder();
const output = await process.output()
const parsed = decoder.decode(output);
console.log(parsed);
Why is this? I’d assume since the start of the bash file and the single line command both start with echo it would return the same result twice
Version 1.5 of deno added the prompt function which allows you to completely remove the need for shelling out to a different program and handling inter-process communication via stdin/stdout.
let name: string | null = null;
let age: string | null = null;
while (name === null) {
name = prompt("What is your name?");
}
while (age === null) {
age = prompt("What is your age?");
}
console.log(`you are ${name}, ${age}yo`);
Your code is telling Deno to set up the subprocess to expect piped stdin -- but never providing it any content on stdin! Consequently, it hangs in the very first read.
If we take that out (letting stdin be passed through from the parent process), and do in fact answer the two prompts on the parent process's stdin, everything works perfectly:
deno run --allow-run run-bash.js <<'EOF'
A Nony Mouse
3
EOF
...with run-bash.js containing:
const process = Deno.run({
cmd: [`./bash.sh`],
stdout: "piped",
});
const decoder = new TextDecoder();
const output = await process.output()
const parsed = decoder.decode(output);
console.log(parsed);
...and your bash.sh unchanged. output thus captures the two prompts (What is your name? and What is your age?), and forwards them to the javascript interpreter's stdout as-requested.
You have to call bash to call your script
( of course with --allow-run option )
like :
const process = Deno.run({
cmd: ["bash","bash.sh"],
stdin: "piped",
stdout: "piped",
});
const decoder = new TextDecoder();
const output = await process.output()
const parsed = decoder.decode(output);
console.log(parsed);

Workaround to call "airport -s" from Swift OSX app?

I'm working on an alternative to the wireless network organization and diagnostics utilities provided by Apple. So far it's going fairly well. I'm able to pull and store the current network, some network details, password, and location data and store it in an encrypted realm.
The area I'm running into issues with is being able to access a list of the networks that are currently in range of the computer. I know this can be accessed by using the "airport -s" command from the terminal. My initial plan was to call this command from an NSTask and parse and store the results. However, after hours of tinkering and googling and coming up empty, I finally came upon Objective-C: NSCommand "airport -s" returning empty which seems to reflect what I'm seeing.
I've to get around this by writing a quick bash script to store in my bundle resources and call from an NSTask and return the output, or even to call a script that will write the output from "airport -s" to a .txt file in the bundle resources... but these all seem to fail when initiated from an NSTask even though they all run fine from the terminal.
func runCommand(cmd : String, args : String...) -> (output: [String], error: [String], exitCode: Int32) {
var output : [String] = []
var error : [String] = []
let task = NSTask()
task.launchPath = cmd
task.arguments = args
let outpipe = NSPipe()
task.standardOutput = outpipe
let errpipe = NSPipe()
task.standardError = errpipe
task.launch()
let outdata = outpipe.fileHandleForReading.readDataToEndOfFile()
if var string = String.fromCString(UnsafePointer(outdata.bytes)) {
string = string.stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet())
output = string.componentsSeparatedByString("\n")
}
let errdata = errpipe.fileHandleForReading.readDataToEndOfFile()
if var string = String.fromCString(UnsafePointer(errdata.bytes)) {
string = string.stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet())
error = string.componentsSeparatedByString("\n")
}
task.waitUntilExit()
let status = task.terminationStatus
return (output, error, status)
}
Is the method I'm using elsewhere to utilize NSTask. I'm attempting get a list of nearby networks with the following code:
func findNearby() -> String {
var checkNearby = sb.runCommand("/bin/sh", args: "-c", "sh '/Users/<username>/Library/Containers/com.user.app/Data/Library/Application Support/getnearby.sh'")
if checkNearby.output != [] {
return checkNearby.output[0]
}
return "could not access airport"
}
Is there an issue with my implementation of NSTask that is causing these scripts to time out, or is Apple really going through all the trouble to stop me from calling "airport -s" from NSTask?
Are there any alternatives to "airport -s" I could try?
Note: I know I'm not really storing the .sh file in my Resources, this location was just temporary while I tried to figure out a solution.

print pdf directly to printer windows

I have a windows app that prints pdfs directly to a printer. Everything is working but for some reason for each pdf to print I see the pdf reader Nitro Pro pop up in the background then close.
Is there a way to keep the window from poping up. It does not seem to effect the over application but just kind of annoying.
private void PrintDocument(string printer, string fileName)
{
ProcessStartInfo info = new ProcessStartInfo
{
Arguments = "\"" + printer + "\"",
Verb = "PrintTo",
FileName = fileName,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = true
};
Process p = new Process { StartInfo = info };
p.Start();
p.WaitForExit(5000);
if (p.HasExited == false)
{
p.Kill();
}
}
This is not possible.
Windows can't print a file directly, it relies on a program to do so. It will use whatever application has configured itself to handle the PrintTo verb for the particular file extension. In your case it appears the application is Nitro Pro.
It's possible that you can find and install an application that can print the file without opening a window to do so, but that's beyond the scope of StackOverflow.

How to run FFMPEG at my web host server

I want to perform some video process at my web host server. I don't think the web host server will allow me to execute an exe file for security reasons.
Should I use SharpFFMpeg?
I have downloaded SharpFFMpeg. But it's lacking a proper documentation.
Can someone give one example how to perform a conversion from one video format to another?
I have written my execution program, but the compiler says it cannot file the file specified. What's wrong with it?
string command = #"D:\Recorded TV\ffmpeg.exe -i ""Australia's Toughest Police_QUEST_2013_04_17_21_57_00.wtv"" -s 800x400 throughCS.mp4";
try
{
ProcessStartInfo psi = new ProcessStartInfo("\"" + command + "\"");
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
Process proc = new Process();
proc.StartInfo = psi;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();
tb1.Text = result;
Debug.WriteLine(result);
}

Read Windows Command Prompt STDOUT

I have a command line application that runs on a windows server. The command prompt remains open when the program is running, and log messages are output to the command prompt window as the program functions.
My need is to read the messages that appear on the command prompt as the program runs, and then run particular commands if a specific set of words appear in the messages.
What's the easiest way to do this on a windows machine? (without modifying the app)
Reading those two posts will give you the solution:
ProcessStartInfo
Capturing console output.
The idea is to to run your app (not modifying it) from your new app (written in C#) and redirect its input-output here, reading and writing as you please.
An example could be:
Process proc;
void RunApp()
{
proc = new Process();
proc.StartInfo.FileName = "your_app.exe";
proc.StartInfo.Arguments = ""; // If needed
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.OutputDataReceived += new DataReceivedEventHandler(InterProcOutputHandler);
proc.Start();
proc.WaitForExit();
}
void InterProcOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
// Read data here
...
// Send command if necessary
proc.StandardInput.WriteLine("your_command");
}

Resources