Существует два инструмента командной строки (в двух разных пакетах) для доступа к буферу обмена X:
xclip
xsel
Я хотел бы знать разницу между этими двумя и услышать рекомендацию, какую использовать в каких случаях.
Существует два инструмента командной строки (в двух разных пакетах) для доступа к буферу обмена X:
xclip
xsel
Я хотел бы знать разницу между этими двумя и услышать рекомендацию, какую использовать в каких случаях.
Ответы:
Оба 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);