Việc gõ một dấu chấm than duy nhất làm gì trong Bash?


20

Bash sử dụng dấu chấm than cho các mở rộng lịch sử, như được giải thích trong các câu trả lời cho câu hỏi này (ví dụ: sudo !!chạy dòng lệnh trước đó với sudo). Tuy nhiên, tôi không thể tìm thấy bất cứ nơi nào giải thích việc chạy lệnh nào sau đây (tức là một dấu chấm than duy nhất):

!

Nó dường như không in gì và thoát bằng 1, nhưng tôi không chắc tại sao nó lại làm như vậy. Tôi đã xem trực tuyến và trong trang Bash của người đàn ông, nhưng không thể tìm thấy bất cứ điều gì, ngoài thực tế rằng đó là một "từ dành riêng" - nhưng cũng vậy }, và chạy nó:

}

in lỗi:

bash: syntax error near unexpected token `}'

1
Không có gì. !cho biết "bắt đầu" của một biểu thức mở rộng lịch sử.
jordanm

Câu trả lời:


47

Sự đơn độc !khi bắt đầu một lệnh phủ nhận trạng thái thoát của lệnh hoặc đường ống : nếu lệnh thoát 0, nó sẽ chuyển sang 1(thất bại) và nếu nó thoát ra khác không, nó sẽ biến nó thành một 0lối thoát (thành công).

Việc sử dụng này được ghi lại trong hướng dẫn Bash:

Nếu từ dành riêng '!' trước đường ống dẫn, trạng thái thoát là phủ định logic của trạng thái thoát như mô tả ở trên.

Một !không có lệnh sau phủ nhận lệnh trống, mà không làm gì và trả về true (tương đương với các :lệnh ). Do đó, nó đảo ngược true thành false và thoát với trạng thái 1, nhưng không tạo ra lỗi.


Ngoài ra còn có các cách sử dụng khác !trong test[[các lệnh, trong đó chúng phủ nhận một bài kiểm tra có điều kiện. Những điều này không liên quan đến những gì bạn đang thấy. Trong cả câu hỏi của bạn và những trường hợp đó, nó không liên quan đến việc mở rộng lịch sử và !được tách ra khỏi bất kỳ điều khoản nào khác.


5
+1 cho câu trả lời đầu tiên để giải thích những gì thực sự chạy và tại sao điều đó giải thích mã trả về.
Jeff Schaller

11

Bạn có thể tìm thấy dấu chấm than duy nhất được ghi lại trong phần hướng dẫn sử dụng bash 3.2.2 Đường ống

Nếu từ dành riêng '!' trước đường ống dẫn, trạng thái thoát là phủ định logic của trạng thái thoát như mô tả ở trên.

$ ! true; echo $?
1
$ ! false; echo $?
0

Ngoài ra phần 3.2.4.2 Cấu trúc có điều kiện

! biểu hiện

Đúng nếu biểu thức là sai.


Ngoài ra phần 4.1 Bourne Shell Buildins

! expr

Đúng nếu expr là sai.


Cũng cần lưu ý rằng !sẽ bắt đầu thay thế lịch sử trừ khi được theo sau: dấu cách, tab, cuối dòng, '=' hoặc '(' (khi tùy chọn shell extglob được bật bằng cách sử dụng nội dung shopt).


0

Bởi vì !được sử dụng trong so sánh và có nghĩa là KHÔNG .

Ví dụ:

a=3
b=2

[ $a -eq $b ] && echo "Equal"
[ ! $a -eq $b ] && echo "Not equal"
# of cause last comparison is possible to write as:
[ $a -eq $b ] || echo "Not equal"

[ $a -eq $b ]
echo $?
1
[ ! $a -eq $b ]
echo $?
0

1
Đó là ý nghĩa của !một đối số cho testlệnh (bao gồm cả phiên bản dựng sẵn của bash), không phải là ý nghĩa !khi được sử dụng ở vị trí lệnh.
Gilles 'SO- ngừng trở nên xấu xa'

1
Nó sẽ cần phải ! [...]phù hợp với câu hỏi trong trường hợp này.
Michael Homer

Đồng ý với @Gilles và @Michael Homer. Tôi biết đó []test. Tôi hơi vội vàng.
Yurij Goncharuk

-2

! lệnh tích hợp, đảo ngược ý nghĩa của một đường ống.

Công dụng khác:

#! lệnh dựng sẵn, gọi trình thông dịch có tên để thực thi tập lệnh.

! người chỉ định sự kiện, đánh dấu một từ dòng lệnh là sự thay thế lịch sử

!= toán tử bất đẳng thức

$! biến shell, trả về số tiến trình của lệnh nền cuối cùng.


Chỉ cần thêm, người ta có thể sử dụng! $ Để sử dụng từ cuối cùng của lệnh trước đó như vậy: ls -l /tmp cd !$ Điều này sẽ đưa bạn đến thư mục / tmp.
Nhảy Bunny

-3

! theo sau là một chuỗi thực thi lệnh gần đây nhất (vẫn trong bộ đệm lệnh) bắt đầu với chuỗi đã cho. Có lẽ shell chỉ thấy rằng không có lệnh nào trước đó bắt đầu bằng <null>.


3
Bạn nhận thấy rằng không có chuỗi nào trong câu hỏi ...?
Jeff Schaller
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.