Как мне отредактировать текущую команду оболочки, не выполняя ее?

13

Кажется, есть довольно много информации о том, как отредактировать и выполнить команду, используя ваш редактор, используя «edit-and-execute-command (Cx Ce)», но чего я хотел бы добиться, так это взять текущую команду оболочки, apply определенную фильтрацию (используя сценарий) и затем верните ее, чтобы запросить дальнейшее утверждение / ручные изменения перед выполнением. Это возможно с Bash?

Петр Мазурек
источник
Это не правильный ответ на вопрос, но попробуйте использовать терминал ZSH вместо собственного Bash. Он имеет автозаполнение, поэтому не выполняйте команды сразу. Я лично пробовал этот конкретный сценарий, и мне всегда нужно нажимать клавишу ввода всякий раз, когда я это делаю edit-and-execute-command.
Правин Премаратне
1
Ярлык, который работает для меня, Escape+ V, но он все равно будет выполнять команду. Что касается обходного пути, я бы добавил echoспереди, чтобы выполнить его, напечатав команду на консоль для просмотра.
Кенорб
2
Можете ли вы привести конкретный пример? Я не понимаю, «применить определенную фильтрацию (используя скрипт), а затем вернуть его в подсказку».
Кент
3
@PraveenPremaratne: Zsh не терминал , это оболочка .
Аркадиуш Драбчик

Ответы:

7

Последнее обновление на моем опыте

Часть 0"+y$ddв следующем отображении - это действительно то, о чем вы должны тщательно подумать и адаптировать ее к своему вкусу / рабочему процессу / опыту.

Например, очень часто я сталкивался с несколькими строками в буфере, где я хочу выполнить только ту, на которой находится курсор; в этом случае я могу использовать 0"+y$dd:%d<CR>вместо 0"+y$dd.

И это только один из возможных сценариев.

Окончательный ответ для тех, кто любит vim

Оригинальный ответ

Мне часто нужно делать то же самое, и я делаю это следующим образом. (Я обычно использую set -o viin bash, поэтому пункты 1 и 2 в следующем отличаются, если вы используете set -o emacs, по умолчанию; в зависимости от вашего вопроса, похоже, что точки 1 и 2 объединены в Ctrl+ с xпоследующим Ctrl+ e, что сложнее набрать, imho .)

  1. нажмите, Escapeчтобы быть в нормальном режиме,
  2. нажмите, vчтобы войти в редактор для редактирования команды,
  3. отредактируйте команду, как мне нравится,

(Здесь вы задаете вопрос.)

  1. ударить Escape0"+y$dd:wq,
    • Примечание: 0"+y$не просто "+yy, так как последний также скопирует символ новой строки, и это приведет к выполнению команды после ее вставки в командную строку,
  2. вставить буфер обмена в командной строке
    • как это сделать зависит от используемого вами терминала; Я ударил Ctrl+ Alt+ vв URxvt.
  3. перейти к утверждению / ручному редактированию.

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

Обновить

Поскольку мои EDITORVISUAL) равны vim, когда я редактирую команду, я редактирую ее в vim.

В этом отношении я заметил, что буфер имеет имя /tmp/bash-fc.random, где random6-символьная буквенно-цифровая случайная строка.

Это дает пространство множеству возможностей, если вы используете их в vimкачестве редактора, так как вы можете определить некоторое отображение в вашем .vimrcфайле для выполнения всей последовательности Escape0"+y$dd:wq. Например, одна команда , которую вы редко используют при редактировании командной строки Leaderd; поэтому вы можете поместить следующий mapпинг в ваш .vimrcфайл

au BufEnter /tmp/bash-fc.* nn <Leader>d 0"+y$dd:wq<CR>

так что шаг 4 в приведенном выше рецепте становится

  1. ударил EscapeLeaderd
Энрико Мария Де Анжелис
источник
Для меня это лучший способ редактировать команды
A.Villegas
2

Это невозможно сделать в Bash / readline, но это возможно в zsh с помощью edit-command-lineкоманды:

darkstar% autoload edit-command-line; zle -N edit-command-line
darkstar% bindkey "^X^E" edit-command-line

