почему tee отказывается работать при удаленном запуске через ssh?

Вы ошиблись. /bin/shпочти никогда не является оболочкой Борна в наши дни, и именно тогда¹ у вас возникают проблемы при использовании #! /bin/shона -взрыва.

Оболочка Борна была написана в конце 70-х и заменила предыдущую оболочку Томпсона (, также называемую sh). В начале 80-х Дэвид Корн написал несколько расширений для оболочки Bourne, исправил несколько ошибок и несуразностей дизайна (, а также представил некоторые )и назвал это оболочкой Korn.

В начале 90-х POSIX определилshязык , основанный на подмножестве оболочки Korn, и большинство¹ систем теперь изменили свой /bin/shлибо на оболочку Korn, либо на оболочку, соответствующую этой спецификации. В случае с BSD они постепенно изменили свою /bin/sh, первоначально (после того, как они больше не могли использовать оболочку Bourne по причинам лицензии )оболочку Almquist, клон оболочки Bourne с некоторыми расширениями ksh, поэтому она стала POSIX-совместимый.

Сегодня все системы POSIX чаще всего имеют оболочку с именем sh(, но не обязательно в /bin, POSIX не указывает путь к утилитам, которые он указывает ), которые в основном совместимы с POSIX. Обычно он основан на ksh88, ksh93, pdksh, bash, ash или zsh², но не на оболочке Bourne, поскольку оболочка Bourne никогда не была совместима с POSIX³. Несколько таких снарядов (bash, zsh,yashи некоторые производные pdkshвключают режим совместимости с POSIX -при вызове как shи менее совместимы в противном случае ).

bash(ответ GNU на оболочку Korn )на самом деле является единственной оболочкой с открытым исходным кодом (, и можно сказать, что она поддерживается только в настоящее время, поскольку другие, как правило, основаны на ksh88, который не получил никаких новых функций с 90-х годов. ), который был сертифицирован как совместимый с POSIXsh(в рамках сертификации macOS ).

Когда вы пишете скрипт с #! /bin/sh -ше -челкой, вы должны использовать стандартный shсинтаксис (и также должны использовать стандартный синтаксис для утилит, используемых в этом скрипте, если вы хотите быть переносимым, при интерпретации сценария оболочки )задействована не только оболочка, тогда не имеет значения, какая реализация того стандартного shинтерпретатора синтаксиса используется (ksh, bash... ).

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

Здесь, с вашим #! /bin/shона -ударом, вашей основной проблемой будут системы, где /bin/sh— это оболочка Борна, которая, например, не поддерживает стандартные функции, такие как $((1+1)), $(cmd), ${var#pattern}... В этом случае вам может понадобиться работа -вокруг, например:

#! /bin/sh -
if false ^ true; then
  # in the Bourne shell, ^ is an alias for |, so false ^ true returns
  # true in the Bourne shell and the Bourne shell only.
  # Assume the system is Solaris 10 (older versions are no longer maintained)
  # You would need to adapt if you need to support some other system
  # where /bin/sh is the Bourne shell.
  # We also need to fix $PATH as the other utilities in /bin are
  # also ancient and not POSIX compatible.
  PATH=`/usr/xpg6/bin/getconf PATH`${PATH:+:}$PATH || exit
  export PATH
  exec /usr/xpg4/bin/sh "$0" "$@"
  # that should give us an environment that is mostly  compliant
  # to the Single UNIX Specification version 3 (POSIX.2004), the
  # latest supported by Solaris 10.
fi
# rest of the script

Кстати, /bin/shв Ubuntu по умолчанию не является bash. В наши дни это dash, оболочка, основанная на NetBSD sh, сама основанная на оболочке Almquist, которая в основном совместима с POSIX, за исключением того, что она не поддерживает многобайтовые -символы. В Ubuntu и других системах на базе Debian -вы можете выбирать между bashи dashдля /bin/shс помощьюdpkg-reconfigure dash)4 .shСкрипты, поставляемые с Debian, должны работать одинаково в обеих оболочках, поскольку они написаны в соответствии со стандартом политики Debian (надмножеством стандарта POSIX ). Вы, вероятно, обнаружите, что они также работают нормально в эмуляции zshshили bosh(, вероятно, не ksh93и yash, которые не имеют встроенного local(, требуемого политикой Debian. но не POSIX )).

