./ so với. để chạy các chương trình dưới thiết bị đầu cuối


13

Tôi cần một số giải thích về cách chúng tôi chạy các tệp thực thi trong thiết bị đầu cuối. Đây có thể là một câu hỏi khập khiễng nhưng sự khác biệt giữa việc chạy một tệp thực thi với ./an_executable. an_executable(giả sử rằng chúng ta đang ở trong thư mục nơi đặt an_executable)

Tôi đã biết rằng cái trước làm cho trình bao tìm kiếm an_executable trong thư mục hiện tại ( .), nhưng tại sao không /cần thiết sau .khi sử dụng phiên bản sau?

Cảm ơn trước.


Câu trả lời:


22

Các . executablecú 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 sourcehợ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 :)

./executableyê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 executablelà 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 bashquy 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, exitlệ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ì exitlệnh chạy trong shell hiện tại. Vì vậy, nó tương đương với việc gõ exitvào dấu nhắc lệnh.


Thật vậy, tôi đã xử lý kịch bản shell khi nhận thấy hành vi này. Cảm ơn bạn rất nhiều, đó là câu trả lời tôi cần. :)
zipzap

một câu hỏi khác được đặt ra (nếu bạn không phiền): nếu tập lệnh của tôi chỉ chứa một số tin nhắn đơn giản có tiếng vang và tôi đang chạy nó với ./script, thì tại sao tôi có thể thấy các tin nhắn trong trình bao cha mẹ nếu lớp con đóng lại ngay khi cuộc hành quyết kết thúc?
zipzap

2
Bởi vì trong khi lớp con là một quá trình riêng biệt , nó sử dụng cùng một thiết bị đầu cuối như vỏ gọi. Nó tương tự như cách bạn vẫn có thể thấy lsđầu ra: bạn nhập lệnh, nó chạy, hiển thị đầu ra và sau đó kết thúc, nhưng đầu ra vẫn ở trong thiết bị đầu cuối.
roadmr

2
Đừng nhầm lẫn vỏ với thiết bị đầu cuối; chúng là những thứ khác nhau Mở một thiết bị đầu cuối và dấu nhắc lệnh được đưa ra bởi một bashvỏ chạy bên trong nó. Nếu bạn gõ bash, bạn sẽ chạy một shell khác ; với lớp vỏ đầu tiên, nó chỉ là một chương trình được chạy. Nếu bạn nhập exit, bạn sẽ đóng lớp vỏ cuối cùng mà bạn đã bắt đầu nhưng vẫn ở lớp vỏ đầu tiên (lớp vỏ từ khi bạn khởi động thiết bị đầu cuối). Một lần nữa, tất cả điều này xảy ra trong cùng một thiết bị đầu cuối.
roadmr

1
@DavidZ Tôi đã đề cập đến nó :) "Tìm nguồn cung ứng sẽ chỉ" chạy "(hoặc dường như chạy) các kịch bản shell."
roadmr
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.