linux - tagger - puddletag ubuntu




В чем смысл! перед командой в оболочке? (2)

"!" Означает «не», поэтому, когда вы помещаете его перед командой и запускаете «$?» Он будет отображать 1, что означает, что он потерпел неудачу, а не 0, что означает успех.

Вопрос в заголовке. Какова цель команды оболочки (часть сценария оболочки), начинающейся с восклицательного знака? Конкретный пример:

В foo.sh:

#!/usr/bin/env bash
set -e
! docker stop foo
! docker rm -f foo
# ... other stuff

Я знаю, что без пробела восклицательный знак используется для замены истории и ! <expression> ! <expression> соответствии с man-страницей может использоваться для оценки " True, если expr имеет значение false ". Но в контексте примера это не имеет смысла для меня.


TL; DR: это просто set -e флага set -e в конкретной строке, где вы его используете.

Добавление добавить к правильному и полезному ответу hek2mgl .

У тебя есть:

set -e
! command

Справочное руководство Bash → Трубопроводы описывает:

Каждая команда в конвейере выполняется в своей собственной оболочке. Состояние выхода конвейера - это состояние выхода последней команды в конвейере (...). Если зарезервированное слово «!» перед конвейером, состояние выхода - это логическое отрицание состояния выхода, как описано выше. Оболочка ожидает завершения всех команд в конвейере, прежде чем вернуть значение.

Это значит что ! предшествующая команда отменяет статус ее выхода:

$ echo 23
23
$ echo $?
0
                # But
$ ! echo 23
23
$ echo $?
1

Или же:

$ echo 23 && echo "true" || echo "fail"
23
true
$ ! echo 23 && echo "true" || echo "fail"
23
fail

Статус выхода полезен во многих отношениях. В вашем скрипте, используемом вместе с set -e завершается всякий раз, когда команда возвращает ненулевой статус.

Таким образом, когда у вас есть:

set -e
command1
command2

Если command1 возвращает ненулевое состояние, сценарий завершится и не перейдет к command2 .

Однако есть еще один интересный момент, о котором следует упомянуть, описанный в 4.3.1 Построение набора :

-e

Немедленно завершите работу, если конвейер (см. Конвейеры), который может состоять из одной простой команды (см. Простые команды), списка (см. Списки) или составной команды (см. Составные команды), возвращает ненулевое состояние. Оболочка не завершает работу, если сбойная команда является частью списка команд, следующих сразу за ключевым словом некоторое время или до, часть теста в операторе if, часть любой команды, выполняемой в && или || список, кроме команды, следующей за последним символом && или ||, любой команды в конвейере, кроме последней, или если статус возврата команды инвертируется с помощью! , Если составная команда, отличная от подоболочки, возвращает ненулевое состояние из-за сбоя команды, когда -e игнорировалась, оболочка не завершается. Ловушка ERR, если установлена, выполняется до выхода из оболочки.

Принимая все это во внимание, когда у вас есть:

set -e
! command1
command2

То, что вы делаете, это set -e флаг set -e в команде 1. Зачем?

  • если command1 работает правильно, она вернет нулевой статус. ! будет отменять его, но set -e не будет запускать выход, потому что он приходит из состояния возврата, инвертированного с!, как описано выше.
  • если command1 не выполнена, она вернет ненулевой статус. ! будет отрицать его, поэтому строка в конечном итоге вернет нулевой статус, и сценарий продолжится в обычном режиме.






sh