使用 Mono 4.0,有谁知道如何写入打开的控制台,即 /dev/pts/0?

Using Mono 4.0, does anyone know how to write to an open console i.e. /dev/pts/0?

我似乎无法弄清楚如何在 CentOS 7.1 上重复写入 /dev/pts/0 等控制台。我想要做的是将命令通过管道传递给正在监听命名管道的进程。该进程应该能够将一些输出写回指定的控制台。

使用 SerialPort 给我一个 InvalidArguement 异常,我认为这意味着它不知道伪终端文件类型。

我尝试了 File.WriteAllText 并且成功了一次,然后当我在管道上发送第二个命令时,它在路径 /dev/pts/0.

上给我一个共享冲突

我尝试了 File.AppendAllText 但我收到错误信息流不支持搜索。

我尝试使用 FileStream,但在路径 /dev/pts/0 上出现共享冲突,与 WriteAllText 相同。

下面 echoCommand 函数中的代码显示了我在注释掉不同选项后所做的事情:

using System;
using System.IO;
using System.IO.Pipes;
using System.IO.Ports;

class PipeListener
{

    static void Main(string[] args)
    {
        Console.WriteLine("\n***Named piper server example ***\n");        
        NamedPipeServerStream pipe = new NamedPipeServerStream("/tmp/test");
        pipe.WaitForConnection();
        StreamReader reader = new StreamReader(pipe);
        int i = 0;
        String tty = "";
        String cmd = "";
        while(i < 10)
        {
            var line = reader.ReadLine();
            tty = Command.getTTY(line);
            cmd = Command.getCommand(line);
            echoCommand(tty, cmd); 
            Console.WriteLine("Recevied command: " +line);
            i++;
        }
        pipe.Close();
    }

    public static void echoCommand(String tty, String command)
    {
        if (tty != "" && File.Exists(tty))
        {
            String output = String.Format("\nYour command was: {0}\n", command);
            byte[] bytes = new byte[output.Length * sizeof(char)];
            System.Buffer.BlockCopy(output.ToCharArray(), 0, bytes, 0, 
                                    bytes.Length);

            /*SerialPort port = new SerialPort(tty, 38400);
            port.Open();
            if (port.IsOpen)
            {
                Console.WriteLine("Echoing command");
                port.Write(output);     
            }
            */

            //File.WriteAllText(tty, output);

            //File.AppendAllText(tty, output); 

            FileStream file = new FileStream(tty, FileMode.Open);
            file.Write(bytes, 0, bytes.Length);
        }
    }
}

class Command
{
    public static String getTTY(String str)
    {
        String[] words = str.Split(' ');
        return words[0];
    }

    public static String getCommand(String str)
    {
        String[] words = str.Split(' ');
        String[] cmd = new String[words.Length-1];
        Array.Copy(words,1,cmd,0, words.Length - 1);
        return String.Join(" ", cmd);
    }
}

原来问题出在我使用 FileStream 的方式上。 FileStream 需要使用正确的文件共享打开 PTS。我将 post 我的解决方案如下:

using System;
using System.IO;
using System.IO.Pipes;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;

class PipeListener
{

    static void Main(string[] args)
    {
        Console.WriteLine("\n***Named piper server example ***\n");
        NamedPipeServerStream pipe = new NamedPipeServerStream("/tmp/test");
        pipe.WaitForConnection();
        StreamReader reader = new StreamReader(pipe);
        int i = 0;
        String tty = "";
        String cmd = "";
        while(i < 10)
        {
            Console.WriteLine("Waiting for pipe.");
            var line = reader.ReadLine();
            tty = Command.getTTY(line);
            cmd = Command.getCommand(line);

            echoCommand(tty, cmd);
            Console.WriteLine("Recevied command: " +line);
            i++;
        }
        pipe.Close();
    }

    public static void echoCommand(String tty, String command)
    {
        if (tty != "" && File.Exists(tty))
        {
            String output = String.Format("\nYour command was: {0}\n", command);
            byte[] bytes = new byte[output.Length * sizeof(char)];
            System.Buffer.BlockCopy(output.ToCharArray(), 0, bytes, 0,
                                    bytes.Length);

            FileStream term = new FileStream(tty, FileMode.Open,
                    FileAccess.Write, FileShare.Write);

            term.Write(bytes, 0, bytes.Length);
            term.Flush(true);
            term.Dispose();
        }
    }
}

class Command
{
    public static String getTTY(String str)
    {
        String[] words = str.Split(' ');
        return words[0];
    }

    public static String getCommand(String str)
    {
        String[] words = str.Split(' ');
        String[] cmd = new String[words.Length-1];
        Array.Copy(words,1,cmd,0, words.Length - 1);
        return String.Join(" ", cmd);
    }
}