Существует ли способ прервать межпроцессное взаимодействие в Unix/Linux?

Точный язык, используемый в Единственной спецификации UNIX для описания значения set -e :

Когда эта опция идет, если простая команда перестанет работать по какой-либо из причин, перечисленных в Последствиях Ошибок Shell, или возвратит значение статуса выхода> 0 и не будет [условным выражением или отрицаемой командой], то оболочка должна сразу выйти.

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

Один такой проблематичный случай является тем, с которым Вы встретились: ненулевой статус возврата от замены команды. Так как это состояние проигнорировано, оно не заставляет родительскую оболочку выходить. Поскольку Вы уже обнаружили, способ принять статус выхода во внимание состоит в том, чтобы использовать замену команды в простом присвоении: затем статус выхода присвоения является статусом выхода последней замены команды в присвоении (присвоениях).

Обратите внимание, что это будет работать, как предназначено, только если существует единственная замена команды, поскольку только состояние последней замены принято во внимание. Например, следующая команда успешна (и согласно стандарту и в каждой реализации, которую я видел):

a=$(false)$(echo foo)

Другой случай для наблюдения за является явными подоболочками: (somecommand). Согласно интерпретации выше, подоболочка может возвратить ненулевое состояние, но так как это не простая команда в родительской оболочке, родительская оболочка должна продолжиться. На самом деле все оболочки, о которых я знаю, действительно делают родительский возврат в этой точке. В то время как это полезно во многих случаях такой как (cd /some/dir && somecommand) где круглые скобки используются для хранения операции, такой как изменение текущего каталога локальной, это нарушает спецификацию если set -e выключен в подоболочке, или если бы подоболочка возвращает ненулевое состояние способом, которое не завершило бы ее, такие как использование ! на истинной команде. Например, весь пепел, удар, pdksh, ksh93 и zsh выходит без отображения foo на следующих примерах:

set -e; (set +e; false); echo "This should be displayed"
set -e; (! true); echo "This should be displayed"

Все же никакая простая команда не перестала работать в то время как set -e был в действительности!

Третий проблематичный случай является элементами в нетривиальном конвейере. На практике все оболочки игнорируют отказы элементов конвейера кроме последнего и показывают одно из двух поведений относительно последнего конвейерного элемента:

  • ATT ksh и zsh, которые выполняют последний элемент конвейера в родительской оболочке, занимаются бизнесом, как обычно: если простая команда перестала работать в последнем элементе конвейера, оболочка, выполняющая ту команду, которая, оказывается, родительская оболочка, выходы.
  • Другие оболочки приближают поведение путем выхода, если последний элемент конвейера возвращает ненулевое состояние.

Как прежде, выключая set -e или использование отрицания в последнем элементе конвейера заставляет это возвращать ненулевое состояние способом, которое не должно завершать оболочку; оболочки кроме ATT ksh и zsh затем выйдут.

Bash pipefail опция заставляет конвейер сразу выйти под set -e если какой-либо из его элементов возвращает ненулевое состояние.

Обратите внимание, что как дальнейшая сложность, удар выключает set -e в подоболочках, если это не находится в режиме POSIX (set -o posix или имейте POSIXLY_CORRECT в среде, когда удар запускается).

Все это показывает, что спецификация POSIX, к сожалению, делает плохое задание при определении -e опция. К счастью, существующие оболочки главным образом последовательны в своем поведении.

15
23.11.2010, 23:25
2 ответа

Это во многом зависит от механизма связи.

  • В самом прозрачном конце спектра процессы могут передать интернет-сокеты использования (т.е. IP). Затем wireshark или tcpdump могут показать весь трафик путем указания на него на петлевой интерфейс.

  • На промежуточном уровне трафик в каналах и сокетах Unix может наблюдаться с truss/strace/trace/..., швейцарская армейская цепная пила системной трассировки. Это может значительно замедлить процессы, однако, таким образом, это не может подойти для профилирования.

  • В самом непрозрачном конце спектра существует общая память. Основной операционный принцип общей памяти - то, что доступы абсолютно прозрачны в каждом включенном процессе, Вам только нужны системные вызовы для установки регионов общей памяти. Трассировка этих доступов памяти с внешней стороны была бы трудна, особенно при необходимости в наблюдении для не беспокойства синхронизации. Можно попробовать инструменты как инструментарий трассировки Linux (требует патча ядра), и посмотрите, можно ли извлечь полезную информацию; это - вид области, где я ожидал бы, что Солярис будет иметь лучший инструмент (но я не знаю о нем).

    Если у Вас есть источник, Ваш наилучший вариант может состоять в том, чтобы добавить трассировочные операторы для манипулирования библиотечных функций. Это может быть достижимо с LD_PRELOAD приемы, даже если у Вас нет (целого) источника, пока у Вас есть достаточно понимания потока управления части программы, что это получает доступ к общей памяти.

19
27.01.2020, 19:49

Это покажет то, что процесс читает и пишет:

strace -ewrite -p $PID

Это не чистый вывод (показывает строки как: запишите (#)), но работы! (и одна строка :D), Вам мог бы также не понравиться факт, что аргументы сокращены. Управлять тем использованием-s параметр, который устанавливает maxlength отображенных строк.

Это ловит все потоки, таким образом, Вы могли бы хотеть отфильтровать это так или иначе.

Можно отфильтровать его:

strace -ewrite -p $PID 2>&1 | grep "write(1"

шоу только дескриптор 1 вызов. 2> &1 должен перенаправить stderr к stdout, как strace пишет в stderr по умолчанию.

6
27.01.2020, 19:49

Теги

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