1

When I try to call the find command from a Rust program, either I get a FIND: Invalid switch or a FIND: Parameter format incorrect error.

find works fine from command line.

echo $PATH

/usr/local/bin:/usr/bin:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:.....

The file I am searching for (main.rs) exists.

use std::process::{Stdio,Command};
use std::io::{Write};

fn main() {
    let mut cmd_find = Command::new("/cygdrive/c/cygwin64/bin/find.exe")
        .arg("/cygdrive/c/cygwin64/home/*")
        .stdin(Stdio::piped())
        .spawn()
        .unwrap_or_else(|e| { panic!("failed to execute process:  {}", e)});

    if let Some(ref mut stdin) = cmd_find.stdin {
        stdin.write_all(b"main.rs").unwrap();   
    }       

    let res = cmd_find.wait_with_output().unwrap().stdout;  
    println!("{}",String::from_utf8_lossy(&res));
}

./find_cmdd.exe

thread '<main>' panicked at 'failed to execute process: The system cannot find the file specified. (os error 2)', find_cmdd.rs:12

I have also tried the following option,

let mut cmd_find = Command::new("find").....

for which I get FIND:Invalid switch error.

I do not have the luxury of renaming/copying the find.exe to another location.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Rustic
  • 87
  • 1
  • 7

2 Answers2

2

"FIND:Invalid switch error" indicates this is NOT the cygwin find, but you are invoking the Windows one. To double check:

$ find -k
find: unknown predicate `-k'

$ /cygdrive/c/windows/system32/find -k
FIND: Parameter format not correct
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
matzeri
  • 8,062
  • 2
  • 15
  • 16
  • Hi Matzeri, I agree the windows find is being invoked. As I have pointed out, the PATH variable holds the Cygwin bin directory, before the windows path, so am not sure how the windows find is getting invoked, but how do I invoke or use the Cygwin find command in my program?? – Rustic Aug 09 '16 at 11:29
  • Again as I have pointed out, I have tried using, ("/cygdrive/c/cygwin64/bin/find) ...which seems to be of no use. – Rustic Aug 09 '16 at 11:33
1

Cygwin basically doesn't exist when you are running a program via Command. Executing a process uses the operating system's native functionality; in the case of Windows that's CreateProcessW.

That means that:

  1. The PATH variable set by your cygwin shell may or may not mean anything when starting a process.
  2. The directory structure with /cygdrive/... doesn't actually exist in Windows; that's an artifact.

All that said, you have to use Windows-native paths:

use std::process::{Stdio, Command};
use std::io::Write;

fn main() {
    let mut cmd_find = Command::new(r#"\msys32\usr\bin\find.exe"#)
        .args(&[r#"\msys32\home"#])
        .stdin(Stdio::piped())
        .spawn()
        .unwrap_or_else(|e| panic!("failed to execute process:  {}", e));

    if let Some(ref mut stdin) = cmd_find.stdin {
        stdin.write_all(b"main.rs").unwrap();
    }

    let res = cmd_find.wait_with_output().unwrap().stdout;
    println!("{}", String::from_utf8_lossy(&res));
}

As a side note, I have no idea what piping standard input to find does; it doesn't seem to have any effect for me on Msys2 or on OS X...

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366