ฉันมีแขก Debian ติดตั้งบนโฮสต์ Windows 7 โดยใช้ Virtualbox การติดตั้งรวมถึง virtualbox-ose-guest-utils ตามค่าเริ่มต้นดังนั้นฉันควรมีทุกสิ่งที่ฉันต้องการ ฉันจะเปิดคลิปบอร์ดที่ใช้ร่วมกันได้อย่างไร
ฉันมีแขก Debian ติดตั้งบนโฮสต์ Windows 7 โดยใช้ Virtualbox การติดตั้งรวมถึง virtualbox-ose-guest-utils ตามค่าเริ่มต้นดังนั้นฉันควรมีทุกสิ่งที่ฉันต้องการ ฉันจะเปิดคลิปบอร์ดที่ใช้ร่วมกันได้อย่างไร
คำตอบ:
ฉันกลัวว่าคุณไม่สามารถมีคลิปบอร์ดที่ใช้ร่วมกันในแขกบรรทัดคำสั่งเท่านั้น
นี่เป็นเพราะ TTY ไม่ได้สร้างคลิปบอร์ดที่เหมาะสมที่แขกเพิ่มเติมสามารถใช้ได้คุณต้องมี GUI แบบเต็มสำหรับสิ่งนั้น
คุณจะดีขึ้นเมื่อใช้ SSH เพื่อเข้าสู่ระบบแขกจากโฮสต์ ด้วยวิธีนี้คุณสามารถใช้คุณสมบัติของไคลเอนต์ SSH ของคุณเช่น Putty เพื่อแชร์คลิปบอร์ด
สิ่งนี้สามารถทำได้ ฉันไม่สามารถทำงานแบบสองทิศทางต่อไปนี้ได้ แต่ Host to Guest (เช่นวางเนื้อหาลงในคอนโซลข้อความ) ใช้งานได้ คำแนะนำต่อไปนี้สำหรับ CentOS 5/6/7 อย่างไรก็ตามกลไกที่คล้ายกันควรใช้กับรสชาติอื่น ๆ
สิ่งนี้จะทำให้คลิปบอร์ด X11 ซิงค์กับคลิปบอร์ด gpm เมื่อการตั้งค่าคลิปบอร์ดที่ใช้ร่วมกันได้รับการกำหนดค่าสำหรับ "โฮสต์ต่อแขก" VirtualBox จะอัปเดตคลิปบอร์ด X11 เมื่อมีการเปลี่ยนแปลงคลิปบอร์ดโฮสต์ ... gpm ที่ได้รับการแก้ไขจะใช้ xclip เพื่อดึงข้อมูลคลิปบอร์ด X11 ลงในคลิปบอร์ด gpm ... ปุ่มกลางของเมาส์
เป็นไปได้ที่จะได้รับการแชร์คลิปบอร์ด“ โฮสต์สู่แขก” เพื่อทำงานในโหมดเซิร์ฟเวอร์ / คอนโซล การแบ่งปัน“ แขกกับโฮสต์” ไม่ทำงานในขณะนี้อาจเกิดจากปัญหาระหว่าง VBoxClient และ Xvfb
ยำติดตั้ง Xvfb
mount / dev / cdrom / mnt /mnt/VBoxLinuxAdditions.run
ดาวน์โหลดคอมไพล์และติดตั้ง xclip ( http://sourceforge.net/projects/xclip/ ) เป็น / usr / local / bin / xclip
ดาวน์โหลด gpm ที่มาล่าสุดและแก้ไขด้วยการเปลี่ยนแปลงต่อไปนี้
ติดตั้งไบนารีเป็น / usr / local / bin / xclip-gpm
นี่เป็นแพทช์รุ่นปรับปรุงโดย Alex Efros ( http://powerman.name/patch/gpm.html )
แกลลอนต่อนาที-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
ยังไม่ได้ใช้งานโปรดดูคำขอคุณลักษณะที่โดดเด่นซึ่งมีอายุ 6 ปีแล้ว
ฉันพบวิธีการวงเวียนในการรับเนื้อหาคลิปบอร์ดของ Windows ไปเป็น Linux แขกแบ่งปันที่นี่ในกรณีที่คนอื่นเห็นว่ามีประโยชน์:
ก่อนอื่นให้ติดตั้งClipX ที่มีประโยชน์อย่างเหลือเชื่อ(ฉันโชคดีที่ฉันติดตั้งไว้แล้วและเพิ่งเรียกดูผ่านรายการปลั๊กอินด้วยเหตุผลอื่นเมื่อฉันเจอปัญหาการคัดลอกวาง)
ติดตั้งClipX DiskLog Plugin 1.2
จากหน้าเดียวกัน
คลิกขวาที่ไอคอน ClipX ในซิสเต็มเทรย์Configure
แล้วเลือกตำแหน่งสำหรับไฟล์ (หมายเหตุ: ไฟล์นี้จะเก็บเนื้อหาคลิปบอร์ดทั้งหมดของคุณเลือกตำแหน่งส่วนตัวและ / หรือล้างมันเป็นประจำ) สมมติว่าD:\Personal\clipboard\clip.txt
บนผู้เยี่ยมชม Linux ของคุณให้ติดตั้งส่วนเพิ่มเติม 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
ผ่านคุณสมบัติที่เรียบง่ายนี้ ฉันไม่พบวิธีที่จะทำให้เป็นแบบสองทิศทางคำแนะนำยินดีต้อนรับ!
นี่คือวิธีที่ฉันเปิดใช้งานการสนับสนุนคลิปบอร์ดสองทิศทางสำหรับเซิร์ฟเวอร์ Debian 7.4.0 ของฉันที่ฉันติดตั้งโดยไม่มีสภาพแวดล้อมเดสก์ท็อป Gnome ฉันใช้ 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
shutdown -r now
ในที่สุดก็เริ่มต้นใหม่กับเดเบียน
ผมได้คำแนะนำสำหรับการติดตั้งเพิ่มเติมของผู้เข้าพักที่นี่ นี้รายการบล็อกจะเป็นประโยชน์สำหรับการปรับแต่ง xclip