Là ./ (dấu gạch chéo) là một lệnh?


16

Cốt lõi của câu hỏi:

Câu hỏi đặt ra trong khi tôi không thể cài đặt phần mềm, vì vậy tôi thực sự hỏi về ./ bởi vì tôi không biết về nó và "lệnh không tìm thấy" đầu ra làm tôi bối rối về việc lệnh thực sự là gì.

Bối cảnh:

Tôi muốn cài đặt các tập tin truecrypt-7.2-setup-x86.

Hướng dẫn sử dụng lệnh:

sudo ./truecrypt-7.2-setup-x86

Nhưng đầu ra là:

sudo: ./truecrypt-7.2-setup-x86: command not found

CẬP NHẬT: để hoàn thiện, trong thử nghiệm tôi đã ở trong thư mục tệp nhưng chưa làm cho tệp thực thi (chmod + x).


1
Một ./phần của lệnh đang nói "Hãy tìm trong thư mục hiện tại và thực thi lệnh 'truecrypt-7.2-setup-x86' từ đây". Bạn cần chạy lệnh này từ thư mục nơi bạn giải nén tệp.
Charles Green

2
@Videonauth - Không thực sự, cá nhân tôi không nghĩ rằng nó tăng đến mức của một câu trả lời.
Charles Green

1
@Zanna Tôi đã kiểm tra tập lệnh mà không có quyền thực thi và lỗi được ném là lỗi quyền thiếu, không tìm thấy lệnh.
Charles Green

2
@ubuntubu OK, rất tốt, bạn đã chuyển vào thư mục - tốt. Nhận xét nhỏ về chỉnh sửa, mặc dù. Lệnh nên là chmod +x, chmod -xngược lại - nó loại bỏ các quyền thực thi
Sergiy Kolodyazhnyy

4
Tiêu đề câu hỏi khá khác với cơ thể; Có lẽ nên sửa?
David Z

Câu trả lời:


24

./không phải là một lệnh. Lệnh là ./truecrypt-7.2-setup-x86.

Shell và các chương trình như thế của sudobạn sẽ coi một lệnh là một tên đường dẫn khi nó chứa ít nhất một /ký tự. Vì .đại diện cho bất kỳ thư mục nào bạn hiện đang ở, hãy ./truecrypt-7.2-setup-x86đặt tên tệp truecrypt-7.2-setup-x86trong thư mục hiện tại. Nếu không có tệp đó, hoặc có nhưng tệp không thể chạy được, thì bạn sẽ nhận được thông báo lỗi.

Khi một lệnh không chứa dấu gạch chéo, các thư mục được liệt kê $PATHsẽ được tìm kiếm, như Sergiy Kolodyazhnyy nói . Thư mục hiện tại không được tự động tìm kiếm - và không nên đưa .vào $PATH. Bằng cách đó, bạn không vô tình chạy những thứ bạn không muốn chạy vì bạn tình cờ có cdmột thư mục chứa chúng.

Viết ./trước tên của một tệp thực thi trong thư mục hiện tại theo cách phổ biến để chạy nó, nhưng đây không thực sự là một cú pháp đặc biệt. Ví dụ, nếu bạn làm hỏng $PATHvà bạn cần chạy một lệnh như thế ls, bạn có thể viết /bin/ls. Không .cần thiết trong trường hợp đó hoặc nói chung; những gì cần thiết là một /nơi nào đó trong tên đường dẫn để biểu thị rằng bạn có nghĩa là tên đường dẫn.

.luôn luôn là thư mục hiện tại và /chỉ là dấu phân cách thư mục, điều đầu tiên cần làm là kiểm tra xem tệp bạn đã đặt tên có thực sự tồn tại trong thư mục hiện tại không. (Nếu có, thì hãy kiểm tra các quyền của nó , như Charles Green giải thích . Nhưng nếu bạn trích xuất tệp từ kho lưu trữ, thì nó thường sẽ có quyền thực thi nếu dự định được chạy.)


21

