Поместите текст в буфер командной строки bash

9

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

Я с нетерпением жду чего-то похожего read -iна команды.

-i text Если readline используется для чтения строки, текст помещается в буфер редактирования перед началом редактирования.

Изменить : Под программно я подразумеваю, что хочу написать это в скрипте , запустить скрипт и подготовить буфер команд или изменить историю команд (как предлагалось в некоторых вопросах).

Gioele
источник
IIRC screenможет сделать это для вас.
Strugee
1
Этот ответ на СУ .
Камиль Мачоровский

Ответы:

6

Я нашел хакерский способ сделать это на странице примеров fzf . Это работает с bash 4.3 и perl 5.18:

writecmd () { 
  perl -e 'ioctl STDOUT, 0x5412, $_ for split //, do{ chomp($_ = <>); $_ }' ; 
}

# Example usage
echo 'my test cmd' | writecmd

Он выводит команду на стандартный вывод, но также копирует ее в буфер команд. На связанной странице также есть пример, если вы хотите выполнить команду напрямую.

trhodes
источник
Этот ответ наиболее близок к тому, о чем просил ФП.
Реза.сафия
Немного другой синтаксис в этом ответе , &TIOCSTIнемного лучше, чем 0x5412тоже. Стоит отметить, что это звучит так, как будто некоторые платформы (например, OpenBSD ) отключают TIOCSTI. Я думаю, это означает, что и этот подход, и zsh print -zне сработают.
dimo414
4

Если это для функции, которую вы собираетесь использовать в привязке readline, bind -xто вы можете изменить READLINE_LINE. ( Пример )

Вне привязки readline, вы можете вставить поддельную команду в историю с помощью history -s.

Жиль "ТАК - перестань быть злым"
источник
Проблема в том, что если я делаю это history -s 'foo'в скрипте, история запущенной оболочки не изменяется вообще
gioele
@gioele Вы должны запустить его из оболочки (например, из скрипта, который вы загружаете source). Вы не можете ничего сделать из отдельного процесса.
Жиль "ТАК - перестань быть злым"
2

Ответ Жиля правильный, но не полностью удовлетворительный. Когда я читаю этот вопрос, ОП хочет «отобрать» следующую строку ввода. В моем случае я хотел прочитать текущую позицию терминала в моей функции PROMPT_COMMAND. Это работает, но использует тот же буфер чтения, что и первичная оболочка, и поэтому любой пользовательский ввод отбрасывается тем фактом, что я сделал встроенный вызов read для функции. Поэтому я хотел прочитать пользовательский ввод отдельно, выполнить чтение с моего терминала, а затем поместить ввод для чтения обратно в буфер ввода, что является первоначальным вопросом. Обратите внимание, что это действительно в том же процессе, поэтому теоретически это должно быть возможно.

Насколько я вижу (на моем bash 4.2) нет функции, чтобы программно что-то помещать в стек ввода. В zsh используется 'print -z'.

Ответ таков: в bash это невозможно, для этого нужно использовать zsh.

Стейн Хооп
источник
0

Как альтернатива history -s 'foo'попробовать:

echo 'foo' >> ~/.bash_history
history -n

# or
history -s 'foo'
history -a
history -n
Строймеханизация
источник