Як редагувати поточну команду оболонки, не виконуючи її?


13

Здається, є досить багато інформації про те, як редагувати та виконувати команду за допомогою свого редактора за допомогою "edit-and-Execute-command (Cx Ce)", але те, що я хотів би досягти, це взяти поточну команду shell, застосувати певну фільтрацію (за допомогою сценарію), а потім повернути її для запиту на подальше затвердження / зміни вручну перед виконанням. Це можливо з басом?


Це не правильна відповідь на питання, але спробуйте використовувати термінал ZSH замість рідного Bash. Він має автоматичне завершення, тому не виконуйте команди відразу. Я особисто спробував цей конкретний сценарій, і він завжди вимагає від мене натиснути клавішу Enter, коли я роблю edit-and-execute-command.
Praveen Premaratne

1
Ярлик, який працює для мене, є Escape+ V, але він все одно буде виконувати команду. Що стосується способу вирішення, я б додав echoспереду, щоб виконати його, надрукувавши команду на консоль для огляду.
kenorb

2
ви можете, будь ласка, зробити конкретний приклад? Я не розумію, "застосувати певну фільтрацію (за допомогою сценарію), а потім повернути її в запит".
Кент

3
@PraveenPremaratne: zsh не термінал , це оболонка .
Аркадіуш Драбчик

Відповіді:


7

Останнє оновлення на моєму досвіді

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

Наприклад, дуже часто я виявляю, що в буфері закінчується декілька рядків, де я хочу виконати лише той, на якому курсор; в цьому випадку я можу використовувати 0"+y$dd:%d<CR>замість 0"+y$dd.

І це лише один із можливих сценаріїв.

Остаточна відповідь для тих, хто подобається vim

Оригінальна відповідь

Мені часто потрібно робити те саме, і я роблю це наступним чином. (Я зазвичай використовую set -o viв 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, де randomє 6-символьним буквено-цифровим випадковим рядком.

Це дає простір для багатьох можливостей, якщо ви використовуєте vimв якості редактора, так як ви можете визначити деяке відображення у вашому .vimrcдля виконання всієї послідовності Escape0"+y$dd:wq. Наприклад, одна команда, яку ви рідко використовуєте під час редагування командного рядка Leaderd; тому ви можете помістити наступний mapping у свій .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. Тоді, коли ви виходите з програми "Вихід", команда буде неефективною, і вам доведеться лише натиснути arrow up(або k, якщо ви використовуєте set -o vi), видалити #та підтвердити.

Зауважте, що ця стратегія додає лише кілька натискань клавіш, тому вона може бути досить ефективною, залежно від рівня набору тексту.


1

Ці деталі можуть вас зблизити:

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

б) захопити поточний рядок з історії, використовуючи !#

замініть дату будь-яким сценарієм.

в) редагувати вручну

г) при необхідності якось пов'язати, в !!:pякому друкується нова команда в командному рядку, але не виконується, тим самим дозволяючи вам вручну редагувати її.

д) використовуючи ctrl-J, подайте відредаговану команду, а не новий рядок

або вони не можуть ....


1

У баші є можливість змінити команду з історії, не виконуючи її. Я не впевнений, що можна використовувати скрипт для цього, здається, це не ймовірно. Хоча ви можете вносити зміни за допомогою модифікаторів історії.

  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

Я хотів би вказати на рамку композиції для 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

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.