ChatGPT解决这个技术问题 Extra ChatGPT

在 Bash 脚本中通过管道传入/传出剪贴板

是否可以在 Bash 中与剪贴板进行管道传输?

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

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

cat /dev/clip        # Dump the contents of the clipboard
cat foo > /dev/clip  # Dump the contents of "foo" into the clipboard
我一直在 vim 中使用 :%y+,这是 vim 所说的“将所有行拖入(复制)到 '+' 寄存器(X PRIMARY 剪贴板)”。如果您想具体一点,可以将 % 替换为范围。但是有三个警告: 1. 现在,您必须先将任何文本保存到文件中,然后才能复制它。这与答案中提到的 xclip 命令形成对比。 2. 如果你还不知道如何 vim,这可能会很乏味。 3.只有在编译vim时启用了某个功能才可以这样做。如果您安装 GVim,它应该在 vim 的 GUI 和终端实例中默认启用。
@BradenBest 你应该把它作为答案。我在 NIX 环境中,无法安装 xclip。你的回答就像一个魅力。
@HankCa 好的,我发布了 an answer。告诉我你的想法。
@BradenBest 这是一个非常全面的答案。我只是喜欢 :%y+ 一个,但是好的,你已经涵盖了所有的基础!好一个。
另一种选择:使用一点 perl 脚本:不需要安装。请参阅my answer below

P
Peter Mortensen

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

在 X 的情况下,有 xclip(和其他)。 xclip -selection c 将数据发送到剪贴板,在大多数应用程序中与 Ctrl + CCtrl + V 配合使用.

如果您使用的是 Mac OS X,则有 pbcopy。例如,cat example.txt | pbcopy

如果您处于 Linux 终端模式(没有 X),请查看具有剪贴板的 gpmScreen。尝试屏幕命令 readreg

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


赛格温:/dev/clipboard
在 Windows 上,/dev/clipboard 也适用于 Msys/MinGW bash shell
请注意,在大多数应用程序中,xclip -selection c 会将数据发送到与 ^C、^V 一起使用的剪贴板
在较新的 Windows 版本上,您可以像这样使用 clipdir | clip
令人遗憾的是 GNU/Linux 没有像 /dev/clipboard 这样的设备,并且强制安装 xclip 或 gpm 至少在 Kubuntu 中默认缺少 (我猜在大多数其他发行版中也是如此) .
r
recvfrom

确保您使用的是 alias xclip="xclip -selection c",否则您将无法使用 Ctrl+v 进行粘贴。

示例:运行 echo -n test | xclip 后,Ctrl+v 将粘贴 test


如果没有该命令参数,将如何粘贴它?
xclip -selection clipboard -o
因为我经常在 osx 和 linux 之间来回走动,所以我的 dotfiles 中有以下内容。 alias pbcopy="xclip -selection c" alias pbpaste="xclip -selection clipboard -o" 希望对您有所帮助。
@ApockofFork,xclip 没有添加换行符,echo 是。试试 printf test | xclip -i -selection clipboard。 (除非您写 'test\n',否则 printf 不会添加换行符。)
或使用 echo -n 而不是 printf
t
tleb

安装

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

# or `pacman`
pacman -S xclip

# or `dnf`
dnf install xclip

如果您无权访问 apt-getpacmandnf,则可以在 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"

不要忘记通过重新启动终端来重新启动您的鱼实例以应用更改。

用法

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

$ echo foo | setclip
$ getclip
foo

对于所有其他发行版:您可以从 sourceforge.net/projects/xclip 下载源代码
+1 最佳解决方案!在 Arch 中,sudo pacman -S xclip。但请注意,.bashrc 不是最佳位置。我建议最终用户阅读正确的 bashrc、bash_aliases 和 .profile 文件以及 bash 如何处理每个文件。提示:将其放在 .bash_aliases 中。
谢谢@eduncan911! :) 添加了使用 pacman 包管理器的选项并删除了 .bashrc 提议。我知道 .bash_aliases 更适合,但最终结果是相同的(.bashrc 只需要 .bash_aliases 如果它存在)。如果人们想要一个凌乱的系统,就让他们拥有一个。 :)
@eduncan911 我在 bash 手册中找不到提及 .bash_aliases。我相信这一定是对 .bashrc 的发行版特定修改。 (我见过特定于发行版的 .bashrc,如果存在则导入 .bash_profile。)基于此,我会说 .bash_aliases 不是通用约定,而是对拥有它的人来说方便的简写。
@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
B
Boris Verkhovskiy

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