Phần ./ của lệnh có nội dung "Tìm trong thư mục hiện tại và thực thi lệnh 'truecrypt-7.2-setup-x86' từ đây". Bạn cần chạy lệnh này từ thư mục nơi bạn giải nén tệp.

Điều này có thể được kiểm tra: Trong cùng một cửa sổ đầu cuối nơi bạn đang thử lệnh, hãy nhập lệnh ls -l true*- nếu tệp có trong thư mục làm việc hiện tại, thì một danh sách hiển thị tệp (và một loạt thông tin bổ sung) sẽ được hiển thị.

Như Zanna đã lưu ý trong các bình luận, tệp của bạn có thể không có quyền thực thi - điều này có thể được khắc phục dễ dàng. Như một trường hợp thử nghiệm, thư mục của tôi hiển thị

chick@dad:~/test$ ls -l
total 4
-rw-r--r-- 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

và tệp "rFullBack" liệt kê '-rw-' là sự cho phép của tôi, để đọc và ghi tệp. Tôi có thể thực thi lệnh chmod +x rFullBackvà danh sách thư mục thay đổi thành

chick@dad:~/test$ ls -l
total 4
-rwxr-xr-x 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

Hiện tại quyền của tôi là '-rwx', cho biết tôi có thể thực thi tệp.


Nói tóm lại, nếu tập tin tồn tại trong thư mục của bạn

chạy lệnh

chmod +x ./truecrypt-7.2-setup-x86

và sau đó là lệnh

sudo ./truecrypt-7.2-setup-x86

1
Không hẳn. Nó liệt kê rw-dưới dạng sự cho phép của bạn - -trước đó là để đặt [gu] id và bit dính.
Duncan X Simpson

@DuncanXSimpson Cảm ơn - Tôi đã cập nhật một chút mô tả về các quyền, nhưng tôi sẽ bỏ qua các bit setguid và dính cho câu trả lời này!
Charles Green

8

Làm thế nào để gọi lệnh trong shell hoạt động

Không, nó không phải là một lệnh. Cách shell hoạt động là khi bạn nhập một dòng văn bản, từ đầu tiên sẽ được coi là lệnh và nếu lệnh không phải là một trong những shell được tích hợp thì shell sẽ xem xét tất cả các vị trí được liệt kê trong PATH biến môi trường .

Điều gì xảy ra nếu khi lệnh bạn muốn chạy nằm trong cùng thư mục với vị trí hiện tại của bạn nhưng thư mục đó không có trong danh sách PATHthư mục? Đó là khi bạn cần sử dụng ./. Đó là một cách chính xác giống như làm /bin/bash- bạn đang nói với shell nơi lệnh bạn muốn nằm, một đường dẫn đầy đủ đến nó. Và trong trường hợp ./ bạn đang nói với shell "hãy tìm trong thư mục này". Vì vậy, phần quan trọng là bạn phải ở trong cùng thư mục chứa tệp.

Tất nhiên, để thực sự chạy một tệp thực thi, nó phải có tập bit thực thi, vì vậy bạn sẽ cần chmod +x ./my_file.

Vì vậy, các bước quan trọng:

  1. cd nơi bạn đã lưu tệp; nếu nó ở trong ~/Downloadsthìcd ~/Downloads
  2. Chạy chmod +x ./truecrypt-7.2-setup-x86, cái này nói "tạo tập tin truecrypt-7.2-setup-x86 đang ở thư mục này có thể thực thi được"
  3. Và bây giờ làm sudo ./truecrypt-7.2-setup-x86

Lưu ý rằng việc sử dụng ./không phải là hành vi ngẫu nhiên, nhưng thực sự là một tiêu chuẩn, được chỉ định bởi tiêu chuẩn Giao diện hệ điều hành di động (còn gọi là POSIX) , xem cụ thể phần "Tìm kiếm và thực thi lệnh".

Tái tạo lỗi

$ # my script is in ~/Downloads folder
$ stat -c "%n" /home/xieerqi/Downloads/my_script.sh                         
/home/xieerqi/Downloads/my_script.sh
$ # if I run sudo ./my_script.sh, we get an error
$ sudo ./my_script.sh
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found
$ # of course the command not found because file is not in ./, not in this dir
$ # this is not  sudo's problem
$ # but sudo does indeed show the same error even if you're in same directory
$ cd ./Downloads/                                                                                                                                                      
$ sudo ./my_script.sh                                                                                                                                                  
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found

