0

I'm trying to start a process in Java, which runs the following command (taken from this StackOverflow answer):

osascript -e 'the clipboard as «class HTML»' |   perl -ne 'print chr foreach unpack("C*",pack("H*",substr($_,11,-3)))'

Here is my code:

public class ClipboardService {

    public String getClipboardContents() {
        try {
            List<String> result;
            List<Process> processes = ProcessBuilder.startPipeline(List.of(
                    new ProcessBuilder("osascript", "-e", "'the clipboard as «class HTML»'")
                            .inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE),
                    new ProcessBuilder("perl", "-ne", "'print chr foreach unpack(\"C*\",pack(\"H*\",substr($_,11,-3)))'")
                            .redirectError(ProcessBuilder.Redirect.INHERIT)
            ));
            String res = new String(processes.get(processes.size() - 1).getInputStream().readAllBytes());
            return res;
        } catch (Exception e) {
            throw  new RuntimeException(e);
        }
    }
}

I noticed that this method returned nothing, why? How to make it work?

Searene
  • 25,920
  • 39
  • 129
  • 186

1 Answers1

0

After some tweaking and testing, I finally made it work by using the following code:

public class ClipboardService {

    public String getClipboardContents() {
        try {
            List<String> result;
            List<Process> processes = ProcessBuilder.startPipeline(List.of(
                    new ProcessBuilder("osascript", "-e", "the clipboard as «class HTML»")
                            .redirectOutput(ProcessBuilder.Redirect.PIPE).redirectError(ProcessBuilder.Redirect.INHERIT),
                    new ProcessBuilder("perl", "-ne", "print chr foreach unpack(\"C*\",pack(\"H*\",substr($_,11,-3)))")
            ));
            String res = new String(processes.get(processes.size() - 1).getInputStream().readAllBytes());
            return res;
        } catch (Exception e) {
            throw  new RuntimeException(e);
        }
    }
}
Searene
  • 25,920
  • 39
  • 129
  • 186
  • 1
    single quote, double quote, and all that jazz are bashisms. Bash knows what that is. Java doesn't take your ProcessBuilder commands and throw them at `/bin/bash`. No, it just asks the OS. Which just takes your single quote verbatim and passes it on to `osascript` which has no idea what it is. If you _want_ bash to process your stuff, you can - run `/bin/bash` `-c` `the whole command as one string`. Other bashisms: `*.txt` style unpacking, variable substitution, $PATH resolution, and more. Java half-does some things such as $PATH resolution, but better not to rely on it. – rzwitserloot Oct 05 '22 at 04:13