Що робиться набравши єдиний знак оклику в Bash?


20

Bash використовує знаки оклику для розширення історії, як пояснено у відповідях на це питання (наприклад, sudo !!запускає попередній командний рядок з sudo). Однак я не можу ніде знайти, що пояснює, що працює наступна команда (тобто єдиний знак оклику):

!

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

}

друкує помилку:

bash: syntax error near unexpected token `}'

1
Нічого. !вказує на "початок" вираження розширення історії.
Йорданм

Відповіді:


47

Одинокий !на початку команди заперечує стан виходу команди або конвеєра : якщо команда вийде 0, вона перетвориться на 1(збій), а якщо вона вийде ненульовою, вона перетворить її на 0(успішний) вихід.

Це використання задокументовано в посібнику Bash:

Якщо застережене слово "!" перед трубопроводом, статус виходу є логічним запереченням статусу виходу, як описано вище.

!З допомогою наступної команди не заперечує порожню команду, яка нічого не робить і повертає істинне (еквівалент в :команді ). Таким чином, це перетворює значення true у false та виходить зі статусом 1, але не створює помилок.


Існують також інші способи використання в !межах testта [[команд, де вони заперечують умовний тест. Вони не пов'язані з тим, що ви бачите. Як у вашому запитанні, так і в тих випадках це не пов’язано з розширенням історії і !відокремлено від будь-яких інших термінів.


5
+1 для першої відповіді, щоб пояснити, що насправді виконується, і чому це пояснює код повернення.
Джефф Шаллер

11

Ви можете знайти єдиний знак оклику, задокументований в розділі 3.2.2 Трубопроводи

Якщо застережене слово "!" перед трубопроводом, статус виходу є логічним запереченням статусу виходу, як описано вище.

$ ! true; echo $?
1
$ ! false; echo $?
0

Також розділ 3.2.4.2 Умовні конструкції

! вираз

Вірно, якщо вираз хибний.


Також розділ 4.1. Бультіни Борна

! експр

Щоправда, якщо expr неправдивий.


Слід також зазначити, що !почнеться заміна історії, якщо не буде пробіл: пробіл, вкладка, кінець рядка, '=' або '(' (коли опція оболонки extglob увімкнена за допомогою вбудованого shopt).


0

Тому що !використовується в порівняннях і означає НЕ .

Наприклад:

a=3
b=2

[ $a -eq $b ] && echo "Equal"
[ ! $a -eq $b ] && echo "Not equal"
# of cause last comparison is possible to write as:
[ $a -eq $b ] || echo "Not equal"

[ $a -eq $b ]
echo $?
1
[ ! $a -eq $b ]
echo $?
0

1
Це сенс !як аргумент testкоманди (включаючи вбудовану версію bash), а не значення !при використанні в командному положенні.
Жил "ТАК - перестань бути злим"

1
У цьому випадку потрібно ! [...]відповідати питанню.
Майкл Гомер

Погоджено з @Gilles та @Michael Homer. Я знав, що []це test. Я трохи поспішаю.
Юрій Гончарук

-2

! вбудована команда, інвертує сенс конвеєра.

Інші види використання:

#! вбудована команда викликає названого інтерпретатора для виконання сценарію.

! позначення події, позначає слово командного рядка як заміну історії

!= оператор нерівності

$! змінної оболонки, повертає номер процесу останньої фонової команди.


Просто додати, можна використовувати! $, Щоб використовувати останнє слово попередньої команди так: ls -l /tmp cd !$ Це перенесе вас до каталогу / tmp.
Заскакуючий Зайчик

-3

! Після цього рядок виконує останню попередню команду (все ще знаходиться в буфері команд), що почалася з даної рядка. Можливо, оболонка щойно виявила, що жодна попередня команда не починалася з <null>.


3
Ви помітили, що у запитанні не було заданого рядка ...?
Джефф Шаллер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.