перенаправить stdout и stderr на null в середине цепочки '&&'

ifupdownНабор скриптов не предназначен для такой работы.

Вместо этого вы можете:

  1. Прекратите использовать ifupdownи настройте сеть самостоятельно с помощью специального скрипта. (я бы, наверное, выбрал этот вариант)
  2. Используйте функцию post-upфункции ifupdown, таким образом:
iface eth0 inet static
  pre-up ifconfig eth0 hw ether `cat /root/macaddress`
  address 0.0.0.0
  netmask 255.255.255.0
  post-up ifconfig eth0 `cat /root/ipaddress`

Обратите внимание, что я не проверял, может ли post -up управлять конструкцией обратной кавычки...

Может быть, вы также можете покопаться в методах manual(вместо static)...

0
19.11.2020, 19:25
2 ответа

Это смесь задачи XY, вопроса о каналах, выходах и делении. Я попытаюсь прояснить их, хотя я чувствую, что нет ни одного вопроса, на который нужно ответить.

Язык оболочки

Группировка

echo "before" && echo inside1 && echo inside2 && echo "after"

Чтобы сгруппировать несколько операторов, можно использовать либо круглые, либо фигурные скобки:

echo "before" && ( echo inside1 && echo inside2 ) && echo "after"
echo "before" && { echo inside1 && echo inside2; } && echo "after"

()будет работать в подоболочке, а { }просто формирует список в текущей среде. Оба могут использоваться для перенаправления вывода этой части.

echo "before" && ( echo inside1 && echo inside2 ) > /dev/null && echo "after"
echo "before" && { echo inside1 && echo inside2; } > /dev/null && echo "after"

Возвращаемые значения

Каждая команда возвращает значение по завершении. Он сохраняется в $?, поэтому вы можете просмотреть его с помощьюecho $?сразу после выполнения .

Принято считать, что возврат нуля означает успешное завершение, а отсутствие -нуля означает неудачу. Все, что программа может считать успехом. Операторы оболочки and &&и or ||работают с этой концепцией. Есть также пара удобных крошечных утилит, называемых trueи false, которые всегда возвращают ноль (успех )и ненулевой (отказ )соответственно.

if true && false; then
 echo Yes
else
 echo No
fi

Когда вы соединяете серию &&, правая рука оператора выполняется только в том случае, если левая рука вернула успех.

Например, вы можете создать папку с именем photosи переместить туда все файлы.

Вы можете сначала попробовать

mv *.jpg photos

Но если есть одна фотография и нет папки photos, она переименует фотографию в photos.

Вы можете использовать &&для перемещения изображений, только если папка создана успешно:

mkdir photos && mv *.jpg photos

Если mkdirдал сбой, mvне выполняется.

Это связано с тем, что в случае сбоя mkdirвернет не -ноль.

Однако, если папка photosуже существует, mkdirтакже вернет ошибку (: не удалось создать папку).

Так что более сложная проверка может быть:

( test -d photos || mkdir photos ) && mv *.jpg photos/

Если фотографии уже являются каталогом,он не будет пытаться создать его и вместо этого перейдет к перемещению изображений. Если же photosне был каталогом, но он смог его создать, он также добьется успеха и переместит фотографии.

Если фотографии не были папкой (или символической ссылкой на папку )и она не была создана, левая часть &&не работала и фотографии не перемещались.

Примечание :Для этого конкретного примера вы могли бы использовать более простой mkdir -p photos && mv *.jpg photos/, так как флаг -pзаставляет mkdir создавать промежуточные папки и не отключать их, если папка уже существует, но это менее дидактично.

Трубопроводы

Если у вас есть конвейер, по умолчанию его возвращаемое значение — это одна из самых правых команд. Если вы выполните

command1 | command2 | command3

возвращаемое значение конвейера в целом будет таким же, как command3. Неважно, возвратил command1или command2не -ноль. Это можно изменить, установив параметр pipefailтак, чтобы возвращаемое значение было одним из самой правой команды в конвейере, которая вернула не -ноль .

Деление на ноль

в вашем случае echo 1/0 | bcне останавливает конвейер, потому что bcвозвращает код 0, даже несмотря на то, что на экране отображается диагностика попытки деления на ноль.

Непосредственное выполнение $((1/0))проблематично, так как ошибка возникает при расширении. Вы можете обернуть его в новый процесс оболочки:

echo hi1 && bash -c 'echo $((1/0))' 2> /dev/null && echo hi2

или даже просто подоболочка

echo hi1 && ( echo $((1/0))' ) 2> /dev/null && echo hi2

Существует также базовое решение, состоящее в фактической проверке того, равен ли делитель нулю . Например:

division() {
  if [ "$2" -eq 0 ]; then
     return 1
  fi
  echo "$(( $1 / $2 ))"
}

echo hi1 && division 1 0 && echo hi2

Вы даже можете сделать что-то подобное с функцией bc(она будет выводить 0, а не пусто, хотя):

define division(x,y) {
   if (y == 0) return;
   return x/y;
}
division(1,0)
1
18.03.2021, 22:48

Even without redirection, the divide-by-zero failure doesn't stop the && chain, i.e. the short-circuited-'and'-operator chain.

GNU bc:

$ echo "1/0" | bc 
Runtime error (func=(main), adr=3): Divide by zero
$ echo $?
0

Бизибокс:

$ echo "1/0" | busybox bc 
bc: divide by zero
$ echo $?
1

POSIX до н.э.:

NAME
bc - arbitrary-precision arithmetic language
EXIT STATUS
The following exit values shall be returned:
0 -- All input files were processed successfully.
unspecified -- An error occurred.

RATIONALE
The exit status for error conditions has been left unspecified for several reasons:

  • The bc utility is used in both interactive and non-interactive situations. Different exit codes may be appropriate for the two uses.
  • It is unclear when a non-zero exit should be given; divide-by-zero, undefined functions, and syntax errors are all possibilities.
  • It is not clear what utility the exit status has

Это не разрывает цепочку, потому что ваш bc не считает деление на ноль чем-то, что заслуживает возврата ложного статуса выхода.

Однако GNU bc возвращает ложный статус выхода, если не может прочитать входной файл.

I'd like to use the bc method, mainly to avoid bash-isms like the $(( )) that will follow.

$(( ))не является башизмом, это часть языка оболочки POSIX (арифметического расширения).


Я не уверен, каков здесь контекст, как деление на ноль связано с условным оператором и цепочкой &&и что вы пытаетесь сделать в конце, поэтому трудно предложить какие-либо предложения.

Альтернативой тому, чтобы полагаться на обнаружение деления на ноль, может быть проверка делителя нуля перед первой попыткой деления.

2
18.03.2021, 22:48

Теги

Похожие вопросы