Розуміння знака оклику (!) В баш


108

я використав

history | less

щоб отримати рядки попередніх команд і з цифр ліворуч я знайшов рядок, який я хотів повторити (наприклад, 22) і зробив

!22

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


6
Ця відповідь може допомогти
Майкл Мрозек

9
Не відповідь на ваше запитання, але <ctrl> + R дозволить вам інтерактивно шукати свою історію, а потім негайно виконувати, якщо ви знайдете те, що шукали.
кастерма

Відповіді:


144

!це особливість, яка спочатку з'явилася в оболонці С ще за дні, перш ніж ви могли розраховувати на терміналах, щоб мати клавіші зі стрілками. Це особливо корисно, якщо ви додасте поточний номер команди до рядку ( PS1="\!$ "), щоб ви могли швидко переглянути свій екран, щоб отримати цифри за минулі команди.

Тепер, коли ви можете використовувати клавіші зі стрілками і такі речі, як Ctrl-Rпошук історії команд, я не бачу великої користі для цієї функції.

Один із варіантів цього варіанту, який вам може бути корисним, - !!це повторне виконання попередньої команди. Сам по собі я не знаходжу !!Enterшвидше, ніж просто Enter, але це може бути корисно при поєднанні в більшу команду.

Приклад: Поширена помилка пілотування на sudoоснові базованих систем - це забути sudoпрефікс команди, яка вимагає додаткових привілеїв. Новачок повторно повторює всю команду. Старанний студент редагує команду з історії команд оболонки. Просвітлений один тип sudo !!.

Bash дозволяє вимкнути !обробку в оболонці з set +o histexpandабо set +H. Ви можете відключити його в Zsh за допомогою set -K.


4
Я вважаю Ctrl-P Ctrl-J досить швидким; швидше, ніж Up Enter, принаймні.
ефемієнт

24
Якщо ви просто хочете виконати останню команду, Up / Enter нормально, але якщо ви хочете якось додати її (скажімо, ви забули sudoчи щось), можете зробити це sudo !!, наприклад. Це може бути трохи швидше, ніж "Up / Ctrl-A (або Home, якщо пощастить) / sudo / space / enter". YMMV. :)

1
@AquariusPower: Просто цитуй це. Або echo 'Hi!'чи echo "Hi!"або echo Hi\!. Усі роблять те саме.
Warren Young

1
setopt NO_BANG_HISTв zsh може бути більш пам'ятним, ніж -K.
Григорій

48

Якщо немає більше відповіді, то тут, безумовно, одна на Super User, оскільки я читав її нещодавно. На сторінці bash man ви можете знайти величезний розділ під назвою ІСТОРІЙНЕ РОЗШИРЕННЯ з цього питання.

Ви можете виконати цілий хост більше, ніж просто виконати останню команду або номер команди X. Ви можете робити такі речі, як !catзапуск останньої команди, що почалася з cat. Або !?bash?:s/bash/csh/запускає останню команду, що містить, bashале замінює її csh.


3
Хоча це не є прямою відповіддю на питання ОП, це потребує набагато більших результатів. Так корисно! Спасибі, Хавок.
malvim

Гм, я дійсно повинен заглянути в сторінку чоловіка, перш ніж почати гуглювати.
erikbwork

1
!!:s/bash/csh/насправді виконує останню команду , а потім замінює bash на csh, якщо така є. Не остання команда, яка включала bash. Це було б, !?bash?:s/bash/csh/а може!?bash?:s/%/csh/
cde

Швидко використовуючи Bash протягом декількох років, я був шокований, виявивши, що раніше ніколи не знав про це ключове слово, і хоча я витратив години на перегляд manсторінок, ця функція неймовірно незрозуміла. Дякуємо, що вказали на відповідний розділ - це єдине місце у фактичних документах, де вони достатньо пояснюють це.
Стів Беннер

39

Набагато більше можна зробити з !такими як:

  • виконати команду, яка набирається перед 3 командами: !-3
  • виконати команду, яка починається з !ls

і багато іншого. Див. 15 прикладів розширення історії Bash Linux, які ви повинні знати


Оголосив це. Жодна з інших відповідей не мала жодного з цих хитромудрих хитрощів.
Гергелі Лукачсі

Оновлено, оскільки www.thegeekstuff.com - просто фантастичний ресурс, і це була одна з небагатьох статей Linux, яких я ще не бачив. Дуже корисний.
Стів Беннер

4

Мій друг надіслав мені це електронною поштою:

Це частина бібліотеки історії GNU. У bash він використовується для повторного запуску команд у вашій історії. Якщо ви хочете бути хардкор, перегляньте для data_expansion_char в bash-4.1 / lib / readline / histexpand.c для детальної інформації про реалізацію.


3

Звичайно, ви можете зробити !!повторне використання останньої команди в bash shell. А потім є !$повторне використання останньої частини останньої команди.

наприклад, переглянути якийсь файл

less path/to/your/file.txt

Якщо ви хочете відредагувати той самий файл, ви можете використовувати !$лише шлях до останньої команди до файлу

vim !$

1
Ах, я сподівався це знайти. Як він поводиться з двома аргами?
Джонатан

Це просто повторно використає останній аргумент двох. $touch f1 f2а потім $vim !$оцінюватимуть до$vim f2
Тешань Шанука J
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.