在Bash脚本中管道往返剪贴板


945

是否可以在Bash中通过管道与剪贴板通信?

无论是管道到设备手柄或从设备手柄到管道,还是使用辅助应用程序,我都找不到任何东西。

例如,如果/dev/clip是链接到剪贴板的设备,我们可以这样做:

cat /dev/clip        # Dump the contents of the clipboard
cat foo > /dev/clip  # Dump the contents of "foo" into the clipboard

3
我一直:%y+在vim中使用,这是vim所说的“将所有行都提取(复制)到'+'寄存器(X PRIMARY剪贴板)中”。%如果要具体说明,可以用范围代替。但是有三个警告:1.现在,您必须将任何文本保存到文件中,然后才能将其复制。这xclip与答案中提到的命令相反。2.如果您还不知道如何vim,这可能很乏味。3.只有在编译vim时启用了某些功能时,才能执行此操作。如果安装了GVim,则默认情况下应在GUI和vim的终端实例中将其启用。
Braden Best 2015年

1
@BradenBest最好将其作为答案。我在NIX环境中,无法安装xclip。您的回答就像一个魅力。
HankCa'5

@HankCa好吧,我发布了答案。告诉我你的想法。
Braden Best,

@BradenBest是一个非常全面的答案。我只是喜欢:%y+一个,但是好的,您已经涵盖了所有基础!好一个
HankCa's

另一个选择:使用一些perl脚本:无需安装。请参阅下面的答案
VonC

Answers:


861

您可能要处理很多剪贴板。我希望您可能是Linux用户,希望将内容放入X Windows主剪贴板。通常,您要与之交谈的剪贴板都有一个实用程序,可让您与其交谈。

对于X,有xclip(和其他)。在大多数应用程序中,xclip -selection c会将数据发送到与兼容的剪贴板。Ctrl + CCtrl + V

如果您使用的是Mac OS X,则显示pbcopy

如果你在Linux终端模式(没有X)是再看看gpm屏幕具有剪贴板。尝试screen命令readreg

在Windows 10+或cygwin下,使用/dev/clipboardclip



24
在Windows上,/dev/clipboard也适用于Msys / MinGW bash shell
Mihai Rotaru 2011年

71
请注意,xclip -selection c在大多数应用程序中,它将数据发送到与^ C,^ V一起使用的剪贴板
Klaas van Schelven 2011年

31
在更新的Windows版本上,您可以clip像这样使用:dir | clip
maep 2011年

11
令人遗憾的是,GNU / Linux没有这样的设备/dev/clipboard,并且强制安装xclip或gpm,这至少在Kubuntu中是默认缺少的(我猜在大多数其他发行版中也是如此)
Hi-Angel 2014年

282

确保您正在使用,alias xclip="xclip -selection c" 否则您不能只使用Ctrl+ v将其粘贴回另一个位置。

echo test | xclip    

Ctrl+v === test


1
没有该命令参数的情况下如何粘贴它?
约拿(Jonah)2013年

15
xclip -selection clipboard -o
doug

32
因为我经常在osx和linux之间来回切换,所以我在dotfile中有以下内容。alias pbcopy="xclip -selection c" alias pbpaste="xclip -selection clipboard -o" 希望能有所帮助。
doug

15
@ApockofFork是,不xclip添加换行符echo。尝试printf test | xclip -i -selection clipboard。(printf除非您编写,否则不会添加换行符'test\n'。)
David X

7
或使用echo -n代替printf
Christian Pietsch 2015年

182

安装

# You can install xclip using `apt-get`
apt-get install xclip

# or `pacman`
pacman -S xclip

# or `dnf`
dnf install xclip

如果您无法访问apt-getnor pacman或nor dnf,则无法在sourceforge上获得源。

设定

重击

在中~/.bash_aliases,添加:

alias setclip="xclip -selection c"
alias getclip="xclip -selection c -o"

