Общий буфер обмена в Virtualbox только с командной строкой гостя Debian

14

У меня установлен гостевой Debian на хосте Windows 7 с использованием Virtualbox. Установка по умолчанию включала virtualbox-ose-guest-utils, поэтому у меня должно быть все, что мне нужно. Как включить общий буфер обмена?

alnorth29
источник
Вы можете установить SSH-сервер и затем вставлять вещи через сеанс SSH.
Робин Динс

Ответы:

10

Я боюсь, что вы не можете иметь общий буфер обмена только для гостя из командной строки.

Это потому, что TTY на самом деле не создает надлежащий буфер обмена, который могут использовать гостевые дополнения, для этого вам нужен полный графический интерфейс.

Вам будет лучше использовать SSH для входа в гостевую систему с хоста. Таким образом, вы можете использовать функции вашего SSH-клиента, например, Putty, чтобы поделиться буфером обмена.

Джулиан Найт
источник
Или альтернатива последовательной линии, хотя это идет со всеми недостатками последовательной связи (например, без динамического изменения размера).
phk
8

Это можно сделать. Мне не удалось настроить двунаправленную работу со следующими компонентами, но Host to Guest (т.е. вставка содержимого в текстовую консоль) работает. Следующие инструкции предназначены для CentOS 5/6/7, однако аналогичный механизм должен работать и для других вкусов.

Это позволит синхронизировать буфер обмена X11 с буфером обмена gpm. Когда параметр «Общий буфер обмена» настроен для «Host to Guest», VirtualBox обновит буфер обмена X11 при изменении буфера обмена хоста… исправленный gpm затем будет использовать xclip для извлечения данных из буфера обмена X11 в буфер обмена gpm… который затем можно вставить с помощью средняя кнопка мыши.

Общий буфер обмена

Можно настроить общий доступ к буферу обмена «Host to Guest» для работы в режиме сервер / консоль. Общий доступ «Гость к хосту» в настоящее время не работает, возможно, из-за проблемы между 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
SharedClipboard
источник
6

Он еще не реализован, см. Этот выдающийся запрос о функциях, которому уже 6 лет.

https://www.virtualbox.org/ticket/1139

начинающий
источник
Ну, это сделать 12 лет, сейчас! :(
Orabîg
2

Я нашел обходной способ загрузки содержимого буфера обмена Windows в гостевой Linux, поделившись им здесь на тот случай, если кто-нибудь еще найдет это полезным:

  • Во-первых, установите невероятно полезный ClipX (мне повезло, что он уже установлен и только что просматривал список плагинов по другим причинам, когда я столкнулся с этой проблемой копирования-вставки).

  • Также установите ClipX DiskLog Plugin 1.2с той же страницы

  • Щелкните правой кнопкой мыши значок ClipX на панели задач Configureи выберите местоположение для файла (примечание: этот файл будет хранить все содержимое буфера обмена, выберет личное местоположение и / или регулярно его очищать), скажем,D:\Personal\clipboard\clip.txt

  • На гостевой системе Linux установите гостевые дополнения Virtualbox (инструкции доступны в другом месте и игнорируйте любые Xсвязанные с этим ошибки во время установки, необходимая функция «общих папок» все равно будет работать)

  • В вашей виртуальной коробке перейдите Devices->Shared Folders, добавьте указанную выше папку D:\Personal\clipboard\и дайте ей имя, скажем clipboard(вы можете перезагрузить гостя, прежде чем продолжить, если вы не хотите вручную подключить диск в этот момент)

  • Теперь создайте псевдоним в вашем .bashrc(или, .bash_aliasesесли хотите), который говорит

    alias winclip='tail -n 1 /media/sf_clipboard/clip.txt'
    
  • Всякий раз, когда вы хотите использовать текущее содержимое буфера обмена Windows в командной строке, просто используйте $(winclip)в этой точке

Это выглядит как множество шагов, но все это занимает всего несколько минут и позволяет избежать хлопот, связанных с работой сервера виртуальной машины и клиента Putty, а также sshс этой простой функцией. Я не нашел способа сделать его двунаправленным, предложения приветствуются!

sundar - Восстановить Монику
источник
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

Наконец перезапустите Debian с помощью shutdown -r now.

Я получил инструкции по установке гостевых дополнений здесь . Эта запись в блоге полезна для настройки xclip.

Матиас Браун
источник