'xclip' กับ 'xsel'


43

มีเครื่องมือบรรทัดคำสั่งสองตัว (ในแพ็คเกจที่แตกต่างกันสองแพคเกจ) เพื่อเข้าถึงคลิปบอร์ด X:

  • xclip
  • xsel

ฉันชอบที่จะทราบความแตกต่างระหว่างทั้งสองและได้ยินคำแนะนำที่ควรใช้ในกรณีใด


1
สิ่งที่ฉันอยากรู้ในวันนี้ :) +1
WinEunuuchs2Unix

คำตอบ:


26

ทั้งสอง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ยังชนะในความจริงที่ว่าคุณสามารถส่งออกเนื้อหาของคลิปบอร์ดไปยังไฟล์ (ซึ่งอาจมีประโยชน์เมื่อคุณต้องการเปลี่ยนเส้นทางการเลือกหลักเช่นไฮไลท์) xselนำเสนอเฉพาะเอาต์พุตไปยัง stdout


2
ดังนั้นจึงไม่มีความแตกต่างนอกจากที่xselสามารถทำงานผ่าน STDIN / STDOUT เท่านั้นในขณะที่xclipยังสามารถใช้ไฟล์จริงได้ น่าเบื่อแค่ไหน! ฉันเคยเป็นเพื่อนกันxselมานานแล้วและสามารถใช้ชีวิตด้วยการใช้การเปลี่ยนเส้นทางของเชลล์ไปยังไฟล์ดังนั้นฉันจะใช้มันต่อไป
ผู้บัญชาการ Byte

2
เว้นแต่ว่าฉันพลาดบางสิ่งบางอย่างใน man page หรือมีคุณสมบัติที่ซ่อนอยู่นั่นคือทั้งหมดที่มีอยู่ในโปรแกรมทั้งสองนี้ :) ทั้งสองทำงานได้ดีพอดังนั้นฉันเดาว่ามันเป็นเรื่องที่ชอบมากกว่าอะไร
Sergiy Kolodyazhnyy

ฉันติดตั้งxclipวันนี้และสงสัยว่ามันเป็นตัวเลือกที่เหมาะสมหรือไม่ คำตอบของคุณยืนยันว่าเป็นเพราะฉันกำลังสร้างไฟล์จากคลิปบอร์ดเพื่อใช้กับdiffคำสั่ง +1 ขอบคุณ :)
WinEunuuchs2Unix

1
ฉันวิ่งข้ามโพสต์มีฟังก์ชั่น wrapper ที่ยอดเยี่ยมสำหรับ xclip ที่อาจทำให้สเกลของมันอยู่ไกลเกินเอื้อม madebynathan.com/2011/10/04/a-nicer-way-to-use-xclip
dragon788

@ dragon788 ดีนี่เป็นคำถามที่ดี แต่คำถามเกี่ยวกับความแตกต่างในการใช้คำสั่งสองคำสั่งดังนั้นฉันจึงไม่ค่อยเห็นว่าสิ่งนี้เกี่ยวข้องกันอย่างไร
Sergiy Kolodyazhnyy

22

นอกเหนือจากคำตอบ @Serg ยังมีข้อมูลบางส่วนจากหน้า Tmux ใน Arch Wikiที่สามารถเป็นประโยชน์ในบางกรณี :

ซึ่งแตกต่างจาก xsel มัน [xclip] ทำงานได้ดีขึ้นในการพิมพ์บิตสตรีมดิบที่ไม่เหมาะสมกับสถานที่ปัจจุบัน อย่างไรก็ตามมันเป็น neater ที่จะใช้ xsel แทน xclip เพราะxclip ไม่ได้ปิด STDOUTหลังจากอ่านจากบัฟเฟอร์ของ tmux ดังนั้น tmux จึงไม่ทราบว่างานการคัดลอกเสร็จสิ้นและยังคงรอการยกเลิกของ xclip ดังนั้นการแสดงผล tmux จึงไม่ตอบสนอง วิธีแก้ปัญหาคือเปลี่ยนเส้นทาง STDOUT ของ xclip เป็น / dev / null


นี่ไม่ได้ปิดปัญหาSTDOUTด้วยxclipเป็นปัญหาสำคัญหากคุณพบปัญหา ฉันเสียเวลาแก้จุดบกพร่อง 2 ชั่วโมง ในที่สุดผมก็เปลี่ยนไปและxsel -bi xsel -bo
Bruno Bronosky

15

สิ่งอื่นที่ควรทราบ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

2
ฉันสงสัยว่าการติดตั้งส่วนใหญ่มี libxmu6 อยู่แล้ว แต่แพ็คเกจจำนวนมากเช่น xterm, x11-apps และ x11-utils ขึ้นอยู่กับมัน
JoshB

6

ใช้xclipเพราะxselไม่สามารถแยกข้อมูลไบนารีจากคลิปบอร์ดเช่น screenshost ตัวอย่างเช่นบันทึกภาพหน้าจอไปยังคลิปบอร์ด:

$ 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

1
ฉันพบว่าxclipไม่สามารถจัดการกับข้อมูลไบนารีได้เสมอเช่นเมื่อใช้ปุ่ม "คัดลอกไปยังคลิปบอร์ด" จากหน้าจอ gnome-screenshot ฉันไม่ได้รับผลลัพธ์เลย เมื่อคัดลอกภาพด้วยการกด Ctrl + C จากเช่นเอกสาร LibreOffice xclip -o -t image/png -selection clipboardก็จะทำงานเฉพาะถ้าผมด้วยตนเองระบุประเภทเป้าหมายเช่น
ผู้บัญชาการ Byte

2
ฉันไม่ได้รับผลลัพธ์gnome-screenshotเลย แต่นั่นเป็นปัญหาอีกอย่าง - gitlab.gnome.org/GNOME/gnome-sc Screenshot/issues/14
Anatoly techtonik

0

มีอีกเหตุผลหนึ่งที่ใช้ xclip บน xsel - xclip สามารถจัดการ cut buffer 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);

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