不要忘记使用. ~/.bash_aliases或通过重新启动配置文件来加载新配置。

在中~/.config/fish/config.fish,添加:

abbr setclip "xclip -selection c"
abbr getclip "xclip -selection c -o"

不要忘记通过重启终端以应用更改来重启fish实例。

用法

您现在可以使用setclipgetclip,例如:

$ echo foo | setclip
$ getclip
foo

3
对于所有其他发行版:您可以从sourceforge.net/projects/xclip
Scz 2015年

+1最佳解决方案!在拱门中sudo pacman -S xclip。但是请注意,这.bashrc不是最好的地方。我建议最终用户阅读适当的bashrc,bash_aliases和.profile文件以及bash如何处理它们。提示:请将其放在.bash_aliases中。
eduncan911

1
谢谢@ eduncan911!:)添加了使用pacman程序包管理器的选项,并删除了.bashrc命题。我知道.bash_aliases适应性更强,但最终结果是相同的(如果存在,.bashrc仅要求提供.bash_aliases)。如果人们想要一个凌乱的系统,请让他们拥有一个。:)
tleb 2015年

@EladTabak很高兴它有所帮助。
tleb

1
@jpaugh你是正确的。最后我的.bashrc资料.bash_aliases。;)我遵循这个古老的约定,在Arch,Ubuntu / Debian,Raspberry变体,macOS / OSX和Windows Bash之间仍然保持100%兼容:stefaanlippens.net/my_bashrc_aliases_profile_and_other_stuff 使用该约定,我在所有计算机上使用完全相同的点文件我碰 很好:github.com/eduncan911/dotfiles
eduncan911

143

在macOS上,使用内置的pbcopypbpaste命令。

例如,如果您运行

cat ~/.bashrc | pbcopy

~/.bashrc文件的内容将可以通过Cmd+ v快捷键进行粘贴。



25

xsel在Debian / Ubuntu / Mint上

# append to clipboard:
cat 'the file with content' | xsel -ib

# or type in the happy face :) and ...
echo 'the happy face :) and content' | xsel -ib

# show clipboard
xsel -b

# Get more info:
man xsel

安装

sudo apt-get install xsel

echo "foo" | xclip -selection c有何不同?
莱奥波尔德·赫兹(LéoLéopoldHertz)2016年

Ask Ask Ubuntu的答案上有一些答案,但主要xselxclip在所有方面都等效,除了xclip可以按名称读取/写入文件外,但xsel如果要访问文件,则需要Shell重定向。
Colin D Bennett

xsel在脚本中运行良好,而xclip 仅在提示符下运行。不知道为什么。
NVRM

16

哇,我不敢相信这个问题有多少答案。我不能说我已经尝试了所有方法,但是我尝试了前三或前四项方法,但是它们都不适合我。对我有用的是位于用户doug所写评论之一中的答案。由于我发现它很有帮助,因此我决定在回答中重新陈述。

安装xcopy实用程序,然后在终端中输入:

复制

Thing_you_want_to_copy|xclip -selection c

myvariable=$(xclip -selection clipboard -o)

我注意到建议pbpaste和pbcopy的很多答案。如果您正在使用这些实用程序,但由于某种原因它们在您的存储库中不可用,则可以始终为xcopy命令创建别名,并将其称为pbpaste和pbcopy。

alias pbcopy="xclip -selection c" 
alias pbpaste="xclip -selection clipboard -o" 

因此,它看起来像这样:

Thing_you_want_to_copy|pbcopy
myvariable=$(pbpaste)

很好,您的别名部分与MacOS相当吻合。
MeadowMuffins

15

2018答案

使用剪贴板-cli。它可以与macOS,Windows,Linux,OpenBSD,FreeBSD和Android一起使用,而没有任何实际问题。

通过以下方式安装:

npm install -g clipboard-cli

那你可以做

echo foo | clipboard

如果你愿意,你可以别名cb通过将以下在你的.bashrc.bash_profile或者.zshrc

