2016-12-30 7 views
4

私は別のプロセス(例えばgit status)からの出力をキャプチャして処理し、すべてのスタイル(太字、斜体、下線)と色で印刷したいと思います。 Stringを処理することは非常に重要です。は印刷するだけです。Rustでは、プロセス出力をどのように色で取り込むことができますか?

Unixの世界では、これにエスケープコードが関係すると思いますが、Windowsの世界はわかりませんが、私にとっても重要です。

私は色なしでそれを行う方法を知っている:

fn exec_git() -> String { 
    let output = Command::new("git") 
     .arg("status") 
     .output() 
     .expect("failed to execute process"); 

    String::from_utf8_lossy(&output.stdout).into_owned() 
} 

たぶん私は代わりにspawnを使用する必要がありますか?

+0

ターミナルに出力していると思って(それによってその出力をカラー化している)、または単にフラグ/設定をgitに渡してコンテンツを使用して、端末の検出に頼っていますか? –

+0

'git'をだ​​ましているのはいい考えです。 'git'はstreamがTTYかどうかを確認しますか? (libuvの 'if(uv_guess_handle(1)== UV_TTY)'のようなもの) Ok - 私はそれをだますことにしようとしています(それはまだわかりませんが、遅かれ早かれ解決します)。私の出力にはエスケープコードが含まれており、それらを印刷すると最終的な出力が色づけされますか? –

+0

もしあなたがgitをだますことができたら、あなたの出力は色付けされるべきです(端末で色分けされている場合)。しかし、これはおそらく最も難しいオプションです。 –

答えて

1

あなたのコードはすでに作品:出力([44;[0mなど)内部で散乱ゴミの束があること

total 68 
-rw-r--r-- 4 root root 56158 Dec 23 00:00 [0m[44;38;5;15mCargo.lock[0m 
-rw-rw-r-- 4 root root 2093 Dec 9 02:54 [44;38;5;15mCargo.toml[0m 
drwxr-xr-x 1 root root 4096 Dec 30 15:24 [38;5;27msrc[0m 
drwxr-xr-x 1 root root 4096 Dec 23 00:19 [38;5;27mtarget[0m 

注:

use std::process::Command; 

fn main() { 
    let output = Command::new("ls") 
     .args(&["-l", "--color"]) 
     .env("LS_COLORS", "rs=0:di=38;5;27:mh=44;38;5;15") 
     .output() 
     .expect("Failed to execute"); 

    let sout = String::from_utf8(output.stdout).expect("Not UTF-8"); 
    let serr = String::from_utf8(output.stderr).expect("Not UTF-8"); 

    println!("{}", sout); 
    println!("{}", serr); 
} 

は出力を印刷します。それらはANSI escape codesで、端末エミュレータは次のテキストの色を変更するものを解釈します。

デバッグで文字列を印刷する場合は、表示されます。

\u{1b}[0m\u{1b}[44;38;5;15mCargo.lock\u{1b}[0m 

各エスケープコードは、実際のコマンドに続いESC\u{1b})で始まります。どんな処理をしていてもそれらを無視するには、それらを解析する必要があります。

Windowsではエスケープコード(maybe it can in Windows 10?)は使用されず、代わりに直接プログラムmodifies the console it is connected toが使用されます。出力には色を示すものはありません。

2

あなたはこれが唯一のgit statusのために働くgit -c color.status=always status

use std::process::Command; 

fn main() { 
    let output = Command::new("git") 
     .arg("-c") 
     .arg("color.status=always") 
     .arg("status") 
     .output() 
     .expect("failed to execute process"); 

    let output = String::from_utf8_lossy(&output.stdout).into_owned(); 

    println!("{}", output); 
} 

を使用することにより、出力色にgitのを強制することができます。より一般的な解決策としては、プログラムのドキュメントをチェックし、カラー出力を強制的に行う方法や、プログラムが色を出力するかどうかを調べる方法(たとえば、COLORTERM環境変数のチェック)が必要であるかどうかを確認する必要があります。

関連する問題