Как запустить скрипт оболочки на консоли Unix или Mac?


507

Я знаю это, забудь об этом и заново изучи. Время записать это.


15
написание поезда с голосами до станции репутации
— DivideByZer0

не собираюсь возражать, просто чтобы восхититься этой удивительной ошибкой, которую вы там совершили!
— BRHSM

Ответы:


942

Чтобы запустить неисполняемый shскрипт, используйте:

sh myscript

Чтобы запустить неисполняемый bashскрипт, используйте:

bash myscript

Запустить исполняемый файл (любой файл с разрешением на выполнение); вы просто указываете его по пути:

/foo/bar
/bin/bar
./bar

Чтобы сделать скрипт исполняемым, дайте ему необходимое разрешение:

chmod +x bar
./bar

Когда файл исполняемый, ядро отвечает за выяснение того, как его выполнить. Для недвоичных файлов это делается путем просмотра первой строки файла. Он должен содержать hashbang:

#! /usr/bin/env bash

Hashbang сообщает ядру, какую программу запустить (в этом случае команда запускается /usr/bin/envс аргументом bash). Затем сценарий передается программе (в качестве второго аргумента) вместе со всеми аргументами, которые вы указали сценарию в качестве последующих аргументов.

Это означает, что каждый исполняемый скрипт должен иметь хэш-банг . Если это не так, вы не сообщаете ядру, что это такое , и поэтому ядро ​​не знает, какую программу использовать для его интерпретации. Это может быть bash, perl, python, sh, или что - то еще. (На самом деле ядро ​​часто использует оболочку пользователя по умолчанию для интерпретации файла, что очень опасно, потому что он может вообще не быть правильным интерпретатором или может анализировать некоторые из них, но с небольшими поведенческими различиями, такими как дело между shа bash).

Записка о /usr/bin/env

Чаще всего вы увидите такие хэш-челки:

#!/bin/bash

В результате ядро ​​запустит программу /bin/bashдля интерпретации скрипта. К сожалению, bashне всегда поставляется по умолчанию, и это не всегда доступно в /bin. В то время как на машинах Linux это обычно так, есть ряд других машин POSIX, которые bashпоставляются в различных местах, таких как /usr/xpg/bin/bashили /usr/local/bin/bash.

Поэтому для написания переносимого скрипта bash мы не можем полагаться на жесткое программирование местоположения bashпрограммы. POSIX уже имеет механизм для решения , что: PATH. Идея состоит в том, что вы устанавливаете свои программы в один из имеющихся каталогов, PATHи система должна быть в состоянии найти вашу программу, когда вы хотите запустить ее по имени.

К сожалению, вы не можете просто сделать это:

#!bash

Ядро не будет (некоторые могут) PATHискать вас. Существует программа, которая может выполнить PATHпоиск для вас, но она называется env. К счастью, почти во всех системах установлена envпрограмма /usr/bin. Поэтому мы начинаем envиспользовать жестко заданный путь, который затем выполняет PATHпоиск bashи запускает его, чтобы он мог интерпретировать ваш сценарий:

#!/usr/bin/env bash

У этого подхода есть один недостаток: согласно POSIX, hashbang может иметь один аргумент . В этом случае мы используем bashв качестве аргумента envпрограмму. Это означает, что у нас нет места для передачи аргументов bash. Так что нет способа преобразовать что-то вроде #!/bin/bash -exuэтой схемы. Вы должны будете поставить set -exuпосле hashbang вместо этого.

Этот подход также имеет еще одно преимущество: некоторые системы могут поставляться с /bin/bash, но пользователю это может не понравиться, он может обнаружить, что он неисправен или устарел, и, возможно, установил свою собственную в bashдругом месте. Это часто имеет место в OS X (Mac), где Apple поставляет устаревшую версию, /bin/bashа пользователи устанавливают /usr/local/bin/bashновейшую версию, используя что-то вроде Homebrew. Когда вы используете envподход, который выполняет PATHпоиск, вы принимаете во внимание предпочтения пользователя и используете его предпочтительный bash по сравнению с тем, который поставляется с его системой.


66
Спасибо, что нашли время написать хороший ответ на простой вопрос.
— PA

5
Если бы я использовал в zshкачестве своей оболочки, я бы использовал hashbang #! /usr/bin/env zsh?
— stefmikhail

6
@stefmikhail: Неважно, какой интерпретатор оболочки вы используете для вызова скрипта, вы должны использовать, #! /usr/bin/env zshесли (и только если) код внутри скрипта должен выполняться оболочкой Z.
— Johnsyweb

1
+1 за объяснение. Я склонен забывать, но знание значения команды поможет мне вспомнить.
— красавица Надар

2
@Carpetsmoker Это правильно и не ограничивается хэшбэнгом. Скрипты bash всегда должны использовать окончания строк UNIX, иначе к последнему аргументу каждой команды будет добавлен \ r, как и в имени команды hashbang.
— июня

80

Чтобы запустить shell-скрипт 'file.sh':

sh file.sh

bash file.sh

Другой вариант - установить разрешение на выполнение с помощью команды chmod:

chmod +x file.sh

Теперь запустите файл .sh следующим образом:

./file.sh

16

Для оболочки Борн:

sh myscript.sh

Для Баш:

bash myscript.sh

Спасибо за ответ на этот довольно очевидный вопрос. Для такого парня из Mac, как я, легко забыть старые команды Unix между кругами.
— PA

10

Если вы хотите, чтобы скрипт выполнялся в текущей оболочке (например, вы хотите, чтобы он мог влиять на ваш каталог или среду), вы должны сказать:

. /path/to/script.sh

или

source /path/to/script.sh

Обратите внимание, что /path/to/script.shможет быть относительным, например, . bin/script.shзапускает script.shв binкаталоге в текущем каталоге.


7
Будьте очень осторожны при поиске или расстановке точек с относительными путями. Вы всегда должны начинать их с ./ Если вы этого не сделаете, а относительный путь не содержит косых черт, вы будете искать что-то в PATH, ДО чего-то в текущем каталоге! Очень опасно для злоупотреблений.
— lhunath

0

Сначала дайте разрешение на исполнение: -
chmod +x script_name

  1. Если скрипт не является исполняемым: -
    Для запуска файла скрипта sh: -
    sh script_name
    Для запуска файла скрипта bash: -
    bash script_name
  2. Если скрипт исполняемый: -
    ./script_name

ПРИМЕЧАНИЕ : -вы можете проверить, является ли файл исполняемым или нет, используя 'ls -a'


0

Расширение файла .command назначено Terminal.app. Двойной щелчок на любом файле .command запустит его.


0

Небольшое дополнение, чтобы запустить интерпретатор из той же папки, все еще используя #! Hashbang в скриптах.

В качестве примера, исполняемый файл php7.2, скопированный из / usr / bin, находится в папке в сценарии приветствия .

#!./php7.2
<?php

echo "Hello!"; 

Чтобы запустить это:

./hello

Которые ведут себя так же, как:

./php7.2 hello
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.