alias cb=clipboard


2
您确定这是一个安全的npm包裹吗?
约翰尼

3
@Stas,我希望如此,它是由最多产的节点贡献者Sindresorhus(github.com/sindresorhus)制造的。他负责Ava测试库,xo linter,Yeoman和无数其他项目。他还负责无数这样的小型图书馆,这些图书馆将他的代码集中放在互联网上几乎所有使用JS的网站上。这并不是说他不会受到影响。只是对他的回购协议的关注程度和他自己的声誉使得它比大多数随机npm回购协议的可能性要小得多。
伊万·康拉德

凉!在xclip无法正常工作的Ubuntu GNU / Linux上工作。
Kevin Buchs

14

在Linux的Windows子系统上,您可以使用clip.exe复制到剪贴板。

cat file | clip.exe

请记住使用|管道命令。而不是>命令,因为那样行不通。


11

这是一个随时可用的bash脚本,用于读取可在多个平台上使用的剪贴板。如果添加功能(例如,更多平台),请在此处编辑脚本。

#!/bin/bash
# WF 2013-10-04
# multi platform clipboard read access
# supports
#   Mac OS X
#   git shell / Cygwin (Windows)
#   Linux (e.g. Ubuntu)

#
# display an error
#
error() {
  echo "error: $1" 1>&2
  exit 1
}

#
# getClipboard
#
function getClipboard() {
 os=`uname`
      case $os in 
        # git bash  (Windows)
        MINGW32_NT-6.1)
          cat /dev/clipboard;;
        # Mac OS X
        Darwin*)
          pbpaste;;  
        # Linux 
        Linux*)
          # works only for X clipboard - a check that X is running might be due
          xclip -o;;
        *)
          error "unsupported os $os";;
      esac
}

tmp=/tmp/clipboard$$
getClipboard >$tmp
cat $tmp
# comment out for debugging
rm $tmp

恩,这实际上行得通,为什么这不是答案?
255.tar.xz

9

在Windows(Cygwin的)尝试 cat /dev/clipboardecho "foo" > /dev/clipboard在提到这个文章。


1
正如用户@maep在单独的注释中提到的那样,较新版本的Windows(我只能确认Win10)可以简单地传递到clip。我正在使用msysgit 1.9.5,这工作。
肖恩·厄克特

echo "foo" > /dev/clipboard似乎完全破坏了换行符(不是\ r \ n \ n事物,而是完全消失了)
user1529413

9

仅对于Mac:

echo "Hello World" | pbcopy
pbpaste

这些位于/usr/bin/pbcopy/usr/bin/pbpaste


8

Linux中有不同的剪贴板。X服务器有一个,窗口管理器可能有另一个,依此类推。没有标准设备。

哦,是的,在CLI上,屏幕程序也有其自己的剪贴板,其他一些应用程序如Emacsvi也是如此

在X中,您可以使用xclip

您可以检查此线程以获取其他可能的答案:http : //unix.derkeiler.com/Newsgroups/comp.unix.shell/2004-07/0919.html


2
听起来创建/ dev / clip对某人来说将是一个不错的项目。
TED

2
我完全知道多个剪贴板。这如何使我的问题难以回答?
moinudin

如果剪贴板是标准化的,这是有道理的,如果可以使用/ dev / clip1,/ dev / clip2 .. / dev / clip <n>来访问它们,则可能不会受到伤害,唯一的问题是它们是特定于用户的,并且设备是系统范围的。但是,如果您使内核设备驱动程序根据访问的UID进行屏蔽,则它应能按预期工作。

5

在Windows(Cygwin)中复制并粘贴到剪贴板:

看到:

$ clip.exe -?

CLIP
Description:
    Redirects output of command line tools to the Windows clipboard.
    This text output can then be pasted into other programs.
Parameter List:
/?                  Displays this help message.
Examples:
DIR | CLIP          Places a copy of the current directory
                        listing into the Windows clipboard.