例如,如果您运行

cat ~/.bashrc | pbcopy

~/.bashrc 文件的内容可通过 Cmd + V 快捷方式进行粘贴。

要将当前剪贴板保存到文件,请将输出 pbpaste 重定向到文件:

pbpaste > my_clipboard.txt

pbcopy < my_clipboard.txt 也可用于从文件复制内容。
E
Evan Conrad

2018年答案

使用 clipboard-cli。它适用于 macOS、Windows、Linux、OpenBSD、FreeBSD 和 Android,没有任何实际问题。

安装它:

npm install -g clipboard-cli

然后你可以这样做:

echo foo | clipboard 

如果需要,您可以通过在 .bashrc.bash_profile.zshrc 中添加以下内容来为 cb 设置别名:

alias cb=clipboard

您确定它是一个安全的 npm 包吗?
@Stas,我希望如此,它是由最多产的节点贡献者 Sindresorhus (github.com/sindresorhus) 制作的。他负责 Ava 测试库、xo linter、Yeoman 和无数其他项目。他还负责无数像这样的小型库,这些库将他的代码放在互联网上几乎每个使用 JS 的网站上。这并不是说他不能妥协。只是对他的回购的关注数量和他自己的声誉使得它比大多数随机 npm 回购的可能性要小得多。
凉爽的!在 xclip 不工作的 Ubuntu GNU/Linux 上工作。
虽然它在 WSL 中不起作用——windows 中的 linux。
周围的JS太多了
S
SebMa

Debian/Ubuntu/Mint 上的 xsel

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

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

# show clipboard
xsel -ob

# Get more info:
man xsel

安装

sudo apt-get install xsel

这与 echo "foo" | xclip -selection c 有何不同?
关于这个 Ask Ubuntu answer 有一些答案,但主要是 xselxclip 在各方面都是等效的,除了 xclip 可以按名称读取/写入文件,但如果您想访问 xsel,则需要 shell 重定向文件。
xsel 在脚本中运行良好,而 xclip 仅在提示符下运行。不知道为什么。
也可用于基于 Redhat 的系统。在像 xclip 这样的脚本中使用时不会奇怪地阻塞。
Z
Zombo

尝试

xclip

xclip - command line interface to X selections (clipboard) 

man


P
Peter Mortensen

Windows Subsystem for Linux (WSL) 上,您可以使用 clip.exe 复制到剪贴板:

cat file | clip.exe

请记住使用 | 管道命令。而不是 > 命令,因为这不起作用。


这也适用于 gitbash。
P
Peter Mortensen

安装 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)

一个答案位于一个名为 doug 的用户为我写的评论中。因为我发现它很有帮助,所以我决定在答案中重申。


太好了,您的别名部分很好地对应了 MacOS。
P
Peter Mortensen

这是一个现成的 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 the 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

k
kenorb

仅适用于 Mac:

echo "Hello World" | pbcopy
pbpaste

它们位于 /usr/bin/pbcopy/usr/bin/pbpaste


N
Norman H

在 Windows(使用 Cygwin)上尝试本文中提到的 cat /dev/clipboardecho "foo" > /dev/clipboard


正如用户@maep 在另一条评论中提到的那样,较新版本的 Windows(我只能确认 Win10)可以简单地通过管道传输到 clip。我正在使用 msysgit 1.9.5,这很有效。
echo "foo" > /dev/clipboard 似乎完全破坏了换行符(不是 \r\n \n 事情,而是完全消失了)
损坏的链接修复(无法编辑):pgrs.net/2008/01/11/command-line-clipboard-access
P
Peter Mortensen

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

