Tại sao thông báo lỗi cho hai dấu hai chấm dưới dạng lệnh (: :) trong bash có ba dấu hai chấm, nhưng một dấu hai chấm không cho đầu ra?


27

Nếu tôi gõ

::

vào một vỏ bash, tôi nhận được:

-bash: ::: command not found

Nhưng, chỉ có một :kết quả không có đầu ra. Tại sao lại thế này?


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Thomas Ward

Làm thế nào điều này có liên quan đến Ubuntu?
NerdOfCode

@NerdOfCode giống như thế này? meta.askubfox.com/q/17076/158442
muru

Câu trả lời:


40

Các :vỏ tích hợp vs không tồn tại::

Lệnh : shell-in tồn tại (lưu ý sự khác biệt giữa các lệnh bên ngoài và lệnh tích hợp ) không có gì; Nó chỉ trả về thành công, giống như truelệnh. Các :built-in là tiêu chuẩn và quy định của tiêu chuẩn POSIX , nơi nó cũng được gọi là "tiện ích vô giá trị". Nó thường được sử dụng để thử nghiệm hoặc chạy các vòng lặp vô hạn như trongwhile : ; do ...;done

bash-4.3$ type :
: is a shell builtin

Tuy nhiên, ::- hai ký tự dấu hai chấm với nhau - được hiểu là một "từ" cho trình bao và nó giả sử là một lệnh mà người dùng đã nhập. Shell sẽ trải qua quá trình kiểm tra các phần tử dựng sẵn, sau đó bất kỳ thư mục nào trong PATHbiến để tồn tại lệnh đó. Nhưng không có :: lệnh tích hợp cũng như bên ngoài ::. Do đó, điều đó tạo ra một lỗi.

Vâng, một định dạng điển hình cho một lỗi là gì?

<shell>: <command user typed>: error message

Do đó, những gì bạn thấy không phải là 3 dấu hai chấm mà là những gì bạn đã nhập vào định dạng lỗi tiêu chuẩn.

Cũng lưu ý rằng, điều đó :có thể lấy các đối số dòng lệnh, nghĩa là hợp pháp để làm:

: :

Trong trường hợp này, shell sẽ coi đó là hai "từ", một trong số đó là một lệnh và cái còn lại là một tham số vị trí. Điều đó cũng sẽ không có lỗi! (Xem thêm ghi chú lịch sử (sau này trong câu trả lời này) về việc sử dụng các :tham số vị trí.)


Trong vỏ khác với bash

Lưu ý rằng định dạng có thể khác nhau giữa các shell khác nhau. Đối với bash, kshmkshhành vi là phù hợp. Chẳng hạn, /bin/shshell mặc định của Ubuntu (thực tế /bin/dash):

$ dash
$ ::
dash: 1: ::: not found

trong đó 1 là số lệnh (tương đương với số dòng trong tập lệnh).

csh ngược lại không tạo ra thông báo lỗi nào cả:

$ csh
% ::
%

Trong thực tế, nếu bạn chạy strace -o csh.trace csh -c ::, đầu ra theo dõi trong csh.tracetệp cho thấy cshthoát ra với trạng thái thoát 0 (không có lỗi). Nhưng tcshkhông xuất ra lỗi (mặc dù không xuất ra tên của nó):

$ tcsh
localhost:~> ::
::: Command not found.

Thông báo lỗi

Nói chung, mục đầu tiên trong thông báo lỗi phải là quá trình hoặc hàm thực thi (trình bao của bạn cố gắng thực thi ::, do đó thông báo lỗi xuất phát từ trình bao). Ví dụ, ở đây quá trình thực thi là stat:

$ stat noexist
stat: cannot stat 'noexist': No such file or directory

Trong thực tế, POSIX định nghĩa hàm perror () , theo tài liệu này lấy một đối số chuỗi, sau đó xuất thông báo lỗi sau dấu hai chấm và sau đó là dòng mới. Trích dẫn:

