Bash-скрипт для копирования в буфер обмена

Моя цель — написать псевдоним для копирования текущей команды и ее вывода в буфер обмена, например:

ls | myclip

В результате в буфере обмена должно появиться следующее:

$ ls
Desktop Documents Downloads

Это возможно? До сих пор я пробовал:

myclip() {
    command = "$@"
    output=$($@)
    echo -e "$command\n$output" | xclip -selection clipboard
}

Однако это не работает.

Редактировать: Кажется, это в некоторой степени работает, однако для меня это неправильно обрабатывает разрывы строк в выводе:

copyclip(){
    cmd=$(history 1 | sed 's/^ *[0-9]* *//' | sed 's/|.*//');
    output=$(cat);
    echo "\$ "$cmd$'\n'$output | xclip -sel clipboard;
    echo $output;
}

Если кто-нибудь знает, как решить проблему с разрывом строки, было бы здорово!

У вас нет alias в опубликованном вами коде. Кстати, прочти man xclip. Он описывает, как стандартный ввод помещается в буфер обмена.

user1934428 05.04.2024 09:20

Было бы здорово, если бы вывод команды копировался в буфер обмена и отображался на терминале.

beautifulsouper 05.04.2024 09:46

Нет. Я хочу, чтобы это можно было использовать так, как я описал.

beautifulsouper 05.04.2024 12:39

Вы хотите, чтобы $ был добавлен к тексту в буфере обмена, или вы хотите расширение PS1?

William Pursell 05.04.2024 13:59

Я хочу, чтобы $ был добавлен в начале.

beautifulsouper 05.04.2024 14:00

Исправить разрывы строк можно так же просто, как указать «$output». например echo "$output" в функции copyclip. Если установлен HISTTIMEFORMAT (а HISTTIMEFORMAT должен быть установлен всегда, поскольку файл истории без временных меток бесполезен!), вам нужно будет настроить sed при фильтрации вывода history.

William Pursell 05.04.2024 14:07

Функция хрупкая, но она должна работать, если просто сделать printf "$ %s\n%s" "$cmd" "$output" | xclip ...

William Pursell 05.04.2024 14:10

Насколько я вижу, в вашем вопросе не упоминается, что вывод также должен отображаться в терминале. Возможно, вы сможете это прояснить. Однако более сложная проблема заключается в том, что вы сказали, что хотите, чтобы сама команда находилась в буфере обмена. Вы имеете в виду здесь «команду до расширения» или «после расширения»? Возможно, вы могли бы отредактировать свой вопрос, добавив пример: ls -A ~. Что именно вы хотели бы видеть в буфере обмена потом?

user1934428 06.04.2024 11:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
8
211
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Поместите следующий псевдоним в .bashrc:

alias myclip='xclip -i -selection clipboard'

Затем откройте новый терминал и введите следующий пример команды:

ls | myclip

Вот и все!

Спасибо, но это не копирует исходную команду в буфер обмена.

beautifulsouper 05.04.2024 09:43

(этот ответ должен был быть комментарием, но мне пока не разрешено его писать)

Судя по моим тестам, проблема в том, что скрипт ведет себя так, как будто "$@" содержит всю команду перед трубой, но это не работает таким образом, и выполнить эту задачу чисто и надежно может быть сложно (см. этот пост, опубликованный более 5 лет назад) решение, которое я нашел, уродливо, и я боюсь, что оно далеко от надежности

функция

m() { (  echo "$( history 1 | head -n 1 | cut -c 26- | cut -d\| -f 1 )" ; cat  ) | xclip -i  ; }

(он работает путем повторения команды из истории и последующего добавления стандартного ввода в стандартный вывод) вот тест в bash (запуск по ssh с помощью putty)

/tmp $
/tmp $ m() { (  echo "$( history 1 | head -n 1 | cut -c 26- | cut -d\| -f 1 )" ; cat  ) | xclip -i  ; }
/tmp $
/tmp $ ls -1 foo
bar
baz
/tmp $
/tmp $
/tmp $ ls -1 foo |m
/tmp $ cat >/dev/null
this is the content of the clipboard when I paste it with shift-insert:
ls -1 foo
bar
baz
/tmp $

Спасибо, но это не работает для меня. Я получаю: $ m() { ( echo "$( история 1 | head -n 1 | Cut -c 26- | Cut -d\| -f 1 )" ; cat ) | хклип -я; } $ лс | m Буфер обмена: m() { ( echo "$(история 1 | head -n 1 | Cut -c 26- | Cut -d\| -f 1 )" ; cat ) | хклип -я; }

beautifulsouper 05.04.2024 10:53

вы правы: для того, чтобы мое решение также работало с терминала в текстовом редакторе или других приложениях X11, мне нужно было указать флаги xclip, как в вашем исходном скрипте, то есть: m() { ( echo "$( history 1 | head -n 1 | cut -c 26- | cut -d\| -f 1 )" ; cat ) | xclip -selection clipboard ; }

sigmud 05.04.2024 12:29

Тоже не работает. Не хватает команды.

beautifulsouper 05.04.2024 12:38

@beautifulsouper, не могли бы вы предоставить дополнительную информацию о вашей среде (дистрибутив unix/linux, версия оболочки, терминал, приложение с графическим интерфейсом, в которое вставляется скопированный текст)?

sigmud 05.04.2024 15:33

Определите функцию myclip и запустите команду bind:

myclip(){
    (( READLINE_POINT>0 )) || return 0
    local cmd = "$READLINE_LINE"
    READLINE_LINE=''
    printf "%s\n%s\n" "$cmd" "$($cmd)" | xclip -i -selection clipboard
}   

bind -x '"\e[15~":"myclip"'

Теперь введите date, а затем F5. Результат будет в буфере обмена.

Вы можете поместить это в .bashrc:

alias myclip = "xsel -b"

и напишите этот пример команды:

ls | myclip

clipsmth() { (echo "\$ $@"; $@;) | xclip -sel clipboard; } и назови это лайком clipsmth ls -l, если хочешь

Ответ принят как подходящий

Рабочая версия:

copyclip(){
    cmd=$(history 1 | sed 's/^ *[0-9]* *//' | sed 's/|.*//');
    output=$(cat);
    echo "\$ "$cmd$'\n'"$output" | xclip -sel clipboard;
    echo "$output";
}

Другие вопросы по теме