Các . executable
cú pháp không làm việc với bất kỳ chỉ thực thi (hoặc hiện nó?). Thay vào đó, đó là một bí danh cho bash tích source
hợp. Vì vậy, sự khác biệt chủ yếu liên quan đến các tập lệnh bash, và sự thật là chúng là những thứ hoàn toàn khác nhau :)
./executable
yêu cầu chạy thực thi "bình thường". ./
là một tham chiếu tương đối đến đường dẫn hiện tại. Điều này tránh việc trình bao (bash) cố gắng xác định vị trí thực thi trong một thư mục trong thư mục của nó $PATH
(điều này sẽ làm nếu bạn không chỉ định một đường dẫn nào bằng lệnh). Lý do tại sao bạn không thể làm executable
là một trong những bảo mật; hãy tưởng tượng bạn giải nén một kho lưu trữ mà bạn đã tải xuống và nó chứa một phiên bản độc hại của ls
. Nếu nó chạy trực tiếp từ thư mục hiện tại của bạn, bạn sẽ chạy phiên bản đó mà không nhận ra.
Mặt khác, . executable
đang nói "nguồn một tệp có tên executable
". Vì bạn trực tiếp đặt tên tệp và nó thực sự không phải là tệp thực thi, nên hạn chế bảo mật cho $ PATH không áp dụng. Tìm nguồn cung ứng sẽ chỉ "chạy" (hoặc dường như chạy) các kịch bản shell. Những gì nó làm là:
source filename [arguments]
Read and execute commands from filename in the current shell
environment and return the exit status of the last command exe‐
cuted from filename.
Vậy ... thực sự có gì khác biệt giữa thực thi và tìm nguồn cung ứng? Giả sử cùng một kịch bản shell, thực thi nó ( ./script
) sẽ sinh ra một shell mới, chạy script bên trong shell đó và khi script thoát ra, đóng shell đó và trở về shell cha. Trong thực tế, nó sẽ bắt đầu một bash
quy trình mới để thực thi tập lệnh).
( . script
) sẽ khiến shell hiện tại đọc các lệnh từ tệp như thể chúng đang được gõ trong dòng lệnh. Không có vỏ mới sinh sản.
Một cách rất dễ dàng để xem cách ứng xử này là viết một tập lệnh chỉ chứa exit
. Nếu bạn ./script
, điều đó dường như sẽ không xảy ra, điều này là do một quá trình shell mới được bắt đầu, exit
lệnh sẽ thoát khỏi shell mới và shell hiện tại của bạn không bị ảnh hưởng.
Nếu bạn . script
, thiết bị đầu cuối hiện tại của bạn sẽ đóng, bởi vì exit
lệnh chạy trong shell hiện tại. Vì vậy, nó tương đương với việc gõ exit
vào dấu nhắc lệnh.