哦,是的,在 CLI 上,屏幕程序也有自己的剪贴板,就像 Emacsvi 等其他一些应用程序一样。

在 X 中,您可以使用 xclip

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


我完全了解多个剪贴板。这如何使我的问题更难回答?
如果剪贴板是标准化的,那将是有意义的,如果您可以使用 /dev/clip1, /dev/clip2 .. /dev/clip 来访问它们,可能不会受到伤害,唯一的问题是它们是用户特定的并且设备是系统范围的。但是,如果您制作一个根据访问 UID 进行掩码的内核设备驱动程序,它应该可以按预期工作。
P
Peter Mortensen

这是一个简单的 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 str > tmpfile` 和 cat tmpfile ,不是剪贴板操作。 //与@horta 的回答相同。
这似乎没有设置剪贴板变量,所以我无法将内容粘贴到其他应用程序中 - 它不是真正的剪贴板!
P
Peter Mortensen

我找到了一个很好的参考:How to target multiple selections with xclip

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

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

>() 是一种进程替换形式。 Bash 用括号内连接到程序标准输入的文件描述符的路径替换每个。

tee命令派生您的命令,允许您“通过管道传输其内容”并在标准输出“stdout”上查看结果。

您还可以创建别名以在剪贴板上获取和写入,让您可以像在 Mac 上一样使用“pbcopy”和“pbpaste”。就我而言,当我使用 Z shell (zsh) 时,我的别名文件中有这个:

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

shell 中的 (( $+command[name] )) 测试您的系统上是否安装了命令“name”,然后将两个别名与 {} 分组。 && 是二元 AND;如果 a 然后 b,因此如果您有 xclip,则将设置别名。

echo "another test" | tee >(pbcopy)

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

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

P
Peter Mortensen
  xsel -b

为 X Window 做这项工作,而且它大部分已经安装好了。查看 xsel 的手册页是值得的。


P
Peter Mortensen

在 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(echo oaeuoa | putclip.exe 将其放入剪辑)。


P
Peter Mortensen

pbcopy 内置在 OS X 中:

复制文件 .bash_profile 的内容:

cat ~/.bash_profile | pbcopy

P
Peter Mortensen

我刚刚在我的 KDE 环境中搜索了相同的内容。

随意使用 clipcopyclippaste

KDE:

> echo "TEST CLIP FROM TERMINAL" | clipcopy
> clippaste
TEST CLIP FROM TERMINAL

o
otto

在 Linux 中这有效:

cat filename | xclip

但是之前的答案已经涵盖了(?)。
P
Peter Mortensen

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

多路复用器

虽然不是 X 选择,但 tmux 具有可通过 prefix-[ 访问的复制模式(prefix 默认为 Ctrl + B)。用于此模式的缓冲区是 tmux 的独立和专有的,它开辟了很多可能性,并且在适当的情况下使其比 X 选择更通用。

要退出此模式,请按 Q;要导航,请使用您的 Vim 或 Emacs 绑定(默认 = Vim),因此 hjkl 用于移动,v/V/C-v 用于字符/行/块选择等。当您选择时,按 Enter复制并退出模式。

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

默认情况下,任何 X11 的安装似乎都附带两个程序:xclipxsel(有点像它同时附带 startxxinit)。大多数其他答案都提到了 xclip,我真的很喜欢 xsel 的简洁性,所以我将介绍 xsel

xsel(1x)

输入选项 \ -a, --append \ 将标准输入附加到选择中。暗示-i。 -f, --follow \ 随着标准输入的增长而追加到选择中。暗示-i。 -i, --input \ 将标准输入读入选择。输出选项 \ -o, --output \ 将选择写入标准输出。操作选项\-c、--clear\清除选择。覆盖所有输入选项。 -d, --delete \ 请求删除当前选择。这不仅清除了选择,而且还向选择所在的程序请求删除选择的内容。覆盖所有输入选项。选择选项 \ -p, --primary \ 对 PRIMARY 选择进行操作(默认)。 -s, --secondary \ 对 SECONDARY 选择进行操作。 -b, --clipboard \ 对剪贴板选择进行操作。

这就是您需要知道的全部内容。 PRIMARYp(或无),SECONDARYsCLIPBOARDb,输出为 o

示例:假设我想从 TTY 复制 foo 的输出并将其粘贴到网页以获取错误报告。为此,理想的做法是复制到 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

比萨订购似乎是对命令行的有效使用。

...继续。

维姆

如果使用 +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`

