Что эквивалент к && при записи сценария удара?

Вот три вещи, которые можно сделать с заменой процесса, которые невозможны иначе.

Несколько исходных данных процесса

diff <(cd /foo/bar/; ls) <(cd /foo/baz; ls)

Просто нет никакого способа сделать это с каналами.

Сохранение STDIN

Скажите, что у Вас есть следующее:

curl -o - http://example.com/script.sh
   #/bin/bash
   read LINE
   echo "You said ${LINE}!"

И Вы хотите выполнить его непосредственно. Следующее терпит полный провал. Bash уже использует STDIN для чтения сценария, таким образом, другой вход невозможен.

curl -o - http://example.com/script.sh | bash 

Но этот путь работает отлично.

bash <(curl -o - http://example.com/script.sh)

Исходящая замена процесса

Также обратите внимание, что замена процесса работает другой слишком. Таким образом, можно сделать что-то вроде этого:

(ls /proc/*/exe >/dev/null) 2> >(sed -n \
  '/Permission denied/ s/.*\(\/proc.*\):.*/\1/p' > denied.txt )

Это - определенный замысловатый пример, но он отправляет stdout в /dev/null, в то время как передача по каналу stderr к sed сценарию для извлечения названий файлов, для которых "Разрешение отклонило" ошибку, была отображена и затем отправляет ТЕ результаты в файл.

Обратите внимание, что первая команда и stdout перенаправление находятся в круглых скобках (подоболочка) так, чтобы только результат ТОЙ команды был отправлен в /dev/null и это не смешивает с остальной частью строки.

31
02.02.2013, 22:15
7 ответов

Можно сделать это как это:

#!/bin/sh
ls -lh &&
    # This is a comment
    echo 'Wicked, it works!'

Я надеюсь, что понял то, что Вы спросили правильно.

23
27.01.2020, 19:37
  • 1
    Спасибо. Это является самым близким к тому, что я надеялся сделать. И это делает очень легким преобразовать назад в один лайнер в случае необходимости. –  Mike B 02.02.2013, 23:18
  • 2
    Mike, так как Вы обеспокоены чистотой кода, общая конвенция, должен расположить 2-N разделы с отступом цепочки под первым. –  jblaine 13.02.2013, 21:42
  • 3
    @jblaine я не уверен, что понимаю то, что Вы имеете в виду. Можно ли уточнить? –  Mike B 16.02.2013, 21:41
  • 4
    Mike, Stackexchange не позволит мне отформатировать свой ответ правильно, таким образом, вот будет все, что я имел в виду: отступ –  jblaine 03.04.2013, 22:03
  • 5
    @jblaine, отредактированная для расположения с отступом строк. –  Volker Siegel 21.08.2014, 07:18

Можно изменить строку хижины на

#!/bin/bash -e

После любой ошибки остановится сценарий.

38
27.01.2020, 19:37
  • 1
    Интересный. Я буду иметь это в виду.Спасибо. –  Mike B 02.02.2013, 23:19
  • 2
    сохраняет меня от ввода набора-e, когда мне нужен он –  Silverrocker 02.02.2013, 23:38
  • 3
    @Silverrocker Это - POSIX также (за исключением bash часть, конечно). Оболочка POSIX берет набор опций, которые применимы к set. Или наоборот? set способ установить параметры командной строки оболочки в рамках сценария. Солярис –  Kaz 03.02.2013, 05:38
  • 4
    кошку –  ruakh 03.02.2013, 08:23
  • 5
    я раньше помещал -e на хижине, пока один администратор моей компании не продолжал запускать мои сценарии с bash myscript.sh, таким образом, это проигнорировало -e. Теперь все мои сценарии имеют a set -e во второй строке. –  Carlos Campderrós 04.02.2013, 10:00

Если Вам не нравится set -e идея, возможно, можно инвертировать логику.

foocommand || exit 1
foocommand2 || exit 2
foocommand3 || exit 3

Более полезно, замена exit с чем-то для печати полезного сообщения об ошибке затем выйдите. В функции, конечно, Вы хотите return вместо exit.

19
27.01.2020, 19:37
  • 1
    Или foocommand || exit выходить с foocommandстатус выхода, если ненулевой. –  Stéphane Chazelas 02.02.2013, 23:10
  • 2
    Как это работает? Похож на это в C - если левый аргумент оценивает к ПРАВДА, больше аргументов не проверяется? –  Vorac 29.03.2013, 17:39
  • 3
    Да, правильно. Это - общая идиома в Lisp (и функциональные языки в целом, я предполагаю), и в Perl. –  tripleee 30.03.2013, 10:14

Можно использовать if else fi блоки вместо этого.

if foocommand; then

  # some comments

  if foocommand2; then

    # more comments

    foocommand3
  fi
fi

Это немного более читаемо.

Кроме того, можно просто использовать \ повредить Ваш большой 1 лайнер в несколько строк

foocommand && \
  # some comment
  foocommand2 && \
    # more comment
    foocommand3

Но конечно это может сбивать с толку нетренированный глаз.

9
27.01.2020, 19:37
  • 1
    я не думаю \ необходимо там. –  Samuel Edwin Ward 03.02.2013, 03:49
  • 2
    Вы правы. Сила привычки. –  Martín Canaval 03.02.2013, 04:15

Вы могли рассмотреть использование вложенный if операторы. Другая опция состоит в том, чтобы использовать curly's для группировки как { true && echo hi; } || echo huh

Обновление 1:

Вот пример без новых строк/комментариев:

{ { false && echo "inner true"; } && { echo "inner true" && true; } || { echo "inner false" && false; } || echo "outter false"; }
5
27.01.2020, 19:37
  • 1
    @Stephane спасибо за добавление точки с запятой. Я использовал свой телефон для ответа, таким образом, я не проверял свои ответы дважды. :) –  livingstaccato 02.02.2013, 23:52
  • 2
    Интересная идея. Да, я думал вложенный, если операторы, но если я объединяю много в цепочку материала вместе, это могло бы стать грязным. –  Mike B 03.02.2013, 00:38

Разделите каждую последовательность команд в функции:

big_block_1() {
  # ...
}
big_block_2() {
  # ...
}
big_block_3() {
  # ...
}

big_block_1 && big_block_2 && big_block_3
4
27.01.2020, 19:37

Мне всегда нравится писать функцию "сбоя", которая позволяет мне указать вещь, которую я собирался сделать, когда отказ произошел, и затем используйте || шаблон. Как следующее:

function fail() {
  echo "Failure: ${@}"
  exit 1
}

foocommand || fail "couldn't foo"
0
27.01.2020, 19:37

Теги

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