2016-09-06 76 views
2

我之前和我的結果後,通過C#中使用的Plink時獲得想要的字符:的Plink通過C#返回不需要的字符

命令:

ls -l */informatica/tgtdynamicparams*.out | grep vaulttest| grep 'Sep 1'|awk '{print $9}' | sort 

Linux的結果是:通過

aaco/informatica/tgtdynamicparams2269885_CHECK_REF_COMPANY.out 
cdph/informatica/tgtdynamicparams2225704_CDPHDRUGRECON.out 
cdph/informatica/tgtdynamicparams2225704_CDPHELIGRECON.out 
merh/informatica/tgtdynamicparams3454321_OPEN_TEST.out 
merh/informatica/tgtdynamicparams3454322_OPEN_TEST2.out 

C# Plink結果:

[01;32mcdph/informatica/tgtdynamicparams2225704_CDPHDRUGRECON.out[0m 
[01;32mcdph/informatica/tgtdynamicparams2225704_CDPHELIGRECON.out[0m 
[01;32mmerh/informatica/tgtdynamicparams3454321_OPEN_TEST.out[0m 
[01;32mmerh/informatica/tgtdynamicparams3454322_OPEN_TEST2.out[0m 
[0m[01;32maaco/informatica/tgtdynamicparams2269885_CHECK_REF_COMPANY.out[0m 

我試過以下沒有任何運氣:

StandardOutputEncoding = Encoding.UTF8 
StandardOutputEncoding = Encoding.ASCII 
StandardOutputEncoding = Encoding.DEFAULT 

這是我使用的代碼。我已經看到類似的問題,建議使用ssh.net的答覆,但我不能使用,它必須是Plink。

private string GetFileNames = @"ls -l */informatica/tgtdynamicparams*.out 
          | grep vaulttest| grep 'Sep 1' 
          | awk '{print $9}' 
          | sort"; 

GetProcessesCommands = new [] { 
           @"cd /src/trs/runjobs", 
           GetFileNames 
           }; 
Request(ServerName, UserName, Password, GetProcessesCommands); 

調用此:

private void Request(string remoteHost, string userName, string password, IEnumerable<string> lstCommands) 
{ 
    try 
    { 
     var psi = new ProcessStartInfo 
     { 
      FileName = FormInformatiKill.PropFile.Plink, 
      Arguments = string.Format("-ssh {0}@{1} -pw {2}", userName, remoteHost, password), 
      RedirectStandardError = true, 
      RedirectStandardOutput = true, 
      RedirectStandardInput = true, 
      UseShellExecute = false, 
      CreateNoWindow = true, 
      StandardOutputEncoding = Encoding.UTF8 
     }; 

     var p = Process.Start(psi); 
     _mObjLock = new object(); 
     _mBlnDoRead = true; 

     if(p == null) return; 
     AsyncReadFeedback(p.StandardOutput); // start the async read of stdout 

     var strw = p.StandardInput; 

     foreach(var cmd in lstCommands) 
     { 
      strw.WriteLine(cmd); // send commands 
     } 
     strw.WriteLine("exit"); // send exit command at the end 

     p.WaitForExit(); // block thread until remote operations are done 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.Message); 
     Console.WriteLine(e.StackTrace); 
    } 
} 

private void AsyncReadFeedback(StreamReader strr) 
{ 
    var trdr = new Thread(ReadFeedback); 
    trdr.Start(strr); 
} 

private void ReadFeedback(object objStreamReader) 
{ 
    var strr = (StreamReader) objStreamReader; 
    while (!strr.EndOfStream && _mBlnDoRead) 
    { 
     var line = strr.ReadLine(); 
     // lock the feedback buffer (since we don't want some messy stdout/err mix string in the end) 
     lock (_mObjLock) 
     { 
      if(line != null) ListOfFilesResults.Add(line.Trim()); 
     } 
    } 
} 

我試過Trim()。我甚至花時間試圖刪除我不想要的角色,但似乎有更多的可能性比我可以編碼。

+0

這些是[「終端轉義碼」](https://en.wikipedia.org/wiki/ANSI_escape_code)(這與編碼無關,儘管它可能受程序檢測控制檯模式的影響) ,用於顏色等。 – user2864740

+0

在這種情況下,顏色生成可能來自'ls'命令。使用'ls --color = never -l ..'。 – user2864740

+0

user2864740 ...完美的作品。謝謝!我如何給你信貸? –

回答

0

那些是ANSI escape codes

雖然使用--color=never可能會有所幫助,但根本問題在於,您運行Plink(使用標準輸入提供命令)的方式會使其使用交互式會話。如今的大多數系統都被配置爲使用花哨的格式來進行目錄列表(和其他東西)以進行交互式會話以更加人性化。

雖然在你的情況下,沒有人蔘與,所以你應該使用非交互式會話。

有兩種方法做到這一點:

  • 要麼提供的Plink命令行命令(而不是使用標準輸入餵養它的),如:

    plink.exe -ssh [email protected] -pw password "ls -l ... | grep ... | sort" 
    

    此語法隱含地強制非交互模式。

  • 或者使用-T switch明確強制非交互模式:

    plink.exe -ssh [email protected] -pw password -T 
    

    這個語法允許你繼續餵養使用標準輸入的命令。

使用非交互式會話(一個正確配置的系統上),你避免了互動環節,所有的煩惱(不僅僅是--color)。所以這是一種更通用的解決方案。


如果這不適合你,那一定是因爲你的服務器配置錯誤和別名ls使用--color即使對於非互動環節。

如果您無法修復服務器,我建議您同時使用非交互式會話(以避免其他可能的麻煩)和--color=never切換。可能比使用--color=never更好的解決方案是使用unalias ls

+0

我試圖添加-T到我的代碼無效。所有這些都通過C#中的Plink運行。我將標誌UseShellExecute設置爲false。 '參數=的String.Format( 「 - SSH {0} @ {1} -pw {2} -T」,用戶名,REMOTEHOST,密碼), RedirectStandardOutput =真, RedirectStandardInput =真, UseShellExecute =假, CreateNoWindow = true };' –

+0

適用於我。雖然我必須用'.Write(... +「\ n」)替換'.WriteLine(...)'調用''WriteLine'使用'\ r \ n',那麼非交互式* nix會議無法處理。如果這不起作用,那一定是因爲你的服務器配置錯誤,並且別名'ls'使用'--color',即使是非交互式會話。 –

+0

你是對的。我追溯了我的.bashrc,它使用/ etc/bashrc來設置一個交互式會話。我從我的版本中刪除了該呼叫,問題消失了。不幸的是,生產版本使用用戶,我無法更改其會話變量,並且它包含交互式會話。感謝您花時間幫助! –

1

謝謝user2864740! 我加了--color =從不,那些該死的角色消失了。

  private const string GetFileNames = "ls --color=never -l */informatica/tgtdynamicparams*.out " + 
             "| grep vaulttest " + 
             "| grep 'Sep 1' " + 
             "| awk '{print $9}' " + 
             "| sort";