Hàm perror () sẽ ánh xạ số lỗi được truy cập thông qua ký hiệu errno thành thông báo lỗi phụ thuộc ngôn ngữ, được ghi vào luồng lỗi tiêu chuẩn như sau:

  • Đầu tiên (nếu s không phải là con trỏ null và ký tự được trỏ bởi s không phải là byte rỗng), chuỗi được trỏ bởi s theo sau là dấu hai chấm và <dấu cách>.

  • Sau đó, một chuỗi thông báo lỗi theo sau là <dòng mới>.

Và đối số chuỗi về perror()mặt kỹ thuật có thể là bất cứ điều gì, nhưng tất nhiên để rõ ràng, đó thường là tên hàm hoặc argv[0].

Ngược lại, GNU có tập hợp các hàm và biến riêng để xử lý lỗi , mà lập trình viên có thể sử dụng fprintf()để stderrtruyền phát. Như một trong những ví dụ trên trang được liên kết hiển thị, một cái gì đó như thế này có thể được thực hiện:

  fprintf (stderr, "%s: Couldn't open file %s; %s\n",
           program_invocation_short_name, name, strerror (errno));

Ghi chú lịch sử

Trong shell Unix và Thompson cũ, :được sử dụng với gotocâu lệnh (mà theo người dùng có tên Perderabo trên luồng này không phải là shell được tích hợp sẵn). Trích dẫn từ hướng dẫn:

Toàn bộ tệp lệnh được tìm kiếm cho một dòng bắt đầu bằng a: là ký tự không trống đầu tiên, theo sau là một hoặc nhiều khoảng trống, sau đó là nhãn. Nếu một dòng như vậy được tìm thấy, goto định vị lại tập tin lệnh bù vào dòng sau khi nhãn và thoát. Điều này làm cho vỏ chuyển sang dòng có nhãn.

Vì vậy, bạn có thể làm một cái gì đó như thế này để tạo một kịch bản vòng lặp vô hạn:

: repeat
echo "Hello World"
goto repeat


1
DOS command.comvà Windows cmd.execó một tình huống tương tự nhưng ngược lại: :rõ ràng là nhãn goto (không phải là lệnh) và thường được sử dụng lại dưới dạng ký tự nhận xét (ví dụ :: This is a comment).
grawity

54

Dấu hai chấm cuối cùng chỉ là một phần của thông báo "không tìm thấy" mặc định:

$ x
x: command not found
$ ::
::: command not found

Lý do một đơn thư đại tràng sản xuất không có gì là : một lệnh hợp lệ - mặc dù nó không làm gì (trừ lợi nhuận TRUE). Từ SHELL BUILTIN COMMANDSphần man bash:

   : [arguments]
          No effect; the command does nothing beyond  expanding  arguments
          and  performing any specified redirections.  A zero exit code is
          returned.

Đôi khi bạn sẽ thấy nó trong các công trình như

while :
do
  something
done

Xem ví dụ Mục đích xây dựng đại tràng phục vụ mục đích gì?


vâng đây là nhận xét toàn diện nhất .. hùng hồn hơn nhiều so với của tôi .. giải thích rõ hơn nhiều: D
John Orion

8

Hãy thử bất kỳ lệnh không tồn tại nào khác và bạn sẽ thấy rằng :mục đích thông thường của nó bằng tiếng Anh:

$ ---
---: command not found

6

Dấu hai chấm được thêm vào là một phần của thông báo lỗi. Nếu một kiểu cd ownó dẫn đến bash: cd: ow: No such file or directory, điều đó cho thấy lỗi đang đặt vào dấu hai chấm phụ: No such file or directory


6
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found

thứ 3 là một miếng đệm từ định dạng

trong bash a :là một lệnh rỗng dòng trống


4

bạn nhận được 3 dấu hai chấm vì định dạng lỗi chứa dấu hai chấm:

bash: <command>: command not found
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.