Что такое расширение файла Bash?

84

Я написал сценарий bash в текстовом редакторе. Какое расширение я могу сохранить сценарий, чтобы он мог работать как сценарий bash? Я создал сценарий, который теоретически должен запускать ssh-сервер. Мне интересно, как заставить скрипт выполняться, когда я нажимаю на него. Я использую OS X 10.9.5.

Амедео
источник
4
Сценарий оболочки не требует какого-либо конкретного расширения. Просто выполните это какbash myscript
анубхава
7
Обычно это происходит .sh, но расширение вообще не обязательно. Linux - это не Windows. Программа, которая будет интерпретировать ваш скрипт, определяется в его первой строке, которой и должно быть #!/bin/bash. Он может даже включать параметры.
Havenard
1
@anubhava Как бы я мог запустить свой скрипт, если бы я просто дважды щелкнул по нему, а не набирал «bash myscript»
Амедео
2
@Amedeo, который будет заголовком вашего файла со строкой #!/bin/bash.
Havenard
4
Без расширений: расширения имен команд считаются вредоносными .
gniourf_gniourf

Ответы:

110

Не соглашаясь с другими ответами, существует общее соглашение об использовании .shрасширения для сценариев оболочки, но это соглашение не является полезным. Лучше вообще не использовать расширение. Преимущество возможности определить, что foo.shэто сценарий оболочки из-за его имени, минимально, и вы платите за него потерей гибкости.

Чтобы сделать скрипт bash исполняемым, он должен иметь строку shebang вверху:

#!/bin/bash

и используйте chmod +xкоманду, чтобы система распознала ее как исполняемый файл. Затем его необходимо установить в один из каталогов, перечисленных в вашем $PATH. Если сценарий вызван foo, вы можете выполнить его из приглашения оболочки, набрав foo. Или, если он находится в текущем каталоге (обычно для временных сценариев), вы можете ввести ./foo.

Ни оболочка, ни операционная система не обращают внимания на часть расширения имени файла. Это просто часть имени. И, не давая ему специального расширения, вы гарантируете, что любой (будь то пользователь или другой скрипт), который его использует, не должен заботиться о том, как это было реализовано, будь то сценарий оболочки (sh, bash, csh или что-то еще) , сценарий Perl, Python или Awk или исполняемый двоичный файл. Система специально разработана таким образом, чтобы можно было вызывать интерпретируемый скрипт или двоичный исполняемый файл, не зная и не заботясь о том, как он реализован.

UNIX-подобные системы начинались с чисто текстового интерфейса командной строки. Позже были добавлены графические интерфейсы, такие как KDE и Gnome. В настольной системе с графическим пользовательским интерфейсом вы обычно можете запустить программу (опять же, будь то скрипт или исполняемый файл), например, дважды щелкнув значок, который ссылается на него. Обычно это отбрасывает любой вывод, который программа могла бы напечатать, и не позволяет передавать аргументы командной строки; он гораздо менее гибкий, чем запуск из командной строки. Но для некоторых программ (в основном клиентов с графическим интерфейсом) это может быть удобнее.

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

(Некоторые инструменты делают обратить внимание на расширения файлов , например, компиляторы обычно используют расширение для определения языка код написан в:. .cДля C, .cpp. Для C ++, и т.д. Это соглашение не относится к исполняемым файлам)

Имейте в виду, что UNIX (и UNIX-подобные системы) не являются Windows. MS Windows обычно использует расширение файла, чтобы определить, как его открыть / запустить. У двоичных исполняемых файлов должно быть .exeрасширение. Если в Windows установлена ​​UNIX-подобная оболочка, вы можете настроить Windows на распознавание .shрасширения как сценарий оболочки и использование оболочки для его открытия; В Windows нет #!соглашения.

Кейт Томпсон
источник
2
Я стремлюсь к тому, что вы упомянули в четвертом абзаце. Запуск моего скрипта при щелчке по значку, который к нему относится.
Амедео
2
@Amedeo: Тогда это зависит от среды вашего рабочего стола. В том, что я использую (Cinnamon в Ubuntu), двойной щелчок по значку исполняемого скрипта предлагает мне запустить его в терминале, отобразить в редакторе или запустить без терминала. Это происходит независимо от расширения файла.
Кейт Томпсон
4
(Necro) Если вы опустите расширение, у вас не может быть одноименной папки. Так, например, у вас есть deploy.sh(или deploy.bash) и папка deployс дополнительной логикой развертывания. Если вы просто переименуете скрипт, deployэто вызовет конфликт имен. Иное наименование файла или папки ухудшает управляемость и, возможно, сортировку файлов (ls в редакторах и т. Д.). Конечно, в конечном итоге решающим фактором является шебанг. Но расширения файлов действительно занимают свое законное место.
Кафосо
2
@Kafoso: Я не думаю, что когда-либо чувствовал необходимость иметь сценарий и каталог с тем же именем. Если бы я это сделал, я мог бы вызвать каталог Deploy, хотя это может вызвать проблемы при копировании в файловую систему без учета регистра.
Кейт Томпсон
2
На Mac двойной щелчок по файлам всегда открывает их в приложении по умолчанию. Таким образом, полезно иметь .shрасширение, чтобы сценарий открывался в желаемом редакторе. Если вы хотите запускать скрипт при двойном щелчке, дайте ему .commandрасширение, и он запустится в Терминале при двойном щелчке.
BallpointBen
18

