2016-05-28 4 views
3

とPATHに実行することができます検索:私はPythonではサビ

from distutils import spawn 

cmd = spawn.find_executable("commandname") 

は、私は以下のコードのようなものを試してみましたが、それはそれはあなたが利用可能/usr/bin/which(とUNIXライクなシステムにしている前提としても、それはの実行を必要とします外部のコマンドを避けたい):

use std::process::Command; 

let output = Command::new("which") 
         .arg("commandname") 
         .unwrap_or_else(|e| /* handle error here */) 

Rustでこれを行う最も簡単な方法は何ですか?

答えて

2

私はおそらく環境変数を取得し、それを反復処理し、最初に一致したパスを返したい:あなたは実行可能ファイル名に.exeを追加する必要があるだろうと

use std::env; 
use std::path::{Path, PathBuf}; 

fn find_it<P>(exe_name: P) -> Option<PathBuf> 
    where P: AsRef<Path>, 
{ 
    env::var_os("PATH").and_then(|paths| { 
     env::split_paths(&paths).filter_map(|dir| { 
      let full_path = dir.join(&exe_name); 
      if full_path.is_file() { 
       Some(full_path) 
      } else { 
       None 
      } 
     }).next() 
    }) 
} 

fn main() { 
    println!("{:?}", find_it("cat")); 
    println!("{:?}", find_it("dog")); 
} 

は、これはおそらく、Windows上で醜いです。また、実行可能な項目だけを返すように拡張する必要があります。これは、プラットフォーム固有のコードです。

を確認すると、渡される絶対パスもサポートされているようです。関数がそれをサポートするかどうかは、あなた次第です。それは現在

は、現在唯一のUnixライクなオペレーティングシステム上で動作すると言うものの、quale

crates.ioの迅速な検索が有用である可能性がある1つのクレートを返されました。

他にもあることがわかりました。


ここでそれが唯一のWindows上で、欠けている場合は最後に.exeを追加し、いくつかの醜いコードです。

#[cfg(not(target_os = "windows"))] 
fn enhance_exe_name(exe_name: &Path) -> Cow<Path> { 
    exe_name.into() 
} 

#[cfg(target_os = "windows")] 
fn enhance_exe_name(exe_name: &Path) -> Cow<Path> { 
    use std::ffi::OsStr; 
    use std::os::windows::ffi::OsStrExt; 

    let raw_input: Vec<_> = exe_name.as_os_str().encode_wide().collect(); 
    let raw_extension: Vec<_> = OsStr::new(".exe").encode_wide().collect(); 

    if raw_input.ends_with(&raw_extension) { 
     exe_name.into() 
    } else { 
     let mut with_exe = exe_name.as_os_str().to_owned(); 
     with_exe.push(".exe"); 
     PathBuf::from(with_exe).into() 
    } 
} 

// At the top of the `find_it` function: 
// let exe_name = enhance_exe_name(exe_name.as_ref()); 
+1

「.exe」を使用してブラインドではなく、本当に正しいです。 'PATHEXT'環境変数を使用することになっています。これは'実行可能 'とみなされるファイル拡張子の ';'で区切られたリストです。残念ながら、 'CreateProcess'(Rustの' Command'型がAFAIKをサポートしている)はネイティブの実行可能な型しかサポートしていないので、注意する必要があります。シェルスクリプト)。だから、あなたが 'ShellExecute'を使って独自のコードを書こうとしているのでなければ(Rustは私には分かりません)、おそらく' .COM; .EXE'に制限するべきです。 –

+0

@DKクロスプラットフォームの作業は難しいです!それが価値あるものであれば、ここのコードはPythonがやっていることを模倣していますが、WindowsのPythonサポートがどれほど素晴らしいかわかりません。多分、私たちはこれをクレート(クワールのような?)に提出するべきです。 – Shepmaster

+1

ええ、私は実際にWin32のコードを書くことなく、Rustでこれを行う方法が実際にはないことを(文字がなくなると)書きました。なぜなら、あなたが正しく 'commandname.py'か何かを見つけたとしても実際には呼び出すことはできません。スクリプトを実行するとカーネル機能ではなくシェル機能であることは、あなたが得たものだと思います... –

関連する問題