1 概述
本文次要讲述了如何利用xsel
在Linux
环境下对系统剪贴板的拜访。
2 起因
在搜索引擎间接搜寻“Java
拜访剪贴板”,大部分都是间接应用AWT API
进行拜访的例子:
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();StringSelection selection = new StringSelection("test");clipboard.setContents(selection, selection);
然而,一个最大的问题是,须要该程序始终运行,能力拜访到剪贴板,因而,如果没有其余解决逻辑,须要加上线程休眠代码:
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();StringSelection selection = new StringSelection("test");clipboard.setContents(selection, selection);TimeUnit.HOURS.sleep(1);
换句话说,这样只是长期复制到剪贴板,并没有永恒复制,那么,有没有其余方法能够在运行程序完结之后也能拜访到剪贴板呢?
3 xsel
xsel
是Linux
下拜访剪贴板的命令行工具,相似的还有xclip
,没有装置的能够应用包管理器装置。其中写入到剪贴板命令如下:
echo "test clipboard" | xsel -ib
由此想到了能够尝试应用Runtime
:
public static void main(String[] args) throws Exception { Runtime runtime = Runtime.getRuntime(); // 间接执行命令 Process process = runtime.exec("echo \"111\" | xsel -ib"); // 期待执行完结 process.waitFor(); StringBuilder builder = new StringBuilder(); // 获取输入 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); for (String s; ((s = reader.readLine()) != null); ) { builder.append(s); } System.out.println(builder); builder = new StringBuilder(); // 获取谬误输入 reader = new BufferedReader(new InputStreamReader(process.getErrorStream())); for (String s; ((s = reader.readLine()) != null); ) { builder.append(s); } System.out.println(builder); // 获取返回值 int exitValue = process.exitValue(); System.out.println("exitValue is " + exitValue); if (exitValue != 0) { System.out.println("error"); } process.destroy();}
运行之后输入如下:
"111" | xsel -ib"111" | xsel -ibexitValue is 0
能够看到输入后果是不失常的,这样就相当于变成了执行
echo "\"111\" | xsel -ib"
也就是输入的字符串都是echo
的参数。
4 创立脚本文件
呈现下面后果的起因是Process
并不能间接反对应用管道运算符,因而,采纳间接创立脚本运行命令的办法。
步骤:
- 创立长期脚本文件:应用
Files.createFile
创立 - 受权:
700
权限,也就是所有者读、写、执行权限,应用Files.setPosixFilePermissions
- 写入脚本文件:向脚本文件写入
echo str | xsel -ib
,应用Files.writeString
- 执行:利用
Process.exec
执行脚本文件 - 删除:利用
Files.delete
删除临时文件
代码如下:
public static void main(String[] args) throws Exception { String fileName = "1.sh"; Path executeFile = Files.createFile(Path.of(fileName)); Files.setPosixFilePermissions(executeFile, Set.of(PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.OWNER_READ)); String clipboardContent = "111"; Files.writeString(executeFile, "echo " + clipboardContent + " | xsel -ib"); Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec("./" + fileName); process.waitFor(); StringBuilder builder = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); for (String s; ((s = reader.readLine()) != null); ) { builder.append(s); } System.out.println(builder); builder = new StringBuilder(); reader = new BufferedReader(new InputStreamReader(process.getErrorStream())); for (String s; ((s = reader.readLine()) != null); ) { builder.append(s); } System.out.println(builder); int exitValue = process.exitValue(); System.out.println("exitValue is " + exitValue); if (exitValue != 0) { System.out.println("error"); } Files.delete(executeFile); process.destroy();}
输入:
exitValue is 0
有两行空行是System.out.println()
的换行输入,阐明Process
的inputStream
以及errorStream
都没有内容。
测试后果也是失常,可能剪贴出111
字符串。
5 从剪贴板读取
从剪贴板读取的原理相似,就是xsel
的参数不一样,这里不开展了,放上残缺代码:
import java.io.BufferedReader;import java.io.InputStreamReader;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.attribute.PosixFilePermission;import java.util.Set;public class Main { private static final String FILENAME = "1.sh"; public static void main(String[] args) throws Exception { writeToClipboard("111111"); System.out.println(readFromClipboard()); writeToClipboard("22222"); System.out.println(readFromClipboard()); } //写入到剪贴板 private static void writeToClipboard(String content) throws Exception { Path executeFile = createFile("echo " + content + " | xsel -ib"); exec(executeFile); } //从剪贴板读取 private static String readFromClipboard() throws Exception { Path executeFile = createFile("xsel -ob"); return exec(executeFile); } private static Path createFile(String fileContent) throws Exception { Path executeFile = Files.createFile(Path.of(FILENAME)); Files.setPosixFilePermissions(executeFile, Set.of(PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.OWNER_READ)); Files.writeString(executeFile, fileContent); return executeFile; } private static String exec(Path executeFile) throws Exception { Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec("./" + FILENAME); process.waitFor(); StringBuilder builder = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); for (String s; ((s = reader.readLine()) != null); ) { builder.append(s); } String res = ""; if (builder.length() != 0) { res = builder.toString(); } reader = new BufferedReader(new InputStreamReader(process.getErrorStream())); builder = new StringBuilder(); for (String s; ((s = reader.readLine()) != null); ) { builder.append(s); } if (builder.length() != 0) { System.out.println(builder); } int exitValue = process.exitValue(); System.out.println("exitValue is " + exitValue); if (exitValue != 0) { System.out.println("error"); } Files.delete(executeFile); process.destroy(); return res; }}