Вам не нужно никакого расширения (или вы можете выбрать произвольное, но .shэто полезное соглашение).

Вы должны начать свой сценарий с #!/bin/bash (эта первая строка понимается системным вызовом execve (2) ), и вы должны сделать свой файл исполняемым с помощью chmod u+x. поэтому, если ваш скрипт находится в каком-то файле, $HOME/somedir/somescriptname.shвам нужно ввести один раз

 chmod u+x  $HOME/somedir/somescriptname.sh

в терминале. См. Chmod (1) для команды и chmod (2) для системного вызова.

Если вы не вводите полный путь к файлу, вам следует поместить этот файл в какой-либо каталог, указанный в вашем PATH (см. Environment (7) и execvp (3) ), который вы можете установить постоянно в вашем, ~/.bashrcесли ваша оболочка входа в систему bash)

Кстати, вы можете написать свой скрипт на другом языке, например, на Python, запустив его с помощью #!/usr/bin/python, или в Ocaml, запустив его с #!/usr/bin/ocaml...

Выполнение вашего скрипта двойным щелчком (на чем? Вы не сказали!) - это проблема среды рабочего стола и может быть специфичной для рабочего стола (может отличаться от Kde, Mate, Gnome, .... или IceWM или RatPoison). Возможно, чтение спецификации EWMH поможет вам лучше понять.

Возможно, создание исполняемого файла сценария с помощью chmodможет сделать его интерактивным на рабочем столе (по-видимому, Quartz в MacOSX). Но тогда вам, вероятно, следует сделать так, чтобы он давал визуальную обратную связь.

А на некоторых компьютерах нет рабочего стола, включая ваш собственный, когда вы получаете доступ к нему удаленно с помощью ssh .

Я не верю, что запускать сценарий оболочки, щелкнув. Вы, вероятно, захотите предоставить аргументы своему сценарию оболочки (и как бы вы это сделали, щелкнув?), И вам следует позаботиться о его выводе. Если вы можете написать сценарий оболочки, вы можете использовать интерактивную оболочку в терминале. Это лучший и наиболее естественный способ использования скрипта. Хорошие интерактивные оболочки (например, zsh или fish или, возможно, недавняя bash) имеют восхитительные и настраиваемые средства автозаполнения , и вам не придется много печатать (научитесь пользоваться tabклавишами клавиатуры). Кроме того, скрипты и программы часто являются частями составных команд (конвейеров и т. Д.).

PS. Я использую Unix с 1986 года, а Linux с 1993 года. Я никогда не запускал свои собственные программы или сценарии, щелкая. Почему я должен?

Василий Старынкевич
источник
3
Итак, я создал свой сценарий в текстовом редакторе. Сохраняю файл на рабочий стол. Когда я нажимаю на свой сценарий, сохраненный на моем рабочем столе, я хочу, чтобы он действительно запускался при нажатии на него.
Амедео
6
Я не знаю, какой у вас рабочий стол (KDE, Gnome, MATE, ...). Я настоятельно рекомендую вам использовать командную строку в терминале, особенно для запуска ваших скриптов (вы, вероятно, захотите дать им некоторые аргументы; как бы вы это сделали на рабочем столе?). Если вы умеете кодировать сценарий оболочки, вы сможете использовать оболочку в интерактивном режиме в терминале,
Базиль Старынкевич,
2
Я хочу сказать, что если вы пишете сценарий оболочки, вы должны привыкнуть использовать командную строку в терминале.
Василий Старынкевич
2
Я так понимаю, я работаю над проектом. Я хочу, чтобы сценарий выполнялся после нажатия. Я пытаюсь избежать использования терминала для запуска скрипта.
Амедео
3
Я бы использовал chmod +xвместо chmod u+x, если нет особой причины ограничить выполнение только владельцем.
Кейт Томпсон
2

просто .sh .

Запускаем скрипт так:

./script.sh

РЕДАКТИРОВАТЬ: Как сказал Анубхава, расширение на самом деле не имеет значения. Но по организационным причинам все же рекомендуется использовать расширения.

