Виклик сценарію за допомогою ./bla.sh vs. бла.ш


11

Чи може хтось пояснити мені, що оболонка робить у двох прикладах A) та B)? Він, очевидно, поводиться інакше, але я не можу дізнатися, чому вихід відрізняється.

Приклад:
Давайте матимемо скрипт у нашому поточному каталозі, названий bla.shлише однією командою:
echo ${0##/*} hello

А) Починається
як: ./bla.sh
дає:./bla.sh hello

B)
Починається як: . bla.sh
дає:-bash hello

Оскільки я використовую це в сценарії, другий вихід (через "-" перед -bash) вбиває команду. Звичайно, простий --перед тим, що ${...}допомогли, але я хотів би зрозуміти, що викликає вихід в першу чергу.
Я люблю баш. І vi [м]. Але я відволікаюсь…

Відповіді:


22
./bla.sh

Тут команда є ./bla.sh. Це змушує оболонку шукати виконуваний файл, названий bla.shу поточному каталозі, а потім попросити ядро ​​запустити його як звичайну програму, в окремий процес від оболонки. (Це не має значення , якщо bla.shце bashсценарій, perlабо pythonодин, або скомпільований двійковий файл.)


. bla.sh

Тут команда .(ака source) - вбудована команда вашої оболонки. Це змушує оболонку шукати файл, названий bla.shу системному шляху ($ PATH) та інтерпретувати вміст так, як ніби вони були введені вами; все це робиться в тому ж процесі , що і сама оболонка (і тому може впливати на внутрішній стан оболонки).

Це, звичайно, працює лише тоді, коли bla.shмістить команди для bashоболонки (якщо це та, яку ви зараз використовуєте), вона не працюватиме для perlсценаріїв чи чогось іншого.

(Це пояснено в help .і help sourceтеж.)


Як .і ./є абсолютно різними речами (команда проти частини шляху), їх, звичайно, можна поєднувати, використовуючи . ./bla.sh"джерело" файлу bla.shв поточному каталозі.


Зазвичай найкраще використовувати ./bla.shметод. Тільки ~/.bashrc, ~/.profileі такі файли, як правило , надходять, тому що вони повинні змінити поточну середу.


3
Більше того, якщо ви змінюєте bash середовище в bla.sh, ці зміни враховуються після. bla.sh, але не після ./bla.sh. це відбувається тому . bla.sh працює в контексті поточного bash, тоді як ./bla.sh працює як підпроцес.
mouviciel

1
Дивіться також mywiki.wooledge.org/BashFAQ/060 для деяких прикладів. Зверніть увагу, що sourceпсевдонім баш для ., а не навпаки, і sourceне працюватиме в інших оболонках.
mrucci

7

./<cmd>виконає <cmd>програму, яка знаходиться в поточному каталозі в новому (роздвоєному) процесі. Він повинен бути виконаним. А також читати це починається з #!.

. <cmd>змусить вашу поточну оболонку виконати скрипт оболонки, <cmd>який знаходиться у вашому $PATHабо поточному каталозі в поточному процесі оболонки. Він повинен бути читабельним. Це псевдонім для команди оболонки source.


-1 . <cmd>шукатиме програму в, $PATHа якщо її не знайдено, то вона шукатиме в поточному каталозі.
собака

@dogbane Правильно, я це виправив.
kmkaplan

FWIW, не всі оболонки шукатимуть cdd для пошуку скриптів. zsh (принаймні з конфігурацією, яку я маю) вимагає. ./cmd
bstpierre

1
@bstpierre Це, здається, рухається. У посиланні POSIX у мене йдеться про те, що "оболонка повинна використовувати шлях пошуку, визначений PATH" та "Деякі старі реалізації реалізували поточний каталог файлу, навіть якщо значення PATH забороняло його".
kmkaplan

1

./cmd використовує явний шлях ( ./- поточний dir) до виконуваного файлу. І зовсім не обов’язково, що це починається з #!.

. cmd- (ака source) - команда bash вбудована. Одне видиме відмінність виконання через sourceте, що воно може встановлювати / змінювати змінну середовища поточної оболонки.


точніше, sourceце лише псевдонім, .що базується на (що є стандартним)
user1686

Ти правий. Виправлено.
Леонід Вольницький
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.