Як виконувати послідовні команди з історії?


49

Припустимо, я хочу виконати послідовність із чотирьох команд, які я виконував раніше. Якщо перший в історії команд - 432, я можу зробити:

$ !432; !433; !434; !435

Мені цікаво, чи є більш ефективний спосіб досягти цього?


1
Не публікуйте це як відповідь, оскільки він не виконує команди, але ви можете набрати history -p \!43{2..5}друк команд 432 по 435 до терміналу, що підходить для подальшої копіювання / вставки.
Wildcard

Відповіді:


48

Якщо це стосується команд, запущених зовсім недавно, більш ефективним способом є посилання на них з від'ємними числами:

!-4; !-3; !-2; !-1

Крім того, як тільки ви це зробите, ваш останній запис історії міститиме весь ланцюжок команд, тому ви можете повторити його !!.


Редагувати: Якщо ви ще цього не зробили, ознайомтеся з чудовою вбудованою функцією fc, про яку згадував Жилль . (Використовуйте help fc.) Виявляється, ви також можете використовувати негативні числа за допомогою нього, так що ви можете зробити те саме, що описано вище, використовуючи

eval "`fc -ln -4 -1`"

Однак є один застереження: після цього evalрядок зберігається в історії як остання команда. Тож якщо запустити це ще раз, ви потрапите в цикл!

Більш безпечним способом цього є використання fcрежиму роботи за замовчуванням : пересилання вибраного діапазону команд до редактора та запуску їх після виходу з нього. Спробуйте:

 fc -4 -1

Ви навіть можете змінити порядок діапазону команд: fc -1 -4


Я просто прочитав те, що написав ... ЛОЛ. Насправді я не впевнений у повторному зверненні ( можливо, повторне звернення ), але дякую за те, що розповів :) Я завжди ціную виправлення.
rozcietrzewiacz

Scrabblefinder.com каже, що повторне відкликання - дійсне слово Scrabble. Неможливо отримати більш чітке, ніж це. :)
BentFX

1
При гарній відповіді, як ця (+1), не має значення, як ви її написали; тим більше, що жодна форма орфографії не відображається в трьох основних словниках англійської мови: Оксфорд, Кемдрідж, Мерріам-Вебстер (я пішов би за дефіс)
Пітер.O

34

Для перегляду діапазону команд в історії використовуйте вбудовану fcкоманду:

fc -ln 432 435

Щоб виконати їх знову:

eval "$(fc -ln 432 435)"

4
Дуже хороша. Мені цікаво, чому man fcмені нічого не дають. Що означає fc? Які ще варіанти є?
Ерік Вілсон

2
@Eric Wilson ... введіть help fc... і також help help.... help: help [-dms] [pattern ...] Відображення інформації про вбудовані команди.
Пітер.O

Я щойно повернувся сюди, шукаючи вашої відповіді. Це справді чудовий вбудований! Особливо, коли у вас є його функціональність за замовчуванням - виклик редактора для зміни діапазону команд, які потрібно відтворити. Спасибі, Жилле.
rozcietrzewiacz

1
Без -lпрапора він буде страчений без потреби зла eval.
Бернхард

1
@EricWilson Пошук у Google приведе мене до книги "Unix в горішці", де написано, що fcозначає "знайти команду" або "виправити команду".
Slothworks

10

Існує приємний і альтернативний спосіб запускати ряд команд послідовно з історії Bash:
замість використання замінника історії ( !432або !-4) ви можете шукати історію за допомогою Ctrl+ rі, як тільки ви знайдете першу команду, яку хочете виконати запустити, натиснути Ctrl+ o( операція-і-отримати-далі ) замість returnключа.
Це запустить команду і запропонує наступну з історії. Ви можете натиснути Ctrl+oскільки завгодно часу, і закінчити послідовність або returnостаннім, або Ctrl+cзупинити, не запускаючи його.


Хм, після того, як я натиснув Ctrl-oйого, просто виводить буквальне ^oі розбиває моє (reverse-i-search). Можливо, тут є якась інша установка.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

8

Щоб виконати команди негайно, а не редагувати їх, ось синтаксично стрункіша версія відповіді Гілза за допомогою eval :

fc -e: 432 435

Аргумент двокрапки до -e - це bash noop, який спричиняє пропуск кроку "відкрити в редакторі", який хоче fc. Крім того, тепер (недавня) історія міститиме фактичні команди з історії, а не оператор eval.


0

fc для петлі і xsel

Це добре працює, коли я хочу об'єднати та повторно запустити останні n команд кілька разів:

fcn() (
  from="${1:-2}"
  to="${2:-1}"
  if [ "$from" -ne "$to" ]; then
    for i in `seq "$from" -1 "$(($to + 1))"`; do
      printf "$(fc -ln -${i} -${i}) && "
    done
  fi
  printf "$(fc -ln -${to} -${to})"
)

Тоді:

$ echo a
a
$ echo b
b
$ echo c
c
$ fcn 3 1 | xsel -b
$ # Paste.
$  echo a &&  echo b &&  echo c
a
b
c
$ # Paste again if you feel like it.
$  echo a &&  echo b &&  echo c
a
b
c

Або для більших команд, які можуть потребувати редагування:

fcn 3 1 >cmds.sh
vi cmds.sh
bash cmds.sh
bash cmds.sh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.