I have a simple script file test.sh as follow at location /Users/my_user/scripts/:
#!/bin/bash
ls /Users/my_user/my_folder
I just want to run this script file in rust. I tried the following code but i don't understand the correct syntax:
use std::process::Command;
#[tokio::main]
async fn main() {
Command::new("sh")
.current_dir("/Users/my_user/scripts/test.sh")
.spawn()
.expect("sh command failed to start");
}
Do you have any idea? May be I am confused with Command logic
I think this is what you're looking for. If you look at the Rust docs at https://doc.rust-lang.org/std/process/struct.Command.html, it's arg instead of current_dir that makes sense for your use case since you want to pass arguments to the sh command (which works with -C).
Command::new("sh")
.arg("-C")
.arg("/Users/my_user/scripts/test.sh")
.spawn()
.expect("sh command failed to start");
Related
I am trying to create a function that installs homebrew by running install.sh using std::process::Command:
let output = Command::new("bash")
.arg("install.sh")
.output()
.expect("brew install failed");
println!("command output: {:?}", output);
This prints the following output, which is a prompt asking for the user's password, in this case mine.
command output: "==> Checking for `sudo` access (which may request your password).\nNeed sudo access on macOS (e.g. the user blah needs to be an Administrator)!\n"
How do I pass in the password to the command and continue with the installation? Basically, I am looking for a way to emulate the shell script's expect function using the Command struct. Is it possible?
From the answer to How do I invoke a system command in Rust and capture its output?, I can execute a command which itself spawns a shell to execute commands.
use std::process::Command;
Command::new("sh")
.spawn()
.expect("sh command failed to start");
Is it possible to execute commands from Rust in this newly gained shell?
let mut child = Command::new("sh").stdin(Stdio::piped())
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
child.stdin
.as_mut()
.ok_or("Child process stdin has not been captured!")?
.write_all(b"something...")?;
let output = child.wait_with_output()?;
Source: External Command in The Rust Cookbook.
I would like to execute any bash command. I found Command::new but I'm unable to execute "complex" commands such as ls ; sleep 1; ls. Moreover, even if I put this in a bash script, and execute it, I will only have the result at the end of the script (as it is explain in the process doc). I would like to get the result as soon as the command prints it (and to be able to read input as well) the same way we can do it in bash.
Command::new is indeed the way to go, but it is meant to execute a program. ls ; sleep 1; ls is not a program, it's instructions for some shell. If you want to execute something like that, you would need to ask a shell to interpret that for you:
Command::new("/usr/bin/sh").args(&["-c", "ls ; sleep 1; ls"])
// your complex command is just an argument for the shell
To get the output, there are two ways:
the output method is blocking and returns the outputs and the exit status of the command.
the spawn method is non-blocking, and returns a handle containing the child's process stdin, stdout and stderr so you can communicate with the child, and a wait method to wait for it to cleanly exit. Note that by default the child inherits its parent file descriptor and you might want to set up pipes instead:
You should use something like:
let child = Command::new("/usr/bin/sh")
.args(&["-c", "ls sleep 1 ls"])
.stderr(std::process::Stdio::null()) // don't care about stderr
.stdout(std::process::Stdio::piped()) // set up stdout so we can read it
.stdin(std::process::Stdio::piped()) // set up stdin so we can write on it
.spawn().expect("Could not run the command"); // finally run the command
write_something_on(child.stdin);
read(child.stdout);
I've my program in bash and I want to launch a node program to get the string that it return, like in this way:
#!/bin/bash
mystring=$( node getString.js)
mplayer $mystring
Googling I found that I should inlcude
#!/usr/bin/env node
But I need to use string to give it to mplayer.. any ideas?
Solution
As Zac suggesting (and thanks to this link) I solved my problem in this way:
script.sh
#!/bin/bash
mplayer ${1}
script.js
/* do whatever you need */
var output="string"
var sys = require('sys');
var exec = require('child_process').exec;
function puts(error, stdout, stderr) { sys.puts(stdout); }
exec("./script.sh " + output, puts);
Consider simply writing an executable Node script (with the #!/bin/env node line), and, instead of using Bash, just use Node to run the external UNIX command. You can use the child_process module for this, as illustrated in this example. This question is also helpful when debugging shell-style subcommands in Node scripts.
If your example really is all you need to do in Bash, this should be sufficient. The #!/bin/env node line allows your script, once marked as executable, to run as its own program, without having to be invoked with node.
Alright, so let's say I have a .bash file with this inside of it
lib.bash
#!/bin/bash
function hello_world {
echo "Hello World!"
}
That file won't be called on it's own, instead it'll be called via another bash file, i.e
Startup.bash
#!/bin/bash
bash lib.bash
hello_world
But, if I run Startup.bash I get the error: hello_world: command not found
What am I doing wrong, or is it not possible to do what I'm trying to do on bash.
You can use this command in your startup.bash:
source lib.bash
the source command runs the file in the current shell environment, unlike using bash lib.bash (or . lib.bash) which creates a new, separate environment for that script (and only that script) and is why the function is not carried over.
(source)
why don't you call the function directly inside of the first script?
It would look something like this:
#!/bin/bash
function hello_world {
echo "Hello World!"
}
hello_world
If it is a simple script, shouldn't be a problem at all.
Otherwise try the source command, like minerz029 suggested :)
See if this could be helpful to you as well:
Shell Script Loader