bash myscript.sh работает в bash, но первая строка: #! / usr / bin / sh

У меня есть сценарий, похожий на следующий:

#!/usr/bin/sh var="ABC" if [ $var == "ABC" ] then echo True else echo False fi 

Выше код не работает в Solaris Sparc и Solaris X64. Он показывает == undefined. Над кодом работает отлично Если я заменил == с = .

Странная вещь: если я бежал над кодом без каких-либо изменений, следуя методу, который он работает.

 #bash test.sh 

По моему мнению, сценарий не должен работать даже с bash, так как в начале скрипта я использую #!/bin/sh который не поддерживает == как оператор сравнения.

Может кто-нибудь объяснить, почему он работает, когда я запускаю сценарий, как указано выше.

Примечание. Я знаю, что bash распознает == и = .

Первая строка скрипта называется #! линии (иногда называемой строкой «shebang» ).

Он используется только тогда, когда скрипт выполняется непосредственно, как в

 ./test.sh 

объяснение

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

Когда вы запускаете

 ./test.sh 

операционная система видит, что первые два байта ./test.sh являются #! , поэтому он знает, что программа является скриптом.

Он читает остальную часть строки, чтобы увидеть, какую оболочку 1 она должна использовать для запуска скрипта. В этом случае остальная часть строки равна /usr/bin/sh , поэтому она запускает /usr/bin/sh test.sh 2 .

Когда вы запускаете

 bash test.sh 

он находит bash в /usr/bin/bash 3 . Он видит, что первые два байта /usr/bin/bash не #! , поэтому он запускает /usr/bin/bash test.sh даже не глядя на первую строку test.sh.

В обоих случаях sh и bash фактически игнорируют строку shebang, потому что любая строка, начинающаяся с # является комментарием. # Имеет только этот волшебный эффект из-за операционной системы, а не оболочки.

Больше информации:

  • #!
  • Вся история на #! / USR / бен / КШ
  • Панель управления Solaris
  • Linux execve man page

Примечания:

  1. Фактически, это может быть любая программа, она не должна быть оболочкой.
  2. На самом деле это больше похоже на execl("./test.sh", "/usr/bin/sh", "./test.sh", NULL) .
  3. /bin/sh в большинстве систем Linux, но вопрос был о Solaris.

Запуск скрипта с bash (запуск bash test.sh ) означает, что скрипт интерпретируется с помощью bash, а не оболочки Bourne (/ bin / sh). Вот почему это работает. Bash игнорирует #! / Bin / sh, потому что это комментарий. ./test.sh только программный загрузчик вашей ОС, если вы запускаете сценарий оболочки без bash (например, запускаете ./test.sh ).