Запам’ятайте напівнаписану команду, поки я щось перевіряю


97

Я часто опиняюсь у такій позиції: я почав набирати довгу команду в командному рядку bash, але на півдорозі я з’ясував, що мені потрібно щось перевірити за допомогою іншої команди. Це проблема, коли я за консоллю (без X), що часто трапляється, тому що тоді я маю лише такі незадовільні способи зробити це, про що я знаю:

  • Натисніть ctrl+ alt+ F2та увійдіть на іншу віртуальну консоль, і дізнайтеся, що я хотів, а потім поверніться та продовжуйте
  • ctrl+ a, введіть echo + space+ enter, дізнайтеся, що я хотів, натискайте, поки не знайду свою команду, ctrl+ a, delx 5, ctrl+ eта продовжуйте
  • Виділіть те, що я набрав до цього часу мишею (якщо працює gpm, що це зазвичай є), натисніть ctrl+, cщоб перервати, з’ясувати, що я хотів, обережно не використовуючи мишу для виділення матеріалів, а потім натисніть середню кнопку миші на новий підказку і продовжуйте
  • Помоліться богам командного рядка, щоб напівписана команда не мала негативних наслідків, а просто провалилася, і обережно натисніть клавішу Enter, потім дізнайтеся, що я хотів, натисніть на стрілку вгору, поки я не поверну свою команду, і продовжуйте
  • Переходьте до моєї машини часу, повертайтеся назад у часі та нагадуйте собі запустити екран перед тим, як почати вводити команду, повернутися до сьогодення, натисніть ctrl+ a c, дізнайтеся, що я хотів, натисніть ctrl+ a ctrl+aта продовжуйте

Отже, що я хочу знати, чи є якийсь більш елегантний спосіб зробити це? Якась команда subshell-команда чи подібне?

Мене найбільше цікавлять методи, які не потребують будь-якої підготовки або налаштування для роботи.

Відповіді:


68

Кілька більш швидка версія Алекса Ctrl + A Ctrl+ K(яка переміщається до передньої лінії , а потім вирізає все вперед), щоб просто використовувати Ctrl+ U, який ріже назад на баш, і вся лінія (незалежно від поточного положення) на Zsh. Потім ви використовуєте Ctrl+, Yщоб знову вставити його


1
Випробовуючи це, я роблю висновок, що Ctrl + U не рухається назад і не скорочується вперед, а скоріше скорочується назад. Маючи курсор посередині команди, у командному рядку залишається все, що за ним. І все-таки на 33% покращення щодо рішення @ alex, оскільки це економить натискання клавіші.
Lauritz V. Thaulow

2
@lazyr О, цілком правильно; на zshній вирізається вся лінія, а на розрізі bashназад. Я ніколи раніше не помічав цієї різниці
Майкл Мрозек

2
О, я не знав, що Ctrl + U також ставить текст для знищення буфера. Добре знати! :)
alex

1
^U ^Kматиме такий же ефект, як, ^A ^Kале є дещо ергономічнішим та значно зручнішим під screen.
інтуїтоване

53

Зробіть ctrl-A для початку рядка, додайте хеш і натисніть return - таким чином він залишиться в історії команд як коментар, і ви можете повернутися до нього курсором вгору

EDIT: щойно помітив, що це трохи більш елегантний варіант у вашій №2;)


1
Так, і чому я цього не придумав? Дякую!
Lauritz V. Thaulow

1
Мені потрібно прочитати, перш ніж опублікувати власну відповідь. Джеймс має право.
Шон К.

4
Зауважте, що це не працюватиме cshабо zshтому, що вони не дозволяють коментувати інтерактивну оболонку. В zshнеобхідно активувати правильний варіант: setopt interactive_comments.
sam hocevar

1
@Sam Так, але ": command" має той же ефект (":" = команда null)
barrycarter

6
@barrycarter: ні, :для цієї мети слід вважати шкідливим і ніколи і ніколи не пропонуватися. Він виконає все після крапки з комою, всередині задньої панелі тощо з усіма пов'язаними з цим побічними ефектами.
sam hocevar

29

Натисніть Ctrl+A, Ctrl+Kщоб перейти до початку рядка та видалити (вбити) до кінця. Потім зробіть своє дослідження, і коли будете готові продовжувати натискання Ctrl+Y(ривок), щоб повернути збережену (вбиту) лінію назад.


3
А, тепер це більше схоже на те, що я мав на увазі. І я роблю це весь час в Emacs, мав би думати про те, щоб зробити те ж саме в командному рядку.
Лауріц В. Таулов