Все системы на unix.stackexchange.com где-то имеют POSIX sh. У большинства из них есть /bin/sh(, вы можете найти очень редкие, у которых нет каталога /bin, но вам, вероятно, все равно на это ), и это, как правило, интерпретатор POSIX sh(и в редких случаях (не -стандартная )оболочка Борна вместо ).

Но sh— это единственный исполняемый интерпретатор оболочки, который вы обязательно найдете в системе. Для других оболочек вы можете быть уверены, что macOS, Cygwin и большинство дистрибутивов GNU/Linux будут иметь bash. Операционные системы, производные от SYSV -(Solaris, AIX... )обычно имеют ksh88, возможно, ksh93. OpenBSD, MirOS будет иметь производную от pdksh. macOS будет иметь zsh. Но из этого не будет никакой гарантии. Нет гарантии того, что bashили любая из этих других оболочек будет установлена ​​в /binили где-либо еще (, она обычно находится в /usr/local/binна BSD при установке, например ). И конечно нет гарантии версии оболочки которая будет установлена.

Обратите внимание, что #! /path/to/executableне является соглашением , это особенность всех Unix -подобных ядер (, представленная в начале 80-х Деннисом Ритчи ), которая позволяет выполнять произвольные файлы указав путь к интерпретатору в первой строке, начинающейся с #!. Это может быть любой исполняемый файл.

Когда вы выполняете файл, первая строка которого начинается с #! /some/file some-optional-arg, ядро ​​завершает выполнение /some/fileс some-optional-arg, путем к сценарию и исходными аргументами в качестве аргументов.Вы можете сделать эту первую строку #! /bin/echo test, чтобы увидеть, что происходит:

$./myscript foo
test./myscript foo

Когда вы используете /bin/sh -вместо /bin/echo test, ядро ​​выполняет /bin/sh -./myscript foo, shинтерпретирует код содержимого, хранящийся в myscript, и игнорирует первую строку, поскольку это комментарий (, начинающийся с #). ].


¹ Вероятно, единственная система, в которой сегодня кто-либо из нас столкнется с /bin/sh, основанной на оболочке Bourne, — это Solaris 10. Solaris — одна из немногих систем Unix, которые решили сохранить оболочку Bourne для обратной совместимости (язык POSIX shне имеет полной обратной совместимости с оболочкой Bourne )и (, по крайней мере, для настольных и полных развертываний сервера )есть POSIX shв другом месте (в /usr/xpg4/bin/sh, основанный на ksh88 ), но это изменилось в Solaris 11, где /bin/shтеперь равно ksh93. Остальные, в основном, мертвы.

² /bin/shв MacOS/X раньше был zsh, но позже был изменен на bash. zshzshне предназначен для использования в качестве реализации POSIX sh. Его shрежим в первую очередь предназначен для встраивания или вызова(source)кода POSIX shв zshскриптах

.

³ Недавно @schily расширил оболочку OpenSolaris (на основе оболочки SVR4, основанную на оболочке Bourne ), чтобы она стала совместимой с POSIX, называемой bosh, но я не знаю что он уже используется в любой системе. Наряду с ksh88, что делает его второй оболочкой, совместимой с POSIX -, основанной на коде оболочки Bourne

.

4 В более старых версиях вы также могли использовать mkshили его большее воплощение POSIX lksh. Это МирОС (бывшая оболочка MirBSD )на основе pdksh, сама основанная на оболочке Forsyth (другая повторная реализация оболочки Bourne))

4
20.02.2021, 09:26
0 ответов

Теги

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