共计 4771 个字符,预计需要花费 12 分钟才能阅读完成。
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 -ib
exitValue 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;
}
}
正文完