pty4j

repository·master·Indexed 19 days ago

https://github.com/jetbrains/pty4j

A Java implementation of a Pseudo terminal (PTY) that uses JNA with native code for process forking and supports Windows via the WinPty library. It provides PtyProcessBuilder for starting processes and a Command class hierarchy, including RawCommandString and CommandList, to define executable processes. Supported operating systems include Linux, OSX, Windows, and FreeBSD.

Tokens
1.2K
Snippets
5
Records
6
Agent score
15%

What's inside pty4j

  1. Add Pty4J to your build

    master

    Pty4J is published to Maven Central under the group ID org.jetbrains.pty4j. You can include it in your project using Maven or Gradle.

    ### Maven
    
    ```xml
    <dependency>
      <groupId>org.jetbrains.pty4j</groupId>
      <artifactId>pty4j</artifactId>
      <version>0.13.4</version>
    </dependency>

    Gradle

    dependencies {
      implementation 'org.jetbrains.pty4j:pty4j:0.13.4'
    }
  2. Start a pseudo terminal process with PtyProcessBuilder

    master

    To run a command in a pseudo terminal, use PtyProcessBuilder. You can specify the command as a String[] and provide an environment map. Once started, you can interact with the process via its InputStream and OutputStream and wait for its termination using waitFor().

    Supported operating systems: Linux, OSX, Windows, and FreeBSD.

    String[] cmd = { "/bin/sh", "-l" };
    Map<String, String> env = new HashMap<>(System.getenv());
    if (!env.containsKey("TERM")) env.put("TERM", "xterm");
    
    PtyProcess process = new PtyProcessBuilder()
        .setCommand(cmd)
        .setEnvironment(env)
        .start();
    
    OutputStream os = process.getOutputStream();
    InputStream is = process.getInputStream();
    
    // ... work with the streams ...
    
    // wait until the PTY child process is terminated
    int result = process.waitFor();
  3. Represent commands using the Command class

    master

    Pty4J uses a sealed Command class hierarchy to define the processes you want to execute. Depending on whether you have a single command string or a list of arguments, you should use RawCommandString or CommandList respectively.

    • RawCommandString: Use this when you have a single, pre-formatted command line string (e.g., "ls -la"). It uses ParametersListUtil.parse to break the string into a list of arguments.
    • CommandList: Use this when you have a discrete list of arguments (e.g., listOf("ls", "-la")). This is generally safer for avoiding shell injection or parsing issues. It uses joinCmdArgs to reconstruct the command line string.

    Both types provide toList(), toArray(), and toCommandLine() methods to retrieve the command in various formats required by the underlying PTY implementation.

    // Using a raw string
    val cmd1 = RawCommandString("ls -la")
    val args1 = cmd1.toList() // ["ls", "-la"]
    
    // Using a list of arguments
    val cmd2 = CommandList(listOf("ls", "-la"))
    val cmdLine2 = cmd2.toCommandLine() // "ls -la" (platform dependent formatting)
  4. Use RawCommandString for single command lines

    master

    The RawCommandString class wraps a single String representing a full command line. It is useful when you are receiving a command as a single block of text and need Pty4J to parse it into individual arguments.

    • toCommandLine(): Returns the original string.
    • toList(): Returns the command line parsed into a List<String> using ParametersListUtil.parse.
    val command = RawCommandString("echo hello world")
    val list = command.toList() // ["echo", "hello", "world"]
  5. Use CommandList for discrete arguments

    master

    The CommandList class wraps a List<String> where each element is a distinct argument. This is the preferred way to define commands to ensure arguments are handled correctly without manual parsing.

    • toList(): Returns the original list of strings.
    • toCommandLine(): Returns a single string joined by arguments, formatted according to platform-specific requirements (via joinCmdArgs).
    val command = CommandList(listOf("git", "commit", "-m", "message"))
    val cmdLine = command.toCommandLine()