Скопировать текущую команду в bash в буфер обмена - программирование

Скопировать текущую команду в bash в буфер обмена

Я бы хотел, чтобы быстрая командная последовательность клавиш скопировала текущую команду в приглашении bash в буфер обмена.

Чтобы, например, скопировать последнюю команду bash в буфер обмена, я бы нажал + [some command sequence], чтобы скопировать ее. Или, например, для поиска команды в bash hisory, я бы использовал ctrl + r, search, отобразив ее в командной строке, а затем [some command sequence], чтобы скопировать ее и т.д.

Мое текущее решение использует bash pipe: Pipe to/from the clipboard

Итак, чтобы скопировать предыдущую команду в буфер обмена:

echo "!!" | pbcopy

Это не слишком страшно, но что делать, если команда для копирования не является последней командой и т.д.

Какой правильный способ достичь того, чего я пытаюсь достичь здесь?

4b9b3361

Ответ 1

Взяв сообщение @Lauri для вдохновения, вот решение, использующее команду bind:

bind '"\C-]":"\C-e\C-u pbcopy <<"EOF"\n\C-y\nEOF\n"'

ctrl-] затем скопирует все текущее приглашение bash в буфер обмена.

Чтобы сделать это постоянным, вы можете добавить команду привязки, как указано выше, в ваш ~/.bashrc, или вы можете отключить внешние кавычки и удалить часть вызова "bind" и добавить результат к вашему ~/.inputrc.

Пользователям без OS-X придется поменять pbcopy с помощью соответствующей команды, возможно, xclip.

Вместо метода эхо-сигнала использовался метод цитирования heredoc, поэтому сохраняются как одиночные, так и двойные кавычки в команде в приглашении bash. С помощью этого метода, например, я смог нажать ctrl-], скопировать фактическую команду связывания из приглашения на терминал и вставить ее здесь в ответ. Таким образом, метод heredoc обрабатывает все специальные символы в команде bind здесь.

Ответ 2

Вы можете использовать READLINE_LINE с bind -x в bash 4:

copyline() { printf %s "$READLINE_LINE"|pbcopy; }
bind -x '"\C-xc":copyline'

Вы можете установить bash 4 и сделать его оболочкой входа по умолчанию, запустив brew install bash;echo /usr/local/bin/bash|sudo tee -a /etc/shells;chsh -s /usr/local/bin/bash.

Я также использую эту функцию для копирования последней команды:

cl() { history -p '!!'|tr -d \\n|pbcopy; }

Ответ 3

Я потратил приличное количество времени на сегодня, написав простую реализацию zsh для macOS; используется следующее:

example command:          git commit -m "Changed a few things"
command that copies:      c git commit -m "Changed a few things"

# The second command does not actually execute the command, it just copies it. 

# Using zsh, this should reduce the whole process to about 3 keystrokes:
#
# 1) CTRL + A (to go to the beginning of the line) 
# 2) 'c' + ' '
# 3) ENTER

preexec() - это функция zsh hook, которая вызывается справа, когда вы нажимаете клавишу ввода, но перед выполнением команды.

Так как zsh разделяет аргументы определенных символов типа '"', мы хотим использовать preexec(), который позволяет вам получить доступ к необработанной исходной команде.

Псевдокод выглядит следующим образом:

1) Убедитесь, что команда 'c ' в начале

2) Если это так, скопируйте всю команду char на char в временную переменную

3) Проведите переменную temp в pbcopy, буфер копирования macOS

Реальный код:

c() {} # you'll want this so that you don't get a command unrecognized error

preexec() {
  tmp="";
  if [ "${1:0:1}" = "c" ] && [ "${1:1:1}" = " " ] && [ "${1:2:1}" != " " ]; then                                  
    for (( i=2; i<${#1}; i++ )); do
      tmp="${tmp}${1:$i:1}";  
    done
    echo "$tmp" | pbcopy;
  fi
}

Вперед и придерживайтесь двух вышеупомянутых функций в вашем файле .zshrc или где угодно (я поместил мой файл в мой каталог .oh-my-zsh/custom).

Если у кого-то есть более элегантное решение, PLZ говорить. Что угодно, чтобы избежать использования мыши.

Ответ 4

Если в вашей системе установлен xsel, вы можете добавить это в .inputrc:

C-]: '\C-e\C-ucat <<EOF | tr -d "\\n" | xsel -ib\n\C-y\nEOF\n'

В качестве альтернативы, если установлен xclip, вы можете добавить это:

C-]: '\C-e\C-ucat <<EOF | tr -d "\\n" | xclip -se c\n\C-y\nEOF\n'

Примечание: Используемый код из ответа @Clayton.