Марк Антон Дамен
источник
6
Если вы запускаете сценарий, обычно нет причин беспокоиться о том, на чем он написан. Сценарий bash и исполняемый двоичный файл выполняются одинаково. Добавление .shсуффикса к исполняемому сценарию, как правило, бесполезно.
Кейт Томпсон
1
да, но, как я сказал в своей редакции - это соглашение об организации сценариев - не более того ?!
Марк Антон Дамен
5
Я действительно вижу много скриптов с .shрасширением (и меньше с .bashрасширением), но я не уверен, что это вообще полезно. Если я назову сценарий foo.shи позже решу заново реализовать его на Perl, я могу либо изменить имя (и отредактировать все, что его использует), либо оставить его с вводящим в заблуждение расширением. Если я его назову foo, у меня нет этой проблемы.
Кейт Томпсон
@KeithThompson Я сам могу придумать, как использовать, мне все равно, на чем написан сценарий. Я не могу говорить от имени Perl, но мне было бы очень важно, написан ли сценарий на Python или Bash. В общем, я могу предположить, что сценарий Bash будет работать, несмотря ни на что, но сценарии Python имеют зависимости, а Python 2 и Python 3 несовместимы друг с другом. Я также думаю, что важно различать скомпилированные двоичные файлы и сценарии (которые не имеют расширений), потому что у них разные потребности в зависимости (например, двоичный файл может нуждаться в библиотеках и быть скомпилирован для AMD64 и работать только с этим).
jrh
@jrh Конечно, иногда это имеет значение (и это можно понять, запустив head -1 script.fooили file script.foo). Но если все установлено и настроено правильно, в 99% случаев я просто хочу, чтобы команда выполняла то, что она должна делать. Для меня это не оправдывает необходимость знать суффикс .pyили .bashкаждый раз, когда я его запускаю.
Кейт Томпсон,
2

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

Если вы используете Mac и хотите иметь возможность запускать скрипт, дважды щелкнув его, вам необходимо использовать .commandрасширение. Так же, как и раньше, сделайте файл исполняемым с расширением chmod -x.

Как было отмечено ранее, на самом деле это не так уж и полезно.

w_jay
источник
1

TL; DR - Если пользователь (не обязательно разработчик) скрипта использует графический интерфейс, это зависит от того, какой файловый браузер он использует. Finder MacOS потребует .shрасширения для выполнения скрипта. Gnome Nautilus, однако, распознает правильно оформленные скрипты с .shрасширением или без него .

Я знаю, что уже несколько раз говорилось о причинах и против использования расширений в сценариях bash, но не так много, почему или почему не использовать расширения, но у меня есть то, что я считаю хорошим практическим правилом.

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

Если вы относитесь к типу людей, которые в основном выполняют всю или большую часть своей работы в терминале, не беспокойтесь о том, чтобы добавлять какие-либо расширения в свои сценарии bash. Они бесполезны в терминале, если вы уже настроили свой ~/.bashrcфайл, чтобы визуально отличать скрипты от каталогов.

Редактировать:

В браузере файлов Gnome Nautilus с 4 тестовыми файлами (каждый с разрешениями, предоставленными для файла, который должен быть запущен) с глупо простой командой bash, чтобы открыть окно терминала ( gnome-terminal):

  1. Файл без расширения с #!/bin/bashв первой строке.

    Он работал двойным щелчком по файлу.

  2. Файл с .shрасширением #!/bin/bashв первой строке.

    Он работал двойным щелчком по файлу.

  3. Файл без расширения с НЕТ #!/bin/bashв первой строке.

    Он работал двойным щелчком по файлу ... технически, но графический интерфейс не указывал, что это был сценарий оболочки. Он сказал, что это был просто текстовый файл.

  4. Файл с .shрасширением NO #!/bin/bashв первой строке.

    Он работал двойным щелчком по файлу.

Однако, как мудро заметил Кейт Томпсон в комментариях к этому ответу, полагаясь на использование .shрасширения вместо bash shebang в первой строке файла ( #!/bin/bash), это может вызвать проблемы.

Однако, как я помню, когда я ранее использовал MacOS, даже правильно отредактированные (это слово?) Сценарии bash без .shрасширения не могли быть запущены из графического интерфейса на MacOS. Я хотел бы, чтобы кто-нибудь поправил меня по этому поводу в комментариях. Если это правда, это докажет, что существует хотя бы один файловый браузер, для которого .shрасширение имеет значение.

Райан Харт
источник
Какой файловый браузер GUI вы используете (или, что более важно, что используют ваши пользователи)? Использует ли расширение, чтобы решить, как запустить сценарий?
Кейт Томпсон
Ну, платформа, на которой у меня больше всего опыта, - это MacOS. В Finder пользователь решает, какие приложения с каким расширением связать. Теперь я нахожусь в Linux, использую Gnome, но у меня нет времени экспериментировать, как файловый браузер Gnome Nautilus взаимодействует с файлами без расширения.
Райан Харт
Если у вас есть исполняемый скрипт с .shсуффиксом и #!/bin/bashв первой строке, будет ли браузер файлов графического интерфейса использовать shдля его вызова (игнорируя shebang)? Если так, это может вызвать некоторые проблемы. (Ответ может быть разным для разных браузеров.)
Кейт Томпсон
Хорошие моменты там. Я обновил свой ответ выше с помощью некоторых фактических тестов, которые я только что провел.
Райан Харт
Интересно, но ... Вы сказали, что "сработало". Для каждого из 4 тестовых случаев было бы хорошо знать, вызвал ли он его с помощью /bin/bashили /bin/sh(последнее значение по умолчанию для сценария без shebang). Если /bin/shэто символическая ссылка на /bin/bash(что довольно часто), то вы можете определить это, посмотрев на значение $0. (Кроме того, если bash вызывается по мере shего установки POSIXLY_CORRECT=y.)
Кейт Томпсон