Tôi có một khách Debian được cài đặt trên máy chủ Windows 7 bằng Virtualbox. Việc cài đặt bao gồm virtualbox-ose-guest-utils theo mặc định, vì vậy tôi nên có mọi thứ tôi cần. Làm thế nào tôi có thể bật clipboard được chia sẻ?
Tôi có một khách Debian được cài đặt trên máy chủ Windows 7 bằng Virtualbox. Việc cài đặt bao gồm virtualbox-ose-guest-utils theo mặc định, vì vậy tôi nên có mọi thứ tôi cần. Làm thế nào tôi có thể bật clipboard được chia sẻ?
Câu trả lời:
Tôi sợ rằng bạn không thể có một bảng tạm được chia sẻ trên một khách chỉ dòng lệnh.
Điều này là do TTY không thực sự tạo ra một bảng tạm phù hợp mà các bổ sung khách có thể sử dụng, bạn cần một GUI đầy đủ cho điều đó.
Bạn sẽ tốt hơn khi sử dụng SSH để đăng nhập vào khách từ máy chủ lưu trữ. Bằng cách đó, bạn có thể sử dụng các tính năng của máy khách SSH của mình, ví dụ như Putty để chia sẻ bảng tạm.
Điều này có thể thực hiện được. Tôi đã không thể làm việc hai chiều với những điều sau đây, nhưng Host to Guest (tức là dán nội dung vào bảng điều khiển văn bản) không hoạt động. Các hướng dẫn sau đây dành cho CentOS 5/6/7, tuy nhiên chúng là một cơ chế tương tự sẽ hoạt động cho các hương vị khác.
Điều này sẽ giữ cho bảng tạm X11 đồng bộ với bảng tạm gpm. Khi cài đặt Bảng chia sẻ được định cấu hình cho Máy chủ lưu trữ thành Khách lưu trữ, thì VirtualBox sẽ cập nhật bảng tạm X11 khi bảng tạm của máy chủ thay đổi. nút chuột giữa.
Có thể nhận được chia sẻ clipboard của máy chủ lưu trữ trên máy khách để làm việc ở chế độ máy chủ / bảng điều khiển. Hiện tại, tính năng chia sẻ khách và lưu trữ trên máy chủ hiện không hoạt động, có thể là do sự cố giữa VBoxClient và Xvfb.
yum cài đặt Xvfb
gắn kết / dev / cdrom / mnt /mnt/VBoxLinuxAdditions.run
Tải xuống, biên dịch và cài đặt xclip ( http://sourceforge.net/projects/xclip/ ) dưới dạng / usr / local / bin / xclip.
Tải về nguồn gpm mới nhất và vá nó với các thay đổi sau.
Cài đặt nhị phân là / usr / local / bin / xclip-gpm.
Đây là phiên bản cập nhật của bản vá của 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)
Cấu hình nó để bắt đầu sau khi khởi động lại
/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
Nó chưa được thực hiện, hãy xem yêu cầu tính năng nổi bật này đã được 6 năm tuổi.
Tôi đã tìm thấy một cách xoay vòng để đưa nội dung clipboard của Windows vào máy khách Linux, chia sẻ nó ở đây trong trường hợp bất kỳ ai khác thấy nó hữu ích:
Đầu tiên, cài đặt ClipX cực kỳ hữu ích (Tôi đã may mắn vì tôi đã cài đặt nó và vừa duyệt qua danh sách plugin của nó vì những lý do khác khi tôi gặp phải vấn đề sao chép này.)
Cũng cài đặt ClipX DiskLog Plugin 1.2
từ cùng một trang
Nhấp chuột phải vào biểu tượng ClipX trong khay hệ thống Configure
và chọn vị trí cho tệp (lưu ý: tệp này sẽ lưu trữ tất cả nội dung trong bảng tạm của bạn, chọn một vị trí riêng tư và / hoặc xóa nó thường xuyên), giả sửD:\Personal\clipboard\clip.txt
Trên máy khách Linux của bạn, hãy cài đặt các bổ sung Virtualbox Guest (hướng dẫn có sẵn ở nơi khác và bỏ qua mọi X
lỗi liên quan trong quá trình cài đặt, tính năng "thư mục chia sẻ" cần thiết vẫn sẽ hoạt động)
Trong Virtualbox của bạn Devices->Shared Folders
, hãy thêm thư mục trên D:\Personal\clipboard\
và đặt tên cho nó clipboard
(bạn có thể muốn khởi động lại khách trước khi tiếp tục trừ khi bạn muốn gắn ổ đĩa vào thời điểm này)
Bây giờ hãy tạo một bí danh trong .bashrc
(hoặc .bash_aliases
nếu bạn thích) có nghĩa là
alias winclip='tail -n 1 /media/sf_clipboard/clip.txt'
Bất cứ khi nào bạn muốn sử dụng nội dung clipboard của Windows hiện tại trên dòng lệnh, chỉ cần sử dụng $(winclip)
tại thời điểm đó
Điều đó có vẻ như rất nhiều bước, nhưng tất cả chỉ mất vài phút và tránh rắc rối khi chạy máy chủ VM và máy khách Putty và ssh
sử dụng tính năng đơn giản này. Tôi đã không tìm thấy một cách để làm cho nó hai chiều mặc dù, đề nghị hoan nghênh!
Đây là cách tôi kích hoạt hỗ trợ clipboard hai chiều cho máy chủ Debian 7.4.0 mà tôi đã cài đặt mà không có môi trường máy tính để bàn Gnome. Tôi đang sử dụng VirtualBox 4.3.6.
Cài đặt và khởi động máy chủ X:
apt-get install x-window-system-core && startx
Cài đặt xclip để hỗ trợ clipboard
apt-get install xclip
Cài đặt công cụ để Virtualbox có thể xây dựng các bổ sung của khách
apt-get install bzip2 build-essential linux-headers-`uname -r`
Gắn hình ảnh bổ sung của khách và cài đặt các bổ sung
mount /dev/cdrom /mnt && bash /mnt/VBoxLinuxAdditions.run
Cuối cùng khởi động lại debian với shutdown -r now
.
Tôi đã nhận được hướng dẫn để cài đặt các bổ sung của khách ở đây . Mục blog này rất hữu ích để tùy chỉnh xclip.