绑定几个键组合,你应该很好。


从非 X 环境调用 X 应用程序时,一定要记住使用 DISPLAY=。 X 应用程序需要 DISPLAY 环境变量来确定它们正在与哪个服务器(或者只有一个服务器处理多个会话?)。例如,从 TTY 尝试 DISPLAY=:1 firefox(或任何您的显示 ID;我的恰好是 :1)。
对我来说,我的环境中的选择是 VIM 中的 :%y+
H
Harry Moreno

Ruby oneliner 启发了我尝试使用 Python。

假设我们想要一个将剪贴板中的任何内容缩进四个空格的命令。它非常适合在 Stack Overflow 上共享片段。

$ 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 时,剪贴板中的任何内容都会缩进。


您可以只删除括号并使用生成器表达式而不是列表推导。 ''.join(f' {l}' for l in sys.stdin)——对于大多数人来说,python 将指向 MacOS 上的 python2。因此,您可能希望改为指定 python3
什么是“Ruby oneliner”?你指的是什么?另一个答案?或者是其他东西?请通过 editing (changing) your answer 回复,而不是在评论中(没有“编辑:”、“更新:”或类似内容 - 答案应该看起来好像是今天写的)。
P
Peter Mortensen

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

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

它包括源代码:cmd_clip.zip


P
Peter Mortensen

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

Perl 脚本(因为通常总是安装 Perl)

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

我将如何使用它?将脚本保存到 PATH 并通过管道输入?我正在尝试编写 Dropbox cli 包装器来复制共享链接,所以我只需要它来处理文本。
P
Peter Mortensen

Wayland 上,xcopy 似乎不起作用。请改用 wl-clipboard

例如,在 Fedora

sudo dnf install wl-clipboard

tree | wl-copy

wl-paste > file

P
Peter Mortensen

在 macOS 中,使用 pbpaste

例如:

更新剪贴板

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

I
Ilyich

一种从剪贴板粘贴到文件的方法,无需除 echo 之外的任何工具。

在要粘贴的文本中转义单引号:将所有出现的 ' 替换为 '\'' 并将结果复制到剪贴板。键入 echo -n ' 按 Shift + 插入类型 ' > filename.txt 按 Enter

基本上你正在这样做:

echo -n 'copied "text" with '\''single quotes'\'' escaped' > filename.txt

即使复制的文本有新行,它也可以工作。


M
Mahdi-Malv

对于 mac,您可以使用这个使用 pbcopypbpaste 的函数,但更简单一些:

将此添加到您的 .bashrc.zshrc

clp() {
  if [[ -z "$1" ]]
  then
    # No input - act as paste
    pbpaste;
  else
    # Input exists - act as copy
    echo "$1" | pbcopy;
  fi
}

复制使用 clp "Content" 并粘贴使用 clp


J
Jonathon Reinhart

还有xclip-copyfile


h
horta

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

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

我看不出缺乏 root 特权是如何影响这一点的。
@BradenBest 缺乏 root 权限意味着我无法安装东西。
但是你会安装什么? X?在服务器上?除非您托管一些奇怪的 X 转发服务,否则我看不出您为什么要这样做。
@BradenBest 不确定。任何程序或服务都可以让我执行复制粘贴。
好吧,如果您使用任何 X selections(“剪贴板”和任何提及 xclip/xsel 必然暗示),您需要一个活动的 X 会话(因此需要一个 X 服务器),以便您可以访问首先选择。要了解我的意思,请尝试在本地计算机上运行 DISPLAY="" xsel。它将在出错时退出,无法找到会话 "",并且不会与任何 X 选择进行交互。这就是为什么我最初说我看不到 root 权限是如何影响这一点的:root 或没有 root,您不太可能发现 X 选择在服务器环境中有用。