Answers:
恐怕您不能在仅命令行的来宾上拥有共享剪贴板。
这是因为TTY并未真正创建供访客添加使用的适当剪贴板,因此您需要完整的GUI。
使用SSH从主机登录到来宾会更好。这样,您可以使用SSH客户端的功能(例如Putty)共享剪贴板。
可以做到的。我无法双向处理以下内容,但是Host to Guest(即将内容粘贴到文本控制台中)确实有效。以下说明适用于CentOS 5/6/7,但是它们的类似机制也适用于其他口味。
这将使X11剪贴板与gpm剪贴板保持同步。如果将“共享剪贴板”设置配置为“从主机到来宾”,则当主机剪贴板发生更改时,VirtualBox将更新X11剪贴板...修补的gpm然后将使用xclip将X11剪贴板数据拉入gpm剪贴板...然后可以将其粘贴鼠标中键。
可以共享“主机到访客”剪贴板以在服务器/控制台模式下工作。目前,“来宾托管”共享不起作用,可能是由于VBoxClient和Xvfb之间存在问题。
百胜安装Xvfb
挂载/ dev / cdrom / mnt /mnt/VBoxLinuxAdditions.run
以/ usr / local / bin / xclip 下载,编译和安装xclip(http://sourceforge.net/projects/xclip/)。
下载最新的gpm源,并进行以下更改以对其进行修补。
将二进制文件安装为/ usr / local / bin / xclip-gpm。
这是Alex Efros的修补程序的更新版本(http://powerman.name/patch/gpm.html)。
gpm-1.20.7-xclip-support.patch
diff -rupN gpm-1.20.7-orig/src/daemon/do_selection.c gpm-1.20.7-xclip/src/daemon/do_selection.c
--- gpm-1.20.7-orig/src/daemon/do_selection.c 2012-10-27 10:21:38.000000000 +1300
+++ gpm-1.20.7-xclip/src/daemon/do_selection.c 2014-07-29 13:40:19.546689653 +1200
@@ -19,18 +19,49 @@
*
********/
+#include <sys/stat.h>
+#include <sys/wait.h>
#include "headers/message.h" /* messaging in gpm */
#include "headers/daemon.h" /* daemon internals */
#include "headers/gpmInt.h" /* daemon internals */
+#include "headers/xcap.h" /* daemon internals */
/*-------------------------------------------------------------------*/
int do_selection(Gpm_Event *event) /* returns 0, always */
{
static int x1=1, y1=1, x2, y2;
+
+ /* XCaP start */
+ struct stat X0;
+ FILE *xclip;
+ /* XCaP end */
+
#define UNPOINTER() 0
x2=event->x; y2=event->y;
switch(GPM_BARE_EVENTS(event->type)) {
+
+ /* XCaP start */
+ case GPM_UP:
+ if(event->buttons==GPM_B_LEFT) {
+ /* check Xwindow: if Xwindow not active - xclip freeze for 6 sec :( */
+ if (stat("/tmp/.X11-unix/X0", &X0) != -1) {
+ if (!(xclip=popen("/usr/local/bin/xclip -d :0 -i", "w")))
+ gpm_report(GPM_PR_OOPS,"open pipe");
+ /* send currect selection to Xwindow clipboard */
+ fwrite(sel_buffer, sizeof(char), sel_buffer_lth, xclip);
+ if (!WIFEXITED(pclose(xclip)))
+ gpm_report(GPM_PR_OOPS,"close pipe");
+ }
+ /*resize sel_buffer back to "normal" size*/
+ if(sel_buffer_lth>SCR_SIZE) {
+ free(sel_buffer);
+ sel_buffer=malloc(SCR_SIZE);
+ sel_buffer_lth=SCR_SIZE;
+ }
+ }
+ /* XCaP end */
+
case GPM_MOVE:
if (x2<1) x2++; else if (x2>maxx) x2--;
if (y2<1) y2++; else if (y2>maxy) y2--;
diff -rupN gpm-1.20.7-orig/src/daemon/loadlut.c gpm-1.20.7-xclip/src/daemon/loadlut.c
--- gpm-1.20.7-orig/src/daemon/loadlut.c 2012-10-27 10:21:38.000000000 +1300
+++ gpm-1.20.7-xclip/src/daemon/loadlut.c 2014-07-29 13:40:29.895722875 +1200
@@ -30,6 +30,8 @@
#include "headers/daemon.h" /* daemon internals */
#include "headers/gpmInt.h" /* GPM_SYS_CONSOLE */
+#include "headers/xcap.h"
+
int loadlut(char *charset)
{
int i, c, fd;
@@ -47,7 +49,9 @@ int loadlut(char *charset)
};
+/*
#define inwordLut (long_array+1)
+*/
for (i=0; charset[i]; ) {
i += getsym(charset+i, &this);
@@ -56,9 +60,15 @@ int loadlut(char *charset)
else
next = this;
for (c = this; c <= next; c++)
- inwordLut[c>>5] |= 1 << (c&0x1F);
+ (long_array+1)[c>>5] |= 1 << (c&0x1F);
}
+ /* XCaP */
+ /* used in mode=1 (word-by-word selection) */
+ for (i=0; i<8; i++)
+ inwordLut[i] = long_array[i+1];
+ /* XCaP */
+
if ((fd=open(option.consolename, O_WRONLY)) < 0) {
/* try /dev/console, if /dev/tty0 failed -- is that really senseful ??? */
free(option.consolename); /* allocated by main */
diff -rupN gpm-1.20.7-orig/src/daemon/old_main.c gpm-1.20.7-xclip/src/daemon/old_main.c
--- gpm-1.20.7-orig/src/daemon/old_main.c 2012-10-27 10:21:38.000000000 +1300
+++ gpm-1.20.7-xclip/src/daemon/old_main.c 2014-07-29 13:40:36.184743068 +1200
@@ -33,6 +33,8 @@
#include "headers/daemon.h" /* daemon internals */
#include "headers/gpmInt.h" /* daemon internals */
+#include "headers/xcap.h" /* daemon internals */
+
#ifndef max
#define max(a,b) ((a)>(b) ? (a) : (b))
#endif
@@ -73,6 +75,11 @@ int old_main()
maxfd=max(fd, maxfd);
}
+ /* XCaP start */
+ sel_buffer=malloc(SCR_SIZE);
+ sel_buffer_lth=SCR_SIZE;
+ /* XCaP end */
+
/*....................................... catch interesting signals */
signal(SIGTERM, gpm_killed);
diff -rupN gpm-1.20.7-orig/src/daemon/selection_copy.c gpm-1.20.7-xclip/src/daemon/selection_copy.c
--- gpm-1.20.7-orig/src/daemon/selection_copy.c 2012-10-27 10:21:38.000000000 +1300
+++ gpm-1.20.7-xclip/src/daemon/selection_copy.c 2014-07-29 13:40:42.677763908 +1200
@@ -22,11 +22,28 @@
#include <fcntl.h> /* open */
#include <unistd.h> /* close */
#include <time.h> /* time */
+#include <sys/kd.h>
#include "headers/message.h" /* messaging in gpm */
#include "headers/daemon.h" /* daemon internals */
+#include "headers/xcap.h"
+
+/* XCaP start */
+/* inword() from /usr/src/linux-2.4.19/drivers/char/selection.c */
+static inline int inword(const unsigned char c) {
+ return ( inwordLut[c>>5] >> (c & 0x1F) ) & 1;
+}
+/* atedge() from /usr/src/linux-2.4.19/drivers/char/selection.c */
+static inline int atedge(const int p, int size_row)
+{
+ /* p+2 changed to p+1 because kernel operate with screen address */
+ return (!(p % size_row) || !((p + 1) % size_row));
+}
+/* XCaP end */
+
+
void selection_copy(int x1, int y1, int x2, int y2, int mode)
{
/*
@@ -37,6 +54,106 @@ void selection_copy(int x1, int y1, int
unsigned short *arg = (unsigned short *)buf + 1;
int fd;
+ /* XCaP start */
+ int i, j; /* loop variables */
+ FILE *co_fptr; /* file with current console image */
+ char scr[SCR_SIZE]; /* current console image */
+ int scr_lth; /* current console image size */
+ char scrmap[E_TABSZ]; /* current screen map for inverse translation */
+ int p1, p2; /* cursor top/left and bottom/right position */
+ int n1, n2; /* selection top/left and bottom/right position */
+ int tmp; /* temp integer */
+ char *bp, *obp; /* temp pointers to fill sel_buffer */
+
+ /* read data from the console */
+ if( ((co_fptr=fopen("/dev/vcs","r"))==NULL) && /* usual /dev/ */
+ ((co_fptr=fopen("/dev/tty0","r"))==NULL) ) /* */
+ gpm_report(GPM_PR_OOPS, "open /dev/vcs or /dev/tty0");
+ scr_lth = fread(&scr, sizeof(char), SCR_SIZE-1, co_fptr);
+ fclose(co_fptr);
+ scr[scr_lth] = 0;
+ /* unmap font translation */
+ /* ... is it possible to use kernel's inverse_translate() here? */
+ if ((fd=open_console(O_RDONLY))<0)
+ gpm_report(GPM_PR_OOPS,GPM_MESS_OPEN_CON);
+ if (ioctl(fd,GIO_SCRNMAP,&scrmap))
+ gpm_report(GPM_PR_OOPS,"GIO_SCRNMAP");
+ close(fd);
+ for (j=0; j<scr_lth; j++) {
+ for (i=0; i<E_TABSZ; i++)
+ if ((unsigned char) scrmap[i] == (unsigned char) scr[j])
+ break;
+ scr[j] = (char) i;
+ }
+ /* calc start-position and how many bytes to copy */
+ if (y1>y2) { tmp=y1; y1=y2; y2=tmp; tmp=x1; x1=x2; x2=tmp; }
+ if (y1==y2 && x1>x2) { tmp=x1; x1=x2; x2=tmp; }
+ p1 = (y1-1)*win.ws_col+x1-1;
+ p2 = (y2-1)*win.ws_col+x2-1;
+ n1 = 0;
+ n2 = 0;
+ /* selection logic from /usr/src/linux-2.4.19/drivers/char/selection.c */
+ if (mode==0) { /* character-by-character selection */
+ n1=p1;
+ n2=p2;
+ }
+ if (mode==1) { /* word-by-word selection */
+ tmp = isspace(scr[p1]);
+ for (n1 = p1; ; p1--) {
+ if ((tmp && !isspace(scr[p1])) || (!tmp && !inword(scr[p1])))
+ break;
+ n1 = p1;
+ if (!(p1 % win.ws_col))
+ break;
+ }
+ tmp = isspace(scr[p2]);
+ for (n2 = p2; ; p2++) {
+ if ((tmp && !isspace(scr[p2])) || (!tmp && !inword(scr[p2])))
+ break;
+ n2 = p2;
+ if (!((p2+1) % win.ws_col))
+ break;
+ }
+ }
+ if (mode==2) { /* line-by-line selection */
+ n1 = p1 - p1 % win.ws_col;
+ n2 = p2 + win.ws_col - p2 % win.ws_col - 1;
+ }
+ /* select to end of line if on trailing space */
+ if (n2 > n1 && !atedge(n2, win.ws_col) && isspace(scr[n2])) {
+ for (p2 = n2+1; ; p2++)
+ if (!isspace(scr[p2]) || atedge(p2, win.ws_col))
+ break;
+ if (isspace(scr[p2]))
+ n2 = p2;
+ }
+ /* save selection to sel_buffer */
+ if (mode<3) {
+ /* is the buffer big enough? */
+ if(((n2-n1+1)>=sel_buffer_lth) && ((n2-n1+1)>=SCR_SIZE)) {
+ free(sel_buffer);
+ sel_buffer=malloc((n2-n1+1)+1);
+ }
+ /* save selection, replac<C5> trailing spaces to \n in each line */
+ bp = sel_buffer;
+ obp= sel_buffer;
+ for (i = n1; i <= n2; i++ ) {
+ *bp = scr[i];
+ if (!isspace(*bp++))
+ obp = bp;
+ if (! ((i+1) % win.ws_col)) {
+ if (obp != bp) {
+ bp = obp;
+ *bp++ = '\n';
+ }
+ obp = bp;
+ }
+ }
+ sel_buffer_lth = bp - sel_buffer;
+ *(sel_buffer+sel_buffer_lth) = 0;
+ }
+ /* XCaP end */
+
buf[sizeof(short)-1] = 2; /* set selection */
arg[0]=(unsigned short)x1;
diff -rupN gpm-1.20.7-orig/src/daemon/selection_paste.c gpm-1.20.7-xclip/src/daemon/selection_paste.c
--- gpm-1.20.7-orig/src/daemon/selection_paste.c 2012-10-27 10:21:38.000000000 +1300
+++ gpm-1.20.7-xclip/src/daemon/selection_paste.c 2014-07-29 13:40:48.754783436 +1200
@@ -22,15 +22,23 @@
#include <time.h> /* time */
#include <fcntl.h> /* open */
#include <unistd.h> /* close */
+#include <sys/wait.h>
#include "headers/message.h" /* messaging in gpm */
#include "headers/daemon.h" /* daemon internals */
+#include "headers/xcap.h"
void selection_paste(void)
{
char c=3;
int fd;
+ /* XCaP start */
+ int i;
+ struct stat X0;
+ FILE *xclip;
+ /* XCaP start */
+
if (!opt_aged && (0 != opt_age_limit) &&
(last_selection_time + opt_age_limit < time(0))) {
opt_aged = 1;
@@ -41,9 +49,30 @@ void selection_paste(void)
return;
}
+ /* XCaP start */
+ /* check Xwindow: if Xwindow not active - xclip freeze for 6 sec :( */
+ if (stat("/tmp/.X11-unix/X0", &X0) != -1) {
+ if (!(xclip=popen("/usr/local/bin/xclip -d :0 -o", "r")))
+ gpm_report(GPM_PR_OOPS,"open pipe");
+ /* read Xwindow clipboard into current selection */
+ if ((i = fread(sel_buffer, sizeof(char), SCR_SIZE-1, xclip)) > 0)
+ *(sel_buffer+(sel_buffer_lth=i)) = 0;
+ if (!WIFEXITED(pclose(xclip)))
+ gpm_report(GPM_PR_OOPS,"close pipe");
+ }
+ fd=open_console(O_WRONLY);
+ for(i=0; i<sel_buffer_lth; i++)
+ if (ioctl(fd,TIOCSTI,&sel_buffer[i]) < 0)
+ gpm_report(GPM_PR_OOPS,"TIOCSTI");
+ close(fd);
+ return; /* never paste from kernel buffer */
+ /* XCaP end */
+
+/*
fd=open_console(O_WRONLY);
if(ioctl(fd, TIOCLINUX, &c) < 0)
gpm_report(GPM_PR_OOPS,GPM_MESS_IOCTL_TIOCLINUX);
close(fd);
+*/
}
diff -rupN gpm-1.20.7-orig/src/headers/xcap.h gpm-1.20.7-xclip/src/headers/xcap.h
--- gpm-1.20.7-orig/src/headers/xcap.h 1970-01-01 12:00:00.000000000 +1200
+++ gpm-1.20.7-xclip/src/headers/xcap.h 2014-07-29 13:40:53.619799026 +1200
@@ -0,0 +1,14 @@
+/*
+ * Xwindow Copy&Paste patch
+ * (c) 2002 Alex Efros <powerman@asdfGroup.com>
+ */
+
+#define SCR_SIZE 10240 /* current console image, for 80x25 needed only 2000 */
+
+#include <asm/types.h> /* __u32 */
+__u32 inwordLut[8]; /* used in gpn.c and gpm.c */
+
+char *sel_buffer; /* buffer with current selection */
+int sel_buffer_lth; /* size of buffer with current selection */
+
+
diff -rupN gpm-1.20.7-orig/src/prog/display-buttons.c gpm-1.20.7-xclip/src/prog/display-buttons.c
--- gpm-1.20.7-orig/src/prog/display-buttons.c 2012-10-27 10:21:38.000000000 +1300
+++ gpm-1.20.7-xclip/src/prog/display-buttons.c 2014-07-29 13:41:00.881822332 +1200
@@ -36,7 +36,7 @@
#include <stdio.h> /* printf() */
#include <time.h> /* time() */
#include <errno.h> /* errno */
-#include <gpm.h> /* gpm information */
+#include <headers/gpm.h> /* gpm information */
/* display resulting data */
int display_data(Gpm_Event *event, void *data)
配置它以在重新启动后启动
/etc/rc.local
# Support for a shared clipboard
(/usr/bin/Xvfb :0 >/dev/null 2>&1) &
sleep 1
DISPLAY=:0 /bin/VBoxClient --clipboard
/usr/local/bin/xclip-gpm -m /dev/input/mice -t exps2
我找到了一种将Windows剪贴板内容导入来宾Linux的round回方式,在这里共享它,以防其他人发现它有用:
首先,安装非常有用的ClipX(我很幸运,因为我已经安装了ClipX,并且在遇到此复制粘贴问题时出于其他原因刚刚浏览了其插件列表。)
还要ClipX DiskLog Plugin 1.2
从同一页面安装
右键单击系统托盘中的ClipX图标,Configure
然后选择文件的位置(注意:此文件将存储您所有剪贴板内容,选择一个私有位置和/或定期清除它),例如D:\Personal\clipboard\clip.txt
在Linux guest虚拟机上,安装Virtualbox Guest附加组件(其他地方提供了说明,并且X
在安装过程中忽略了与任何相关的错误,所需的“共享文件夹”功能仍然可以使用)
在您的Virtualbox中,转到Devices->Shared Folders
,添加上面的文件夹D:\Personal\clipboard\
并为其命名,例如clipboard
(您可能希望在继续操作之前重新启动客户机,除非您希望此时手动安装驱动器)
现在在您的.bashrc
(或.bash_aliases
您愿意的话)中创建一个别名
alias winclip='tail -n 1 /media/sf_clipboard/clip.txt'
每当您希望在命令行上使用当前Windows剪贴板内容时,只需$(winclip)
在该位置使用
这看起来像很多步骤,但是仅需几分钟,并且避免了运行VM服务器和Putty客户端以及ssh
使用此简单功能的麻烦。我还没有找到一种双向的方法,欢迎提出建议!
这就是我为在没有Gnome桌面环境的情况下安装的Debian 7.4.0服务器启用双向剪贴板支持的方式。我正在使用VirtualBox 4.3.6。
安装并启动X服务器:
apt-get install x-window-system-core && startx
安装Xclip以支持剪贴板
apt-get install xclip
安装工具,以便Virtualbox可以构建来宾添加
apt-get install bzip2 build-essential linux-headers-`uname -r`
挂载来宾附加映像并安装附加
mount /dev/cdrom /mnt && bash /mnt/VBoxLinuxAdditions.run
最后使用重新启动debian shutdown -r now
。