LƯU Ý : thông báo lỗi được cung cấp bởi sudorõ ràng là sai lệch vì vậy đây là điều cần lưu ý; tuy nhiên xin lưu ý rằng đây không phải là cốt lõi của câu hỏi mà OP đang hỏi.

Tài liệu và tài liệu tham khảo

Từ bash4.3 hướng dẫn sử dụng, phần "THỰC HIỆN HÀNH LÝ":

Nếu tên không phải là hàm shell cũng không phải là hàm dựng và không chứa dấu gạch chéo, bash tìm kiếm từng phần tử của PATH cho một thư mục chứa tệp thực thi theo tên đó.

Từ Tại sao bạn cần ./ (dấu chấm chéo) trước tên tập lệnh để chạy nó trong bash? :

Nó hoạt động với ./ vì POSIX chỉ định rằng một tên lệnh có chứa / sẽ được sử dụng trực tiếp làm tên tệp, loại bỏ tìm kiếm trong $ PATH. Bạn có thể đã sử dụng đường dẫn đầy đủ cho cùng một hiệu ứng, nhưng ./ ngắn hơn và dễ viết hơn.


Thực tế sudođầu ra là sai lệch. Nếu bạn thử tương tự mà không có sudo, bạn sẽ gặp một lỗi khác từ bash: Permission denied. Và đúng như vậy, vì bạn đã không cho phép tập lệnh thực thi (thông qua chmod +x).
Ruslan

@Ruslan thực tế là sudođầu ra sai lệch là đúng, nhưng đó là lỗi xuất hiện. Đó có thể là một cái gì đó để báo cáo cho các nhà phát triển và để họ sửa nó. Tuy nhiên, đây không phải là cốt lõi của cuộc thảo luận - chúng tôi cần thiết lập những gì OP đã làm để tạo ra lỗi đó và hướng dẫn họ đi đúng hướng. Có hay không nó gây hiểu lầm - đó không phải là vấn đề ở đây.
Sergiy Kolodyazhnyy

Theo một cách khác, nó không hoàn toàn giống như sử dụng /bin/bash: Nó không cho phép bạn thực thi một tập lệnh mà bạn không có quyền thực thi. Khi bạn mở đầu tên tập lệnh /bin/bash, thực tế có thể /bin/bashthực thi được là tất cả vấn đề, vì đó là lệnh đang được thực thi. Khi bạn không làm điều đó, chính kịch bản đang được thực thi, điều này dẫn đến lớp vỏ hiện tại của bạn hoặc bất cứ thứ gì trên #!dòng trên cùng được gọi
Monty Harder

@MontyHarder /bin/bashchỉ là một ví dụ ở đây. Thực tế là chúng tôi đang gọi /bin/bash./script.sh bằng cách chỉ định đường dẫn đến sự việc đang được thực thi - đó là như nhau. Prefacing kịch bản với bash script.shhoặc /bin/bash script.shhoàn toàn chủ đề khác nhau, nơi mà bạn chạy một thực thi và vượt qua kịch bản để nó như là đối số - mà bằng cách này có thể phá vỡ nếu cú pháp được viết cho một cái gì đó khác hơn so với vỏ bạn đang gọi điện thoại, nói csh. /bin/bashcó thể thực thi được, nhưng thực tế là bạn vẫn đang chỉ định đường dẫn đầy đủ đến nó.
Sergiy Kolodyazhnyy

2
@SergiyKolodyazhnyy prefacing một tên kịch bản với /bin/bashhoặc thậm chí chỉ bashcũng một cách phổ biến để giải quyết việc thiếu các điều khoản thực thi trên kịch bản. Chỉ định đường dẫn kịch bản đầy đủ không giải quyết được vấn đề đó. Vì vậy, /bin/bashlà một ví dụ đặc biệt xấu trong trường hợp cụ thể này.
Monty Harder
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.