Gọi một kịch bản với ./bla.sh vs. bla.sh


11

Bất cứ ai có thể giải thích cho tôi những gì vỏ làm trong hai ví dụ A) và B) dưới đây? Nó rõ ràng hành xử khác nhau, nhưng tôi không thể tìm ra lý do tại sao đầu ra khác nhau.

Ví dụ:
Chúng ta có một tập lệnh trong thư mục hiện tại của chúng tôi được đặt tên bla.shchỉ bằng một lệnh:
echo ${0##/*} hello

A)
Bắt đầu như: ./bla.sh
cho:./bla.sh hello

B)
Bắt đầu như: . bla.sh
cho:-bash hello

Vì tôi sử dụng điều này trong một tập lệnh, đầu ra thứ hai (vì dấu "-" phía trước -bash) sẽ giết lệnh. Tất nhiên, một đơn giản --trước khi được ${...}giúp đỡ, nhưng tôi rất muốn hiểu những gì gây ra đầu ra ở nơi đầu tiên.
Tôi thích bash. Và vi [m]. Nhưng tôi lạc đề…

Câu trả lời:


22
./bla.sh

Đây, lệnh là ./bla.sh. Điều này làm cho shell tìm kiếm một tệp thực thi có tên bla.shtrong thư mục hiện tại, sau đó yêu cầu kernel chạy nó như một chương trình bình thường, trong một quy trình riêng biệt với shell. (Không thành vấn đề nếu bla.shbashtập lệnh, tập lệnh một perlhoặc pythontập tin nhị phân được biên dịch.)


. bla.sh

Ở đây, lệnh là .(aka source), một lệnh tích hợp trong shell của bạn. Nó làm cho trình bao tìm kiếm một tệp có tên bla.shtrong đường dẫn hệ thống ($ PATH) và diễn giải nội dung như thể chúng được bạn gõ vào; tất cả điều này được thực hiện trong cùng một quy trình như chính vỏ (và do đó có thể ảnh hưởng đến trạng thái bên trong của vỏ).

Điều này tất nhiên chỉ hoạt động khi bla.shchứa các lệnh cho trình bashbao (nếu đó là lệnh bạn hiện đang sử dụng), nó sẽ không hoạt động cho perlcác tập lệnh hoặc bất cứ điều gì khác.

(Điều này được giải thích trong help .help sourcequá.)


Như ../là những thứ hoàn toàn khác nhau (một lệnh so với một phần của đường dẫn), tất nhiên chúng có thể được kết hợp - sử dụng . ./bla.shsẽ "nguồn" một tệp bla.shtrong thư mục hiện tại.


Thông thường tốt nhất là sử dụng ./bla.shphương pháp. Chỉ ~/.bashrc, ~/.profilevà các tập tin như vậy thường có nguồn gốc, bởi vì họ có nghĩa vụ phải thay đổi môi trường hiện tại.


3
Hơn nữa, nếu bạn thay đổi môi trường bash trong bla.sh, những thay đổi này sẽ được tính đến sau. bla.sh nhưng không phải sau ./bla.sh. đó là bởi vì bla.sh chạy trong ngữ cảnh của bash hiện tại trong khi ./bla.sh chạy như một quy trình con.
mouviciel

1
Xem thêm mywiki.wooledge.org/BashFAQ/060 để biết một số ví dụ. Lưu ý rằng đó sourcelà một bí danh bash cho ., không phải ngược lại và sourcesẽ không hoạt động trong các shell khác.
mrucci

7

./<cmd>sẽ thực thi <cmd>chương trình nằm trong thư mục hiện tại trong một quy trình (rẽ nhánh) mới. Nó phải được thực thi. Và cũng có thể đọc nó bắt đầu với #!.

. <cmd>sẽ làm cho trình bao hiện tại của bạn thực thi tập lệnh shell <cmd>nằm trong $PATHthư mục hiện tại của bạn hoặc trong quy trình trình bao hiện tại . Nó phải được đọc. Nó là một bí danh cho lệnh shell source.


-1 . <cmd>sẽ tìm chương trình trong $PATHvà nếu không tìm thấy THÌ nó sẽ tìm trong thư mục hiện tại.
dogbane

@dogbane Đúng rồi, tôi đã sửa cái này.
kmkaplan

FWIW, không phải tất cả các shell sẽ tìm kiếm cwd cho các tập lệnh có nguồn gốc. zsh (ít nhất là với cấu hình tôi có) yêu cầu. ./cmd
bstpierre

1
@bstpierre Đây dường như là một mặt bằng di chuyển. Tham chiếu POSIX mà tôi đã nói rằng, vỏ Shell sẽ sử dụng đường dẫn tìm kiếm được chỉ định bởi PATH và một số triển khai cũ hơn đã tìm kiếm thư mục hiện tại cho tệp, ngay cả khi giá trị của PATH không cho phép.
kmkaplan

1

./cmd sử dụng đường dẫn rõ ràng ( ./- thư mục hiện tại) để thực thi. Và nó không cần thiết mà nó bắt đầu với #!.

. cmd- (aka source) - lệnh bash dựng sẵn. Một sự khác biệt có thể nhìn thấy khi thực hiện thông qua sourcelà nó có thể đặt / sửa đổi biến môi trường của shell hiện tại.


chính xác hơn, sourcelà một bí danh chỉ dành cho bash .(là tiêu chuẩn)
user1686

Bạn đúng rồi. Đã sửa.
Leonid Volnitsky
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.