Теперь нажмите Control- x Control- eчтобы открыть редактор, отредактировать строку, выйти из редактора - вы увидите обновленную командную строку, но она не будет выполнена автоматически.

Аркадиуш Драбчик
источник
1

Теперь, когда я думаю об этом, возможно, вариант того, что @kenorb предложил в комментарии, - лучший обходной путь (поскольку кажется, что никакого решения не существует), если мы хотим придерживаться bash.

Что вы можете сделать, это добавить #символ (комментарий в bash) к команде, а не echo. Затем, когда вы выйдете из программы Exitor, команда будет неэффективна, и вам останется только нажать arrow up(или k, если вы используете set -o vi), удалить #и подтверждение.

Обратите внимание, что эта стратегия добавляет всего несколько нажатий клавиш, поэтому она может быть довольно эффективной, в зависимости от вашего уровня набора текста.

Энрико Мария Де Анжелис
источник
1

Эти кусочки могут приблизить вас:

а) заменить нормальную привязку для новой строки (ctrl-M) bind -x '"\C-M":date"

б) взять текущую строку из истории, используя !#

замените дату любым сценарием, который вы хотите.

в) редактировать вручную

d) если необходимо, каким-то образом связать, !!:pкоторый печатает новую команду в командной строке, но не выполняет ее, что позволяет вам вручную редактировать ее.

д) используя Ctrl-J отправьте отредактированную команду вместо новой строки

или они могут не ....

ShpielMeister
источник
1

В bash есть возможность изменить команду из истории, не выполняя ее. Я не уверен, что возможно использовать сценарий для этого, кажется маловероятным. Хотя вы можете вносить изменения, используя модификаторы истории.

  1. Включите опцию Histverify, чтобы предотвратить выполнение измененной команды
  2. Используйте цепочку модификаторов, чтобы изменить последнюю команду
  3. Используйте "!!" поместить ваш результат в командную строку для окончательного редактирования

Вот как это выглядит:

$ shopt -s histverify
$ ls *.sh
script1.sh  script2.sh  script3.sh  script-return.sh
$ !!:s/*/script1/:p
ls script1.sh
$ !!:s/1/2/:p
ls script2.sh
$ !!
$ ls script2.sh
script2.sh
Максим Норин
источник
1

Я хотел бы указать вам на структуру Composure для Bash (я не связан с ней): https://github.com/erichs/composure

Это обеспечивает draftи reviseфункции, которые звучат так, как будто они могут помочь с тем, что вы пытаетесь сделать. Вот (длинная) цитата из файла readme проекта:

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

Сначала набросайте, потом задайте вопросы

После того, как вы создали свою жемчужину команды, не выбрасывайте ее! Используйте draft ()и дайте ему хорошее имя. Это сохраняет вашу последнюю команду как функцию, которую вы можете использовать позже. Думайте об этом как черновик.

  $ cat servers.txt
  bashful: up
  doc: down

  up-arrow

  $ cat servers.txt | grep down
  doc: down

  $ draft finddown

  $ finddown | mail -s "down server(s)" admin@here.com

Пересмотреть, пересмотреть, пересмотреть!

Теперь, когда у вас есть минимальная функция оболочки, вы можете улучшить ее с помощью рефакторинга и ревизии. Используйте revise ()команду для пересмотра вашей функции оболочки в вашем любимом редакторе.

  • обобщать функции с входными параметрами
  • добавить или удалить функциональность
  • добавить поддерживающие метаданные для документации

    $ revise finddown
    finddown ()
    {
      about finds servers marked 'down' in text file
      group admin
      cat $1 | grep down
    }
    
    $ finddown servers.txt
    doc: down
nwinkler
источник
0

Это не представляется возможным с помощью сочетания клавиш, по крайней мере:

$ bind -P | grep -e command -e edit
complete-command can be found on "\e!".
edit-and-execute-command can be found on "\C-x\C-e".
emacs-editing-mode is not bound to any keys
possible-command-completions can be found on "\C-x!".
vi-editing-mode is not bound to any keys
l0b0
источник