คลิปบอร์ดที่ใช้ร่วมกันใน Virtualbox พร้อมบรรทัดคำสั่งเฉพาะแขก Debian


14

ฉันมีแขก Debian ติดตั้งบนโฮสต์ Windows 7 โดยใช้ Virtualbox การติดตั้งรวมถึง virtualbox-ose-guest-utils ตามค่าเริ่มต้นดังนั้นฉันควรมีทุกสิ่งที่ฉันต้องการ ฉันจะเปิดคลิปบอร์ดที่ใช้ร่วมกันได้อย่างไร


คุณสามารถติดตั้งเซิร์ฟเวอร์ SSH แล้ววางสิ่งต่าง ๆ ผ่านเซสชัน SSH
Robin Dinse

คำตอบ:


10

ฉันกลัวว่าคุณไม่สามารถมีคลิปบอร์ดที่ใช้ร่วมกันในแขกบรรทัดคำสั่งเท่านั้น

นี่เป็นเพราะ TTY ไม่ได้สร้างคลิปบอร์ดที่เหมาะสมที่แขกเพิ่มเติมสามารถใช้ได้คุณต้องมี GUI แบบเต็มสำหรับสิ่งนั้น

คุณจะดีขึ้นเมื่อใช้ SSH เพื่อเข้าสู่ระบบแขกจากโฮสต์ ด้วยวิธีนี้คุณสามารถใช้คุณสมบัติของไคลเอนต์ SSH ของคุณเช่น Putty เพื่อแชร์คลิปบอร์ด


หรือทางเลือกสายอนุกรมแม้ว่าจะมาพร้อมกับข้อเสียทั้งหมดของการเชื่อมต่อแบบอนุกรม (เช่นไม่มีการปรับขนาดแบบไดนามิก)
phk

8

สิ่งนี้สามารถทำได้ ฉันไม่สามารถทำงานแบบสองทิศทางต่อไปนี้ได้ แต่ Host to Guest (เช่นวางเนื้อหาลงในคอนโซลข้อความ) ใช้งานได้ คำแนะนำต่อไปนี้สำหรับ CentOS 5/6/7 อย่างไรก็ตามกลไกที่คล้ายกันควรใช้กับรสชาติอื่น ๆ

สิ่งนี้จะทำให้คลิปบอร์ด X11 ซิงค์กับคลิปบอร์ด gpm เมื่อการตั้งค่าคลิปบอร์ดที่ใช้ร่วมกันได้รับการกำหนดค่าสำหรับ "โฮสต์ต่อแขก" VirtualBox จะอัปเดตคลิปบอร์ด X11 เมื่อมีการเปลี่ยนแปลงคลิปบอร์ดโฮสต์ ... gpm ที่ได้รับการแก้ไขจะใช้ xclip เพื่อดึงข้อมูลคลิปบอร์ด X11 ลงในคลิปบอร์ด gpm ... ปุ่มกลางของเมาส์

คลิปบอร์ดที่ใช้ร่วมกัน

เป็นไปได้ที่จะได้รับการแชร์คลิปบอร์ด“ โฮสต์สู่แขก” เพื่อทำงานในโหมดเซิร์ฟเวอร์ / คอนโซล การแบ่งปัน“ แขกกับโฮสต์” ไม่ทำงานในขณะนี้อาจเกิดจากปัญหาระหว่าง VBoxClient และ Xvfb

ติดตั้ง Xvfb

    ยำติดตั้ง Xvfb

ติดตั้ง VBoxClient

    mount / dev / cdrom / mnt
    /mnt/VBoxLinuxAdditions.run

ติดตั้ง xclip

ดาวน์โหลดคอมไพล์และติดตั้ง xclip ( http://sourceforge.net/projects/xclip/ ) เป็น / usr / local / bin / xclip

ติดตั้ง gpm ที่แพตช์ (ด้วยการรวม 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


2

ฉันพบวิธีการวงเวียนในการรับเนื้อหาคลิปบอร์ดของ 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ผ่านคุณสมบัติที่เรียบง่ายนี้ ฉันไม่พบวิธีที่จะทำให้เป็นแบบสองทิศทางคำแนะนำยินดีต้อนรับ!


1

นี่คือวิธีที่ฉันเปิดใช้งานการสนับสนุนคลิปบอร์ดสองทิศทางสำหรับเซิร์ฟเวอร์ 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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.