Подтвердить что ты не робот

Требуется меньшая оболочка

В моей системе Ubuntu /usr/bin/ssh-copy-id содержит любопытный фрагмент кода вверху. Похоже, проверяется, что /bin/sh является "разумной оболочкой". Если это не так, он пытается перезапустить script с помощью ksh. Если это не удается, оно подбрасывает руки и выводит сообщение об ошибке.

Что именно он проверяет? В частности, что делает if false ^ printf, и почему он срабатывает только в старых оболочках? Использовали ли древние раковины XOR-оператор или что?

#!/bin/sh
# ...
# check that we have something mildly sane as our shell, or try to find something better
if false ^ printf "%s: WARNING: ancient shell, hunting for a more modern one... " "$0"
then
  SANE_SH=${SANE_SH:-/usr/bin/ksh}
  if printf 'true ^ false\n' | "$SANE_SH"
  then
    printf "'%s' seems viable.\n" "$SANE_SH"
    exec "$SANE_SH" "$0" "[email protected]"
  else
    cat <<-EOF
        oh dear.

          If you have a more recent shell available, that supports \$(...) etc.
          please try setting the environment variable SANE_SH to the path of that
          shell, and then retry running this script. If that works, please report
          a bug describing your setup, and the shell you used to make it work.

        EOF
    printf "%s: ERROR: Less dimwitted shell required.\n" "$0"
    exit 1
  fi
fi
4b9b3361

Ответ 1

Оригинал Bourne поддерживал ^ как оператор трубы. Это было сброшено в оболочку Korn (из которой получен POSIX sh spec) и, таким образом, является функцией, доступной в Bourne, но не в POSIX sh.

Таким образом, этот код проверяет оболочки pre-POSIX Bourne.

Ответ 2

Эта часть предназначена для script для работы с Solaris 10 и старше, где /bin/sh не совместим с POSIX. Обратите внимание, что последнее не является ошибкой, поскольку POSIX не указывает путь sh.

/bin/sh/sbin/sh) на Solaris 10, вероятно, являются единственными оставшимися оболочками в текущих ОС, которые все еще поддерживают эту форму трубы, которая появилась в исходной оболочке Bourne.