13

У zsh я набираю Ctrl+, Zщоб "призупинити" команду, яку я набираю, і введіть іншу команду. Після того, як я запустив цю команду (або скасував її з Ctrl+ C), призупинена команда повертається до видання (навіть запам'ятовуючи положення курсору). В якості додаткової зручності, якщо командний рядок порожній, коли я набираю Ctrl+ Z, ключ викликає bgвбудований натомість (тож подвійний Ctrl+ Zнадсилає запущену команду безпосередньо на задній план).

fancy-ctrl-z () {
  emulate -LR zsh
  if [[ $#BUFFER -eq 0 ]]; then
    bg
    zle redisplay
  else
    zle push-input
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z'          fancy-ctrl-z

Я не знаю, як зробити щось подібне в баш.

У будь-якій оболонці ви можете використовувати низькотехнологічний метод додавання а #на початку поточного рядка .


2
ваша функція є захоплюючою, але чи знаєте ви, що zshфункція для цієї вбудованої вже є ? Це називається, push-lineі все, що вам потрібно зробити, - це скористатися, bindkeyщоб дістатися до нього.
Калеб

@Caleb: Я не знаю, чому я використовую, push-inputа не push-lineтут, push-lineздається, більш підходящим (можливо, старі версії zsh тільки були push-input?). Але це не є заміною для решти функцій.
Жиль,

Наскільки я можу сказати, єдина відмінність - це той самий обов'язковий ефект для фонової роботи. Я щось пропускаю?
Калеб

1
@Caleb: Ні, я просто знаходжу комбінацію двох зручних ( push-lineмарно в порожньому рядку, а bgввімкнення Ctrl+Zкорисно лише тоді, коли я лише призупинив цей процес Ctrl+Z) і мнемонічного (я або фоновий процес або частковий командний рядок).
Жиль

3
@Caleb push-inputпризупиняє весь вхідний буфер, тоді як push-lineпризупиняє лише поточний рядок. Якщо я набираю багаторядкову команду, я хочу призупинити всю команду, так push-inputце правильна. Я вважаю його push-inputбільш корисним, ніж push-line(якщо я хочу затримати рядок у багаторядковому вхідному буфері, я можу просто перейти на початок рядка та вставити новий рядок), тому мені насправді цікаво, чому push-lineотримали замовчування прив'язку клавіш, а ні push-input.
Жиль

13

У bash просто введіть Alt+ #.

Потім, коли будете готові, натисніть, Upа потім Alt+ #.

Перший ставить a #на початок рядка, щоб перетворити його в коментар, потім приймає рядок, як ніби ви натиснули Enter.

Потім, коли ви це зробите вдруге, він бачить, що лінія вже має #на початку, тож видаляє її та приймає, знову зберігаючи Enterключ.

Якщо другий раз просто вставити інший #, тоді вам доведеться набрати Alt+ - Alt+ #.

Ви можете змусити zsh зробити те саме, поставивши

bindkey -M emacs '\e#' pound-insert

у вашому ~ / .zshrc.

Або, якщо ви використовуєте прив’язки vi, ви можете вводити #з командного режиму як bash, так і zsh.


2
Не працює для мене, друга команда означала видалення # просто додає більше # на передню частину.
Lauritz V. Thaulow

1
Чи працює перший? Яку версію bash ви використовуєте?
Мікель

3
Alt + # працює так, як ви описуєте в третьому абзаці, але не так, як у четвертому, він просто передує ще # на передній частині і приймає рядок. Я використовую bash 4.1.5 (1) -випуск на Ubuntu 10.10.
Lauritz V. Thaulow

1
О, шановний, в bash він вимагає числового аргументу, наприклад, Esc+1тоді Alt+ #для перемикання.
Мікель

Це працює, але набагато громіздкіше, ніж просто Ctrl + A Del Ctrl + E, особливо на моїй розкладці клавіатури, де Alt + # насправді Alt + Shift + 3.
Lauritz V. Thaulow

10

Однією з моїх улюблених особливостей zshє вбудована функція push-line, яка забезпечує це без будь-якого хакерства в інших відповідях тут. У мене в файлі це прив’язано до Ctrl+ так:l.zshrc

bindkey '^L' push-line

Тоді, коли я набираю якусь команду і мені потрібно швидко зробити щось інше, я можу викликати це однією клавішею і отримати пусте підказку. Після запуску іншої команди запит автоматично заповнюється тим, що я вводив раніше.

Ви навіть можете зв'язати декілька шарів цього, і команди повернуться до вас у зворотному порядку, щоб ви натиснули їх у чергу.


5
Зв'язано до Ctrl+Qта ESC qза замовчуванням (у режимі emacs).
Жиль,

Чи є щось подібне для bash?
Магнус

@Magnus: Перегляньте решту відповідей на це питання. Є рішення для баш, просто не такі елегантні, як це.
Калеб

@Caleb, я мав би бути більш конкретним, чи існує подібна комбінація однієї клавіші для bash?
Магнус

1
Це явно "правильна" відповідь, для Zsh все одно! Я просто хочу згадати push-line-or-editвіджет, який за замовчуванням не пов'язаний в жодній картці. У запиті верхнього рівня він робить те саме push-line, що і на будь-якому рівні підказок нижче, перетворює всю команду, що вводиться, у багаторядковий буфер. Дві чудові функції на одній клавіатурі! Я можу порекомендувати прив’язку push-line-or-editзамість простої push-line. Ви нічого не втрачаєте та отримуєте корисну функціональність.
wjv

5

Окрім трюку ctrl- a ctrl- k, якщо ви на екрані, просто ctrl- a dвід'єднати та повторно встановитиscreen -r

Ви також можете просто відкрити інше вікно з ctrl+a c


8
Якщо ви на екрані, просто відкрийте інше вікно Ctrl+A c.
Жиль

1
@Gilles .., якщо вам не потрібно використовувати якийсь аспект стану оболонки (змінні, функції, псевдоніми тощо).
інтуїтована

4

Альтернативний спосіб, не ідеальний, хоча Ctrl-X Ctrl-E. Це відкриє ваш редактор за замовчуванням, що містить половину набраної команди. Тоді ви можете зберегти свою команду у файл або відкрити нову оболонку з вашого редактора. Після виходу з нової оболонки вона поверне вас до редактора, а збереження вмісту автоматично виконає їх.

Це не ідеально, оскільки він не повертає вас до початкової оболонки, але або змушує виконання команди, або повністю відкидає її. Але немає тимчасових виділень або вбивати буфери, щоб турбуватися, а також є деякі приємні налаштування, наприклад, якщо редактор = vi

:wq            # execute the command
:cq            # cancel and abort
:! command     # execute command
:shell         # open a new shell
:r filename    # insert the contents of a file for editing
:r ! command   # insert the output of a command for editing

Дуже приємна альтернатива. Я vi-emacs-агностик, тому буду радий молюскам, використовуючи це, коли powertools справді потрібні. (Якщо говорити про vi, то я деякий час тому спробував емулятор Linux N64 Mupen64Plus. Esc запускає емулятор, не економлячи. Я незабаром відмовився від гри.)
Lauritz V. Thaulow

1
@lazyr, для запуску debian / ubuntu sudo update-alternatives --config editorі виберіть улюбленого редактора. Для інших систем встановіть змінні середовища EDITOR або VISUAL улюбленим редактором, наприклад додайте export EDITOR=/usr/bin/nanoу свій .bashrc.
forcefsck

3

Подібно до способу додавання #на початку рядка, є, мабуть, простіший метод, який я використовую, який не потребує повернення до початку рядка:

Просто додайте відкриту пропозицію і не закривайте її - одиничну чи подвійну.

Потім натисніть Enter.

Потім натисніть CtrlC.

Часткова команда зберігається в історії команд (доступна за допомогою стрілки вгору), але насправді не виконується.


2

Використовуючи zsh, якщо ви введете <ESC> q(escape, то Q), рядок підказок буде вирізаний, щоб ви могли ввести іншу команду. Ви автоматично отримаєте відрізаний текст у наступному запиті.

Він може запам'ятати кілька рядків одночасно, тому ви можете використовувати його, поки лінія чекає на вас. Ви можете навіть використовувати його в порожньому рядку, щоб затримати відновлення вашої лінії скорочення.

Це не найефективніший спосіб, якщо вам доведеться використовувати кілька команд для перевірки / підготовки (вам доведеться повторно вводити <ESC> qперед кожною командою). Але я думаю, що можна прив’язати її до коротшої ярлики.


Якщо ви просто хочете перевірити посібник, введіть <ESC> h(escape, H). Це запустить run-helpвбудований, з аргументом першого слова командного рядка. Ви знайдете свою лінію недоторканою після завершення.


Більшість терміналів дозволять вам робити M-qзамість<ESC> q
sleblanc
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.