CLIP < README.TXT   Places a copy of the text from readme.txt
                        on to the Windows clipboard.

还存在getclip(可代替Shift+ Ins!使用它)和putclip(将回声oaeuoa | putclip.exe放入剪辑)。


4

这是一个简单的Python脚本,可以满足您的需求:

#!/usr/bin/python

import sys

# Clipboard storage
clipboard_file = '/tmp/clipboard.tmp'

if(sys.stdin.isatty()): # Should write clipboard contents out to stdout
    with open(clipboard_file, 'r') as c:
        sys.stdout.write(c.read())
elif(sys.stdout.isatty()): # Should save stdin to clipboard
    with open(clipboard_file, 'w') as c:
        c.write(sys.stdin.read())

将其另存为可执行文件,保存在您路径中的某个位置(我将其保存到/usr/local/bin/clip。您可以通过管道将其保存到剪贴板...

echo "Hello World" | clip

您可以将剪贴板中的内容通过管道传输到其他程序...

clip | cowsay
 _____________
< Hello World >
 -------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

单独运行它只会输出剪贴板中的内容。


当您在一台计算机上时,此方法有效,但不允许您在计算机之间复制内容。
查尔斯·普拉格

似乎只有echo echo> tmpfile和 cat tmpfile,而不是剪贴板操作。//与@horta答案相同。
yurenchen

这似乎没有设置剪贴板变量,所以我无法将内容粘贴到其他应用程序中-这不是真正的剪贴板!
耶拿

4

我找到了一个很好的参考:https : //unix.stackexchange.com/questions/69111/

就我而言,我想将内容粘贴到剪贴板上,并查看粘贴在剪贴板上的内容,因此我还使用了tee带有文件描述符的命令:

echo "just a test" | tee >(xclip -i -selection clipboard)

>()是过程替代的一种形式。bash将每个替换为文件描述符的路径,该文件描述符在括号内连接到程序的标准输入。

tee命令会分叉您的命令,使您可以“传递其内容”,并在标准输出“ stdout”上查看结果

您还可以创建别名以在剪贴板上获取和写入,从而允许您像在MAC上的任何位置一样使用“ pbcopy”和“ pbpaste”。就我而言,当我使用zsh时,我的别名文件中包含以下内容:

(( $+commands[xclip] )) && {
    alias pbpaste='xclip -i -selection clipboard -o'
    alias pbcopy='xclip -selection clipboard'
}

(( $+command[name] )),如果安装在系统上使用命令“名”在zsh的测试,那么这两个别名是与分组{}。的&&是一个二进制,如果A然后B,因此,如果你有XCLIP那么别名将被设置。

echo "another test" | tee >(pbcopy)

要获取剪贴板内容,只需键入:

pbpaste | "any-command-you-need-here"


2

我几年前编写的一些Windows程序。它们允许您转储,推送,追加和打印剪贴板。它是这样的:

dumpclip | perl -pe "s/monkey/chimp/g;" | pushclip

它包含源代码:cmd_clip.zip


2

有几种方法。已经提到的一些方法包括(我认为)tmux,screen,vim,emacs和shell。我不知道emacs或屏幕,所以我将介绍其他三个。

Tmux

虽然不是X选择,但tmux具有可通过prefix-[(默认prefixCtrl+ B)访问的复制模式。这种模式下使用的缓冲区是tmux所独有的,这为tmux提供了很多可能性,并使其在正确的情况下比X选择更具通用性。

要退出此模式,请点击q;要进行导航,请使用vimemacs绑定(默认= vim),以便hjkl进行移动,v/V/C-v选择字符/行/块等。选择后,请单击Enter以复制并退出该模式。

要从此缓冲区粘贴,请使用prefix-]

贝壳

X11默认情况下,任何安装的似乎都附带两个程序:xclipxsel(有点像startx和和一起附带xinit)。其他大多数答案都提到了xclip,我非常喜欢xsel它的简洁性,因此我将介绍xsel

xsel(1x)

输入选项

-a,-追加

将标准输入附加到选择中。意味着-i

-f,-关注

随着标准输入的增加而追加到选择。意味着-i

-i,-输入

将标准输入读取到选择中。

输出选项

-o,-输出

将选择内容写入标准输出。

动作选项

-c,-清除

清除选择。覆盖所有输入选项。

-d,-删除

请求删除当前选择。这不仅清除选择,而且还向选择所在的程序请求删除选择的内容。覆盖所有输入选项。

选择选项

-p,--primary

对PRIMARY选择进行操作(默认)。

-s,--secondary

对SECONDARY选项进行操作。

-b,-剪贴板

在CLIPBOARD选项上进行操作。

这就是您需要了解的所有内容。p(或不执行)for PRIMARYsfor SECONDARYbfor CLIPBOARDo输出。

示例:说我想复制fooTTY 的输出并将其粘贴到网页以获取错误报告。为此,复制到TTY / X会话或从TTY / X会话复制是理想的。因此,问题就变成了如何从TTY访问剪贴板?

对于此示例,我们假设X会话正在显示:1

$ foo -v
Error: not a real TTY
details:
blah blah @ 0x0000000040abeaf4
blah blah @ 0x0000000040abeaf8
blah blah @ 0x0000000040abeafc
blah blah @ 0x0000000040abeb00
...
$ foo -v | DISPLAY=:1 xsel -b # copies it into clipboard of display :1

然后,我可以Ctrl-V像往常一样将其转换为表格。

现在说,支持站点上的某人给了我一个命令来运行以解决问题。它很复杂而且很长。

$ DISPLAY=:1 xsel -bo
sudo foo --update --clear-cache --source-list="http://foo-software.com/repository/foo/debian/ubuntu/xenial/164914519191464/sources.txt"
$ $(DISPLAY=:1 xsel -bo)
Password for braden:
UPDATING %%%%%%%%%%%%%%%%%%%%%%% 100.00%
Clearing cache...
Fetching sources...
Reticulating splines...
Watering trees...
Climbing mountains...
Looking advanced...
Done.
$ foo
Thank you for your order. A pizza should arrive at your house in the next 20 minutes. Your total is $6.99

订购比萨饼似乎可以有效地使用命令行。

...继续。

Vim

如果使用+clipboard(这很重要!请检查vim --version)进行编译,则Vim应该可以访问X PRIMARYCLIPBOARD选择。可以从*+分别访问这两个选择,并且可以像其他任何寄存器一样随意写入和读取。例如:

:%y+    ; copy/yank (y) everything (%) into the CLIPBOARD selection (+)
"+p     ; select (") the CLIPBOARD selection (+) and paste/put it
ggVG"+y ; Alternative version of the first example

