2016-09-06 73 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";