Що таке розширення файлу Bash?


84

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


4
Сценарій оболонки не вимагає якогось конкретного розширення. Просто виконайте це якbash myscript
anubhava

7
Це зазвичай .sh, але розширення взагалі не вимагається. Linux - це не Windows. Програма, яка повинна інтерпретувати ваш сценарій, визначається в першому рядку, що має бути #!/bin/bash. Він може включати навіть параметри.
Havenard

1
@anubhava Як би я змусив свій скрипт виконатись, якби я просто двічі клацнув на ньому, а насправді не вводив "bash myscript"
Амедео

2
@Amedeo, який буде заголовок вашого файлу з рядком #!/bin/bash.
Havenard

Відповіді:


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: Тоді це залежить від робочого середовища. В тому, який я використовую (Кориця під Ubuntu), подвійне клацання на піктограмі виконуваного сценарію спонукає мене запустити його в терміналі, відобразити в редакторі або запустити без терміналу. Це робиться незалежно від розширення файлу.
Кіт Томпсон,

4
(Necro) Якщо ви пропустите розширення, ви не зможете мати папку з тим самим іменем. Так, наприклад, у вас є deploy.sh(або deploy.bash) і папка deployз додатковою логікою розгортання. Якщо перейменувати сценарій просто, deployце призведе до конфлікту імен. Присвоєння імені файлу або папці по-різному шкодить керованості та, можливо, сортуванню файлів ( lsу редакторах тощо). Звичайно, шебанг - зрештою - визначальний фактор. Але розширення файлів мають своє гідне місце.
Кафосо

2
@Kafoso: Я не думаю, що я коли-небудь відчував потребу мати скрипт і каталог з однаковим ім'ям. Якби я це зробив, я міг би зателефонувати до каталогу Deploy, хоча це може спричинити проблеми під час копіювання до файлової системи, що не враховує регістр.
Кіт Томпсон,

2
На Mac подвійне клацання файлів завжди відкриває їх у програмі за замовчуванням. Тому корисно мати .shрозширення, щоб сценарій відкривався у потрібному редакторі. Якщо ви хочете запустити скрипт при подвійному клацанні, надайте йому .commandрозширення, і він запуститься в терміналі при подвійному клацанні.
BallpointBen

18

Вам не потрібно будь-яке розширення (або ви можете вибрати довільне, але .shце корисна умова).

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

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

в терміналі. Див CHMOD (1) для команди і CHMOD (2) для системного виклику.

Якщо ви не вводите весь шлях до файлу, вам слід помістити цей файл у якийсь каталог, згаданий у вашому PATH(див. Середовище (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, ...). Я настійно запрошую вас використовувати командний рядок у терміналі, особливо для запуску своїх скриптів (ви, мабуть, хочете навести їм деякі аргументи; як би ви це зробили на робочому столі?). Якщо ви вмієте кодувати сценарій оболонки, ви повинні мати можливість використовувати оболонку в інтерактивному режимі в терміналі
Basile Starynkevitch

2
Моя думка полягає в тому, що якщо ви кодуєте сценарій оболонки, вам слід взяти звичку використовувати командний рядок у терміналі.
Василь Старинкевич

2
Я розумію, це для проекту, над яким я працюю. Я хочу, щоб сценарій виконувався після натискання. Я намагаюся уникати використання терміналу для запуску сценарію.
Амедео

3
Я chmod +xскоріше скористався цим , крім chmod u+xвипадків, коли існує конкретна причина обмежити виконання власником.
Кіт Томпсон,

2

просто .sh.

Запустіть сценарій так:

./script.sh

EDIT: Як сказав анубхава, розширення насправді не має значення. Але з організаційних причин все-таки рекомендується використовувати розширення.


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.

Як зазначалося раніше, це насправді не так корисно.


1

TL; DR - Якщо користувач (не обов’язково розробник) сценарію використовує графічний інтерфейс, це залежить від того, який браузер файлів він використовує. Finder MacOS потребує .shрозширення для виконання сценарію. Однак Gnome Nautilus розпізнає належним чином оброблені сценарії з .shрозширенням або без нього .

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

Якщо ви тип, який заходить і виходить з bash і використовує термінал загалом, або розробляє інструмент для когось іншого, хто не використовує термінал, додайте .shрозширення до ваших сценаріїв bash. Таким чином, користувачі цього сценарію мають можливість подвійного клацання на цьому файлі в браузері файлів графічного інтерфейсу для запуску сценарію.

Якщо ви той тип, хто в основному виконує всю або більшу частину вашої роботи в терміналі, не турбуйтеся про те, щоб додати будь-яке розширення до ваших скриптів bash. Вони не мали б жодної мети в терміналі, припускаючи, що ви вже налаштували свій ~/.bashrcфайл для візуального розрізнення скриптів від каталогів.

Редагувати:

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

  1. Файл із розширенням NO із #!/bin/bashпершим рядком.

    Це спрацювало подвійним клацанням на файлі.

  2. Файл із .shрозширенням із #!/bin/bashпершого рядка.

    Це спрацювало подвійним клацанням на файлі.

  3. Файл із розширенням NO із номером NO #!/bin/bashу першому рядку.

    Це працювало, двічі клацнувши файл ... технічно, але графічний інтерфейс не вказував, що це скрипт оболонки. Там сказали, що це просто текстовий файл.

  4. Файл із .shрозширенням із номером NO #!/bin/bashу першому рядку.

    Це спрацювало подвійним клацанням на файлі.

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

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


Яким браузером файлів графічного інтерфейсу ви користуєтесь (або, що більш важливо, чим користуються ваші користувачі)? Чи використовує воно розширення для вирішення запуску сценарію?
Кіт Томпсон,

Ну, платформа, на якій я маю найбільший досвід - це MacOS. У Finder користувач вирішує, які програми пов’язувати з яким розширенням. Зараз я працюю на Linux за допомогою Gnome, але мені не вдалося експериментувати, як браузер файлів Nautilus Gnome взаємодіє з файлами без розширення.
Райан Харт,

Якщо у вас є виконуваний сценарій із .shсуфіксом і #!/bin/bashв першому рядку, чи буде браузер файлів GUI використовувати його shдля його виклику (ігноруючи shebang)? Якщо так, це може спричинити деякі проблеми. (Відповідь може бути різною для різних браузерів.)
Кіт Томпсон,

Хороші бали там. Я оновив свою відповідь вище деяким фактичним тестуванням, яке я провів зараз.
Райан Харт,

Цікаво, але ... Ви сказали, що це "спрацювало". Для кожного з 4 тестових випадків було б добре знати, чи він викликав його за допомогою /bin/bashабо /bin/sh(останнє є типовим для сценарію без шебанга). Якщо /bin/shє символічним посиланням на /bin/bash(що є досить поширеним явищем), тоді ви можете сказати, подивившись на значення $0. (Крім того, якщо баш викликається, коли shвін встановлюється POSIXLY_CORRECT=y.)
Кіт Томпсон,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.