Один и тот же скрипт, открытый тремя разными способами, дает три разных результата. Почему? [duplicate]

На этот вопрос уже есть ответ здесь:

У меня есть пример сценария (кредит идет к kos):

#!/bin/bash
cat <(cat /etc/lsb-release)

Я сохраняю этот сценарий как somename.sh в моем домашнем каталоге.

Теперь я пытаюсь открыть этот файл тремя разными способами:

sh somename.sh

bash somename.sh

./somename.sh

Итак, у меня два вопроса:

  1. Почему результаты для вышеуказанных команд разные, хотя они выполняют один и тот же сценарий?

    • sh выдает синтаксическую ошибку

    • bash выдает желаемый результат

    • . / выдает ошибку Permission Denied

  2. Почему необходимо давать разрешение на выполнение скрипта только при запуске скрипта с помощью ./ и не нужно в остальных случаях?

Заранее спасибо!

EDIT: Первая часть может быть похожа на дубликат, но у меня возник второй вопрос.

7
задан 13 April 2017 в 05:23

3 ответа

Поскольку мы обсудили в чате:

  1. sh script производит ошибку потому что, называя интерпретатор непосредственно (в этом случае sh) игнорирует хижину, и скрипт запущен в sh; sh не поддерживает замены процесса (<([...])), которые являются измами Bash, таким образом, выходы сценария на ошибке.

    bash script не производит ошибку, потому что несмотря на хижину, проигнорированную, скрипт все еще запущен в Bash, который поддерживает замены процесса.

    ./script производит ошибку потому что script не исполняемый файл.

  2. Запускать скрипт с ./ у Вас должен быть выполнить бит для Вашего пользовательского набора на сценарии, это - ограничение ОС.

    Таким образом, вопрос на самом деле: почему не делает bash script потребуйте наличия выполнить набора битов для Вашего пользователя на script?

    Поэтому при выполнении bash script сценарий прочитан Bash, и Bash имеет выполнить набор битов для Вашего пользователя.

    Это означает, что Bash, имея разрешение выполнить код, может "обойти" ограничение ОС на тот сценарий, и все потребности сценария состоят в том, чтобы быть читаемыми Bash.

8
ответ дан 23 November 2019 в 06:15
  • sh символьная ссылка на dash оболочка и производит Синтаксическую ошибку, потому что нет никакого <( . . .) в sh синтаксис. Это находится только в ударе (и в zsh и ksh, если я помню правильно).

  • удар производит желаемый результат, потому что это находится в правильном синтаксисе удара, ничто неправильно там

  • ./дает Разрешению Отклоненную ошибку, потому что Вы в основном говорите "Эй, оболочка, смотрите на полномочия того файла и смотрите на первую строку (та с #!/bin/bash) в моем текущий каталог и выясняете, как выполнить этот сценарий для меня". (примечание стороны: если бы у Вас был сценарий в месте, которое включено в Ваш $PATH переменная, то Вы просто работали бы myScriptName.sh и вот именно, но идея будет тем же, мы должны проверить исполнительные полномочия и какой интерпретатор использовать)

, Прежде чем Вы работали bash и dash и говорили им читать команды из файла. bash и dash исполняемый файл на этот раз, не сценарий. Сценарий теперь является источником команд, параметра. Читайте полномочия там всегда устанавливаются для всех пользователей, таким образом, оболочки считают его.

5
ответ дан 23 November 2019 в 06:15

В целом sh,ash,dash,bash,csh,tcsh,zsh... все оболочки с их собственными синтаксисами и характеристиками. Существует некоторая совместимость, но они ориентированы [1]: a bash оболочка выполнит a sh сценарий, но это не сказано наоборот. A sh вызов потребовал меньшего количества ресурсов, чем a bash один. Для одного единственного экземпляра это не проблема, для тысяч этого должен быть.

Способы выполниться.
Для выполнения файла как программы в соответствии с Linux, оба, если это - сценарий или скомпилированный, это должно быть установлено выполнить бит [2], и это должно быть включено в один из каталогов Вашего $PATH.

Если это - сценарий, это может быть передано как аргумент относительной оболочке (sh,bash...myfile.whatever): если это передается неправильной оболочке, можно получить не корректное поведение и если Вы удачливы ошибка; в этом случае это не должен быть исполняемый файл, потому что это похоже, если Вы писали строки, записанные в сценарии непосредственно в новой оболочке, которую Вы вызываете. Для выполнения в той же оболочке вместо этого, можно использовать source myfile или . myfile это - эквивалент для записи линию за линией в текущей оболочке содержания сценария.

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

  • В Вашем случае ./ средства только текущий каталог Вашей оболочки, также ~/myfile.whatever должен обратиться к файлу myfile.whatever в Вашем доме ~/ каталог.
  • Можно вызвать его от другого местоположения, например, с /home/$USER/dir/myfile.whatever.
  • Если этот файл в каталоге, включенном в Ваш путь, можно вызвать его с простым myfile.whatever.

В случае, что больше чем один исполняемый файл совместно использует то же имя, указывая полный путь, будет уверено, о котором Вы собираетесь выполниться. which mycommand может сказать Вам, какой будет выполняться теперь (функция, псевдоним, встроенный или первое, найденное в Вашем пути), но он не может сказать, какой будет выполняться в будущее время или от другого пользователя. Если Вы явно запишете полный путь, то Вы зафиксируете эту неоднозначность. Полезно выполнить определенную версию программы, когда установлены больше что один на том же времени... и избегать троянца. В сценарии всегда предлагается записать /bin/bash вместо bash.

3
ответ дан 23 November 2019 в 06:15

Другие вопросы по тегам:

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