diff --git a/doc/watchexec.1 b/doc/watchexec.1 index 0ff7805..393c6c0 100644 --- a/doc/watchexec.1 +++ b/doc/watchexec.1 @@ -35,7 +35,7 @@ Sends the specified signal (e\.g\. \fBSIGKILL\fR) to the child process\. Default . .TP \fB\-n\fR, \fB\-\-no\-shell\fR -Execute command directly, do not use \fBsh -c\fR\. This is especially useful in combination with \fB--signal\fR, as the signal is then send directly to the specified command\. While \fB--no-shell\fR is a little more performant than the default, it prevents using shell-features like pipes and redirects\. +Execute command directly, do not wrap it in \fBsh -c\fR resp\. \fBcmd.exec /C\R\. This is especially useful in combination with \fB--signal\fR, as the signal is then send directly to the specified command\. While \fB--no-shell\fR is a little more performant than the default, it prevents using shell-features like pipes and redirects\. . .TP \fB\-i\fR, \fB\-\-ignore\fR \fIpattern\fR diff --git a/doc/watchexec.1.html b/doc/watchexec.1.html index ccd0f27..4fc28b7 100644 --- a/doc/watchexec.1.html +++ b/doc/watchexec.1.html @@ -89,7 +89,7 @@
-e, --exts extensions

Comma-separated list of file extensions to filter by. Leading dots are allowed (.rs) are allowed. (This is a shorthand for -f).

-f, --filter pattern

Ignores modifications from paths that do not match pattern. This option can be specified multiple times, where a match on any given pattern causes the path to trigger command.

-s, --signal SIGNAL

Sends the specified signal (e.g. SIGKILl) to the child process. Defaults to SIGTERM.

-
-n, --no-shell

Execute command directly, do not use sh -c. This is especially useful in combination with --signal, as the signal is then send directly to the specified command. While --no-shell is a little more performant than the default, it prevents using shell-features like pipes and redirects.

+
-n, --no-shell

Execute command directly, do not wrap it in sh -c resp. cmd.exec /C. This is especially useful in combination with --signal, as the signal is then send directly to the specified command. While --no-shell is a little more performant than the default, it prevents using shell-features like pipes and redirects.

-i, --ignore pattern

Ignores modifications from paths that match pattern. This option can be specified multiple times, and a match on any pattern causes the path to be ignored.

-w, --watch path

Monitor a specific path for changes. By default, the current working directory is watched. This may be specified multiple times, where a change in any watched directory (and subdirectories) causes command to be executed.

-r, --restart

Terminates the child process group if it is still running when subsequent file modifications are detected. By default, sends SIGTERM; use --kill to send SIGKILL.

diff --git a/doc/watchexec.1.ronn b/doc/watchexec.1.ronn index 0ce9e35..7a1cf34 100644 --- a/doc/watchexec.1.ronn +++ b/doc/watchexec.1.ronn @@ -26,7 +26,7 @@ Ignores modifications from paths that do not match . This option can be Sends the specified signal (e.g. `SIGKILL`) to the child process. Defaults to `SIGTERM`. * `-n`, `--no-shell`: -Execute command directly, do not use `sh -c`. This is especially useful in combination with `--signal`, as the signal is then send directly to the specified command. While `--no-shell` is a little more performant than the default, it prevents using shell-features like pipes and redirects. +Execute command directly, do not wrap it in `sh -c` resp. `cmd.exe /C`. This is especially useful in combination with `--signal`, as the signal is then send directly to the specified command. While `--no-shell` is a little more performant than the default, it prevents using shell-features like pipes and redirects. * `-i`, `--ignore` : Ignores modifications from paths that match . This option can be specified multiple times, and a match on any pattern causes the path to be ignored. diff --git a/src/cli.rs b/src/cli.rs index c197e59..52d2e34 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -104,7 +104,7 @@ pub fn get_args() -> Args { .long("force-poll") .value_name("interval")) .arg(Arg::with_name("no-shell") - .help("Do not wrap command in 'sh -c'") + .help("Do not wrap command in 'sh -c' resp. 'cmd.exe /C'") .short("n") .long("no-shell")) .arg(Arg::with_name("once").short("1").hidden(true)) diff --git a/src/process.rs b/src/process.rs index ed6be69..95661be 100644 --- a/src/process.rs +++ b/src/process.rs @@ -139,7 +139,7 @@ mod imp { } impl Process { - pub fn new(cmd: &str, updated_paths: Vec) -> Result { + pub fn new(cmd: &str, updated_paths: Vec, no_shell: bool) -> Result { use std::os::windows::io::IntoRawHandle; fn last_err() -> io::Error { @@ -163,8 +163,23 @@ mod imp { panic!("failed to set job info: {}", last_err()); } - let mut command = Command::new("cmd.exe"); - command.arg("/C").arg(cmd); + let mut iter_args = cmd.split_whitespace(); + let arg0 = match no_shell { + true => iter_args.next().unwrap(), + false => "cmd.exe", + }; + + // TODO: There might be a better way of doing this with &str. + // I've had to fall back to String, as I wasn't able to join(" ") a Vec<&str> + // into a &str + let args: Vec = match no_shell { + true => iter_args.map(str::to_string).collect(), + false => vec!["/C".to_string(), iter_args.collect::>().join(" ")], + }; + + let mut command = Command::new(arg0); + command.args(args); + debug!("Assembled command {:?}", command); if let Some(single_path) = super::get_single_updated_path(&updated_paths) { command.env("WATCHEXEC_UPDATED_PATH", single_path);