Почему в «$0» на Mac есть знак минуса?

Почему в «$0» на Mac есть знак минуса?

Я уже много лет являюсь пользователем GNU/Linux, но не могу понять, как получить полезную информацию о процессах на Mac.

Я понял, что это $0разрешается -bashв моей оболочке входа в Mac OS (Snow Leopard).Это может привести к сбою некоторых скриптов оболочки, которые отлично работают в среде Linux.*.

К сожалению, на странице руководства этот факт не упоминается.

Если bash вызывается с файлом команд, $0 устанавливается на имя этого файла. Если bash запускается с опцией -c, то $0 устанавливается на первый аргумент после строки, которая должна быть выполнена, если таковой присутствует. В противном случае он устанавливается на имя файла, используемого для вызова bash, как указано в аргументе ноль.

Имеет ли знак минус особое значение? Есть ли что-то вроде /procили инструмент командной строки, который мог бы мне помочь найти соответствующий исполняемый файл?

* Глупый я. Конечно, $0 будет оцениваться как имя скрипта, как указано в руководстве

решение1

Знак минуса — это способ, которым система сообщает оболочке, что она вызывается как оболочка входа и должна быть source ~/.profile(для оболочек, совместимых с Bourne). Это справедливо для Linux, OSX и всех других unix. Скрипт не будет запущен в оболочке входа. Для скрипта $0— это имя файла скрипта (с полным путем или без него).

ДОБАВЛЕН: Страница руководства объясняет (почти все) различные случаи:

  • «Если bash вызывается с файлом команд, $0 устанавливается на имя этого файла». Это касается скриптов, выполняемых с помощью bash myscript, а также косвенного случая, когда скрипт выполняется напрямую и начинается с #!/bin/bash.

  • «Если bash запущен с опцией -c, то $0 устанавливается равным первому аргументу после строки, которая должна быть выполнена, если таковой присутствует». При -c, $0устанавливается равным тому, что явно указывает вызывающая сторона.

  • «В противном случае он устанавливается на имя файла, используемого для вызова bash, как указано в аргументе ноль». Оболочка входа попадает в этот случай: оболочка вызывается без аргументов, отличных от аргумента ноль, поэтому $0устанавливается на аргумент ноль. Это login, su, или любая другая программа, обрабатывающая вход, которая выбирает аргументы, которые она передала оболочке, и добавляет a -к аргументу ноль, чтобы сообщить оболочке, что это оболочка входа.

Возможно, стоит пояснить аргумент ноль. Когда программа выполняется, в конечном итоге execveпроисходит системный вызов. Этот системный вызов принимает три аргумента:

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

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

  3. другой массив строк, называемый средой.

При вызове программы из оболочки путем ввода myprogram foo bar, аргументами execveявляются:
    1. /usr/bin/myprogram(предполагается, что оболочка нашла именно это место myprogram)
    2. myprogram, foo, bar
    3. для каждой экспортированной переменной оболочки — имя переменной, за которым следует знак равенства и значение.

Нет общего способа найти имя исполняемого файла, который был передан execveиз работающей программы. В Linux он обычно доступен как /proc/$$/exeгде $$находится идентификатор процесса. Каждый unix делает его доступным для, psно внутренняя работа psсильно различается. Исполняемый файл может быть удален или переименован во время работы программы; в этом случае psможет сообщаться устаревшая информация или не сообщаться никакая информация.

решение2

От man bash:

exec [-cl] [-a имя] [команда [аргументы]]
Если указана команда, она заменяет оболочку. Новый процесс не создается. Аргументы становятся аргументами команды. Если указана опция -l, оболочка помещает дефис в начало нулевого аргумента, переданного команде. Это то, что делает login(1). ...

решение3

Я не уверен, что происходит с -bash, но если вы снова запустите bash в оболочке, то значение $0, похоже, будет в порядке.

Похоже, это что-то особенное, что делает OS X, потому что если запустить /usr/bin/login, который является скриптом по умолчанию, используемым программой терминала, то возникнет та же проблема с $0.

Связанный контент