I want to run curl command from my rust code to console terminal .. I have done this , but not succeeded; Here is my Rust Playground Link
use std::process::Command;
fn main() {
let output = Command::new("curl")
.arg("-X POST --data '{\"jsonrpc\":\"2.0\",\"method\":\"sayhello\",\"params\":[],\"id\":1}' H \"Content-Type: application/json\" http://127.0.0.1:17853")
.output().unwrap_or_else(|e| {
panic!("failed to execute process: {}", e)
});
if output.status.success() {
let s = String::from_utf8_lossy(&output.stdout);
print!("curl succeeded and stdout was:\n{}", s);
} else {
let s = String::from_utf8_lossy(&output.stderr);
print!("curl failed and stderr was:\n{}", s);
}
}
when I run this I received following output ;
curl failed and stderr was:
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
If you do command.arg('-X POST'), the string -X POST is passed as one argument to curl, but curl expects there to be two separate argument -X and POST. .arg is not going to separate argument by spaces like your shell does. Instead, you would want to do something like:
thanks for your time, but still have following error;
the trait bound `[&str; 4]: std::convert::AsRef<std::ffi::OsStr>` is not satisfied
--> src/main.rs:10:9
|
10 | .arg(&["-X", "POST" , "--data","'{\"jsonrpc\":\"2.0\",\"method\":\"sayhello\",\"params\":[],\"id\":1}' H \"Content-Type: application/json\" http://127.0.0.1:17853"])
| ^^^ the trait `std::convert::AsRef<std::ffi::OsStr>` is not implemented for `[&str; 4]`
|
= help: the following implementations were found:
<[T; 0] as std::convert::AsRef<[T]>>
<[T; 10] as std::convert::AsRef<[T]>>
<[T; 11] as std::convert::AsRef<[T]>>
<[T; 12] as std::convert::AsRef<[T]>>
and 30 others
= note: required because of the requirements on the impl of `std::convert::AsRef<std::ffi::OsStr>` for `&[&str; 4]`
thanks so much, it solve my problem, but still could not print let s = String::from_utf8_lossy(&output.stdout); means no output . Although I properly have given all args to my program
of this command curl -X POST --data '{"jsonrpc":"2.0","method":"sayhello","params":[],"id":1}' -H "Content-Type: application/json" http://127.0.0.1:17853, but no output..
However, If I run this command on terminal I can see the output.. {"jsonrpc":"2.0","result":"Hello, world","id":1}, but could not got through my program..
Because .args directly pass the argument to curl, your quotation marks will be passed to curl, which it won't understand. And you don't need these quotation marks, because you separated the arguments yourself.
Sorry to disturb you , I need one more help... that I want to pass some value to above command through my code like this... .args(format!(&["-X", "POST", "--data", "{\"jsonrpc\":\"2.0\",\"method\":\"sayhello\",\"params\":[**{}**],\"id\":1}" , "-H", "Content-Type: application/json", "http://127.0.0.1:17853"],myNo))
is this possible ? I think I am doing some mistake , because I am facing some errors.. Could you give me more time.. thanks in advance..
Although I think at this point you might want to look into generating JSON string in your code, rather than format!ing strings, which is 1. tedious and 2. error-prone.
Actually, I only need constant json format strings, I don't need to processing JSON string. If you think, still I must use JSON string, then I will follow your recommendation.
Anyhow, now code is working, although need double '{' and '}' i.e. &format!("{{\"jsonrpc\":\"2.0\",\"method\":\"sayhello\",\"params\":[{}],\"id\":1}}" which is i think required in format! macro.
Yeah, forgot about the need to escape {s by doubling. otherwise format! can't know whether a { is supposed to mean format placeholder or a literal {. Glad it worked.
By the way you can use raw string literals (r#"..."#) instead of classic string literals ("...") so that you don't even need to escape the inner double quotes:
thanks I have tried with above json string with raw string option (r#....#), its working and show its expected output. But when I tried with json, it passed successfully to my program but not produced expected output. Is something missing in my program..
fn main() {
let json = ::serde_json::json!({
"jsonrpc": 2.0,
"method": "sayhello",
"params": [],
"id": 1,
}).to_string();
let output = Command::new("curl")
// WORKING
// .args(&["-X", "POST", "--data", r#"{"jsonrpc":"2.0","method":"sayhello","params":[],"id":1}"# , "-H", "Content-Type: application/json", "http://127.0.0.1:17853"])
.args(
&["-X", "POST", "--data", json.as_str(),
"-H", "Content-Type: application/json", "http://127.0.0.1:17853"]
)
.output().unwrap_or_else(|e| {
panic!("failed to execute process: {}", e)
});
if output.status.success() {
let s = String::from_utf8_lossy(&output.stdout);
print!("curl succeeded and stdout was:\n{}", s);
} else {
let s = String::from_utf8_lossy(&output.stderr);
print!("curl failed and stderr was:\n{}", s);
}
output of above program is as below;
curl succeeded and stdout was:
{"jsonrpc":"2.0","error":{"code":-32600,"message":"Invalid request"},"id":1}
run your rust program targeting the port 4242 instead of 17853
Observe the output of socat
or now that I come to think of it, you can just create in your project folder a dump_args.sh script, that you make executable (chmod +x ./dump_args.sh), with the following contents:
#!/bin/bash
for arg in "$@"; do echo $arg; done
And run your rust program spawning the command ./dump_args.sh instead of curl