Существует два инструмента командной строки (в двух разных пакетах) для доступа к буферу обмена X:
xclipxsel
Я хотел бы знать разницу между этими двумя и услышать рекомендацию, какую использовать в каких случаях.
Существует два инструмента командной строки (в двух разных пакетах) для доступа к буферу обмена X:
xclipxselЯ хотел бы знать разницу между этими двумя и услышать рекомендацию, какую использовать в каких случаях.
Ответы:
Оба xclipи xselмогут хранить текст в 3 разных выделениях (по умолчанию это первичное выделение). По своему опыту я знаю, что основной выбор - это то, что вы выделяете и отпускаете средним щелчком мыши (что соответствует нажатию правой и левой клавиш сенсорной панели на ноутбуке). Буфер обмена является традиционным CtrlV.
Однако, изучив manстраницы для обоих, я обнаружил, что xclipвыигрывает в одном аспекте - чтение из входного файла:
xieerqi:
$ cat testfile.txt
HELLOWORLD
xieerqi:
$ xclip -selection clipboard testfile.txt
xieerqi:
$ HELLOWORLD
mksh: HELLOWORLD: not found
xieerqi:
$ xsel testfile.txt
Usage: xsel [options]
Manipulate the X sele . . . (usage page goes on)
Конечно, вы можете использовать перенаправление оболочки, xselчтобы обойти это
xieerqi:
$ xsel --clipboard < testfile.txt
xieerqi:
$ HELLOWORLD
mksh: HELLOWORLD: not found
xclipтакже выигрывает в том, что вы можете выводить содержимое буфера обмена в файл (что, возможно, полезно, если вы хотите перенаправить выбор PRIMARY, то есть выделение). xselпредлагает только вывод на стандартный вывод
xselможно работать только через STDIN / STDOUT, а xclipтакже использовать там реальные файлы? Как скучно! Ну, я xselнедавно подружился и могу использовать перенаправление оболочки на файлы, так что я буду продолжать это использовать.
xclipсегодня и задавался вопросом, был ли это правильный выбор. Ваш ответ подтвердил, что это потому, что я создаю файл из буфера обмена для использования с diffкомандой. +1 Спасибо :)
В дополнение к ответу @Serg , есть часть информации со страницы Tmux в Arch Wiki, которая может быть полезна в некоторых конкретных случаях :
в отличие от xsel, он [xclip] лучше работает при печати необработанных битовых потоков, которые не соответствуют текущей локали. Тем не менее, лучше использовать xsel вместо xclip, поскольку xclip не закрывает STDOUT после чтения из буфера tmux. Таким образом, tmux не знает, что задание копирования выполнено, и продолжает ждать завершения xclip, что делает tmux безразличным. Обходной путь - перенаправить STDOUT xclip в / dev / null.
xclip является серьезной проблемой, если вы столкнетесь с ней. Я потратил 2 часа на его отладку. Я наконец перешел на xsel -biи xsel -bo.
Что-то еще нужно иметь в виду, xselимеет меньше зависимостей, чем xclip:
# apt-cache depends xsel
xsel
Depends: libc6
Depends: libx11-6
Conflicts: xsel:i386
# apt-cache depends xclip
xclip
Depends: libc6
Depends: libx11-6
Depends: libxmu6
Conflicts: xclip:i386
Используйте xclip, потому что xselне может извлечь двоичные данные из буфера обмена, например, снимок экрана. Например, сохранить скриншот в буфер обмена:
$ maim -s | xclip -selection clipboard -t image/png
Затем сохраните в файл и сравните вывод:
$ xclip -o -selection clipboard > 1xclip
$ xsel -o --clipboard > 1xsel
$ ls -go 1*
-rw-rw-r-- 1 11948 Sep 26 20:13 1xclip
-rw-rw-r-- 1 0 Sep 26 20:13 1xsel
xclipне всегда можно обрабатывать двоичные данные, например, при использовании кнопки «Копировать в буфер» из gnome-screenshot я ничего не получаю. При копировании изображения с помощью Ctrl + C, например, из документа LibreOffice, оно работает только в том случае, если я вручную указываю целевой тип, например xclip -o -t image/png -selection clipboard.
gnome-screenshotвообще, но это другая проблема - gitlab.gnome.org/GNOME/gnome-screenshot/issues/14
Есть еще одна причина использовать xclip поверх xsel - xclip может манипулировать буфером обрезки 0, передавая -selection buffer-cut, чего не может сделать xsel.
Относительно легко позволить ему манипулировать и другими буферами вырезания; Вот мой патч, хотя он не проверен и не дает никаких гарантий.
diff --git a/xclip.c b/xclip.c
index 5fc760cb7..eeb05f662 100644
--- a/xclip.c
+++ b/xclip.c
@@ -35,11 +35,12 @@
#include "xclib.h"
/* command line option table for XrmParseCommand() */
-XrmOptionDescRec opt_tab[14];
+XrmOptionDescRec opt_tab[15];
/* Options that get set on the command line */
int sloop = 0; /* number of loops */
char *sdisp = NULL; /* X display to connect to */
+int bufnum = 0; /* Cut buffer number to use */
Atom sseln = XA_PRIMARY; /* X selection to work with */
Atom target = XA_STRING;
@@ -165,6 +166,9 @@ doOptSel(void)
break;
case 'b':
sseln = XA_STRING;
+ if (XrmGetResource(opt_db, "xclip.buffer", "Xclip.Buffer", &rec_typ, &rec_val)) {
+ bufnum = atoi(&rec_val.addr[0]);
+ }
break;
}
@@ -177,8 +181,10 @@ doOptSel(void)
fprintf(stderr, "XA_SECONDARY");
if (sseln == XA_CLIPBOARD(dpy))
fprintf(stderr, "XA_CLIPBOARD");
- if (sseln == XA_STRING)
+ if (sseln == XA_STRING) {
fprintf(stderr, "XA_STRING");
+ fprintf(stderr, "\nUsing buffer number %d", bufnum);
+ }
fprintf(stderr, "\n");
}
@@ -276,7 +282,7 @@ doIn(Window win, const char *progname)
/* Handle cut buffer if needed */
if (sseln == XA_STRING) {
- XStoreBuffer(dpy, (char *) sel_buf, (int) sel_len, 0);
+ XStoreBuffer(dpy, (char *) sel_buf, (int) sel_len, bufnum);
return EXIT_SUCCESS;
}
@@ -445,7 +451,7 @@ doOut(Window win)
unsigned int context = XCLIB_XCOUT_NONE;
if (sseln == XA_STRING)
- sel_buf = (unsigned char *) XFetchBuffer(dpy, (int *) &sel_len, 0);
+ sel_buf = (unsigned char *) XFetchBuffer(dpy, (int *) &sel_len, bufnum);
else {
while (1) {
/* only get an event if xcout() is doing something */
@@ -595,6 +601,11 @@ main(int argc, char *argv[])
opt_tab[13].argKind = XrmoptionNoArg;
opt_tab[13].value = (XPointer) xcstrdup(ST);
+ opt_tab[14].option = xcstrdup("-buffer");
+ opt_tab[14].specifier = xcstrdup(".buffer");
+ opt_tab[14].argKind = XrmoptionSepArg;
+ opt_tab[14].value = (XPointer) NULL;
+
/* parse command line options */
doOptMain(argc, argv);