但是,如果您的vim副本不直接支持对X选择的访问,那就不是世界末日了。您可以只使用xsel上一节中描述的技术。

:r ! xsel -bo ; read  (r) from the stdout of (!) `xsel -bo`
:w ! xsel -b  ; write (w) to the stdin of    (!) `xsel -b`

绑定几个键连击,您应该会很好。


绝对要记住DISPLAY=从非X环境调用X应用程序时使用。X应用程序需要DISPLAY环境变量来确定正在与之通信的服务器(或者只有一台服务器处理多个会话?)。例如,尝试从TTY中尝试DISPLAY=:1 firefox(或使用任何您的显示ID;我的恰好是:1)。
布雷登·贝斯特

对我来说,在我的环境中的选择是:%y+在VIM中。
HankCa's

2

从这个线程,有不需要安装任何一个选项gclip/ xclip/ xsel第三方软件。

一个perl脚本(因为通常总是安装perl)

use Win32::Clipboard;
print Win32::Clipboard::GetText();

我将如何使用它?将脚本保存到PATH中并通过管道传递给它吗?我正在尝试编写dropbox cli包装器来复制共享链接,所以我只需要它来处理文本。
耶拿


2

pbcopy是在OSX中内置的:

复制.bash_profile的内容:

cat ~/.bash_profile | pbcopy

1

在macOS中,使用pbpaste

例如:

更新剪贴板

pbpaste  | ruby -ne ' puts "\|" + $_.split( )[1..4].join("\|") ' | pbcopy

1

如果您像我一样,并且在没有root特权的Linux服务器上运行,并且没有任何xclipGPM,则可以通过使用临时文件来解决此问题。例如:

$ echo "Hello, World!" > ~/clip
$ echo `cat ~/clip`
Hello, World!

我看不出缺少root特权是如何造成这种情况的。
Braden Best

3
@BradenBest缺少root用户特权意味着我无法安装东西。
Horta

但是您要安装什么?X?在服务器上?除非您托管一些奇怪的X转发服务,否则我将不明白为什么要这么做。
Braden Best,

@BradenBest不确定。无论使用哪种程序或服务,我都可以执行复制粘贴。
Horta

1
好吧,如果您使用的是X selections其中的任何一个(“ clipboard”和xclip / xsel都必须暗示),则需要一个活动的X会话(因此需要一个X服务器),以便可以在第一名。要了解我的意思,请尝试DISPLAY="" xsel在本地计算机上运行。它会因错误而退出,无法找到session "",并且不会与任何X选择进行交互。这就是为什么我最初说我不知道​​root特权是如何影响的:root或没有root,您不太可能在服务器环境中找到有用的X选择。
Braden Best,




0

尽管> 1年后,但我有一个稍微不同的解决方案。希望这对某人有用。

昨天我遇到了一个问题:“如何在不同的用户会话之间共享剪贴板?” 。实际上,在使用ctrlaltF7- 切换会话时ctrlaltF8,您无法粘贴复制的内容。

我根据命名管道提出了以下快速而又肮脏的解决方案。它肯定是非常裸露和原始的,但是我发现它可以正常工作:

user1@host:~$ mkfifo /tmp/sharedClip

然后在发送终端

user1@host:~$ cat > /tmp/sharedClip

最后,在接收终端中:

user2@host:~$ cat /tmp/sharedClip

现在,您在第一个终端中键入或粘贴任何内容,然后(单击return),该内容将立即显示在接收终端中,您可以在该终端中从任意位置再次复制/粘贴。

当然,这不仅仅严格地从user1的剪贴板中获取内容以使其在user2的剪贴板中可用,而且还需要另外一对粘贴和复制单击。


似乎并不奇怪。两个不同的X服务器=两个不同的选择集。但是,您可以设置一个通过接受输入/输出的脚本xsel/xclip。例如,一端侦听是否有任何选择更改,然后自动将其通过管道传递(通过命名的FIFO)到另一脚本,该脚本正在侦听一个或多个管道,然后将其插入到自己的X选择中。因此,复制文本将自动导致相同的文本出现在另一个X会话的选择中。而且不要忘记$DISPLAY
Braden Best,

0

红宝石oneliner启发了我尝试使用python。

假设我们想要一个命令,该命令使剪贴板中的任何内容缩进4个空格。非常适合在stackoverflow上共享代码片段。

$ pbpaste | python -c "import sys
 for line in sys.stdin:
   print(f'    {line}')" | pbcopy

那不是错字。Python需要换行符来进行for循环。我们想要一次更改行数,以避免在内存中建立额外的数组。

如果您不介意构建额外的数组,请尝试:

$ pbpaste | python -c "import sys; print(''.join([f'    {l}' for l in sys.stdin]))" | pbcopy

但是老实说,awk比python更好。我在~/.bashrc文件中定义了这个别名

alias indent="pbpaste | awk '{print \"    \"\$0}' | pbcopy"

现在,当我运行indent剪贴板中的任何内容时都会缩进。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.