$ Nghĩa là gì?


32

Tôi đang theo dõi thông qua một hướng dẫn và nó đề cập đến việc chạy lệnh này:

sudo chmod 700 !$

Tôi không quen thuộc !$. Nó có nghĩa là gì?


5
Nói chung là an toàn để thử echomột cái gì đó nếu bạn không chắc chắn nó sẽ làm gì.
Shadur

8
@Shadur, không phải lúc nào. echo $(rm -rf /)
cjm

1
@cjm Trừ khi bạn ở trên một hệ thống thực sự cũ, bạn sẽ cần --no-preserve-roottùy chọn trong đó và nếu bạn thấy các từ "không bảo tồn" trong chương trình, tốt hơn bạn nên suy nghĩ thực sự cẩn thận về những gì nó làm.
wchargein

4
@WChargin Hãy thật cẩn thận khi cho rằng "thực sự cũ" và "không phải Linux / không sử dụng lõi GNU" là như nhau; họ không.
Chris Down

Câu trả lời:


44

Về cơ bản, đó là đối số cuối cùng của lệnh trước đó.

!$là "kết thúc" của lệnh trước đó. Xem xét ví dụ sau: Chúng tôi bắt đầu bằng cách tìm kiếm một từ trong tệp:

grep -i joe /some/long/directory/structure/user-lists/list-15

nếu joe nằm trong danh sách người dùng đó, chúng tôi muốn xóa anh ta khỏi nó. Chúng ta có thể kích hoạt vi với cây thư mục dài đó làm đối số hoặc đơn giản là vi !$bash nào mở rộng thành:

vi /some/long/directory/structure/user-lists/list-15

( nguồn ; hướng dẫn tiện dụng, nhân tiện)


Không có gì đáng phân biệt giữa !$mã thông báo này và biến shell đặc biệt $_. Thật vậy, cả hai mở rộng đến đối số cuối cùng của lệnh trước đó. Tuy nhiên, !$được mở rộng trong quá trình mở rộng lịch sử , trong khi $_được mở rộng trong quá trình mở rộng tham số . Một hậu quả quan trọng của việc này là, khi bạn sử dụng !$, lệnh mở rộng sẽ được lưu trong lịch sử của bạn.

Ví dụ, hãy xem xét các tổ hợp phím

  • echo Foo Enter echo !$ Jar Enter Up Enter; và

  • echo Foo Enter echo $_ Jar Enter Up Enter.

(Các ký tự duy nhất được thay đổi là $!$_ở giữa.)

Trước đây, khi bạn nhấn Up, dòng lệnh sẽ đọc echo Foo Jar, vì vậy dòng cuối cùng được ghi vào thiết bị xuất chuẩn là Foo Jar.

Ở phần sau, khi bạn nhấn Up, dòng lệnh sẽ đọc echo $_ bar, nhưng bây giờ $_có một giá trị khác so với trước đây, thực sự $_là bây giờ Jar, vì vậy dòng cuối cùng được viết cho thiết bị xuất chuẩn là Jar Jar.

Một hậu quả khác là _có thể được sử dụng trong các mở rộng tham số khác, ví dụ, chuỗi lệnh

printf '%s '    isomorphism
printf '%s\n'   ${_%morphism}sceles

in isomorphism isosceles. Nhưng không có ${!$%morphism}sự mở rộng " " tương tự .

Để biết thêm thông tin về các giai đoạn mở rộng ở Bash, hãy xem EXPANSIONphần của man 1 bash(đây được gọi là Mở rộng Shell trong phiên bản trực tuyến). Phần HISTORY EXPANSIONnày là riêng biệt.


6
Tốt đẹp. Tốt để biết. Ngoài ra, điều tốt là có Stack Exchange. Thật khó để tìm kiếm Google cho một cái gì đó như!$
Andrew

4
BTW, trên dòng lệnh, bạn có thể chèn đối số cuối cùng của lệnh trước đó insert-last-argument, thường được liên kết với M-..
choroba

1
@Andrew hãy nhớ chấp nhận điều này nếu nó trả lời câu hỏi của bạn. Chấp nhận và nâng cấp thay vì đăng bình luận là cách cảm ơn được thể hiện trên mạng SE, xem tại đây để biết lập trường "chính thức".
terdon

1
@Andrew FYI, tôi đã tìm kiếm Google cho "bash bang Dollar" và nhận được kết quả tốt, bao gồm liên kết này là danh sách thứ ba.
wchargein

1
@terdon Tôi đã cố chấp nhận câu trả lời tối qua, nhưng nó nhanh đến mức tôi buộc phải chờ để chấp nhận nó.
Andrew

4

Nói đúng ra !$là từ cuối cùng của lệnh cuối cùng từ danh sách lịch sử.

word - Một chuỗi các ký tự được coi là một đơn vị của shell. Các từ có thể không bao gồm các siêu ký tự không được trích dẫn.

metacharacter - Một ký tự mà khi không được trích dẫn sẽ phân tách các từ. Một metacharacter là một khoảng trống hoặc một trong các ký tự sau: '|', '&', ';', '(', ')', '<' hoặc '>'

để trống - Một ký tự khoảng trắng hoặc tab.

Ví dụ:

set -o history # enable command history
set -o histexpand # enable ! style history substitution

HISTSIZE=10

# save all lines on the history list    
HISTCONTROL=
HISTIGNORE=

date
echo !$ # prints date

date>/dev/null
echo !$ # prints /dev/null

echo a b c>/dev/null
echo !$ # prints /dev/null

HISTCONTROL=ignorespace # lines which begin with a space character are not saved in the history list
echo a b c
 echo d e f # space at the beginning
echo !$ # prints c


-3

!$ sẽ cung cấp cho bạn lệnh cuối cùng được sử dụng cho người dùng cụ thể đó ....

bạn cũng có thể tìm thấy lịch sử của các lệnh được sử dụng trước đó bằng cách sử dụng historylệnh ... dùng thử ....

GHI CHÚ: Đối với một người dùng cụ thể, tất cả các lệnh được sử dụng trước đó sẽ được lưu trữ trong tệp lịch sử bash.


1
Các câu trả lời khác là đúng. Điều này là sai.
Scott
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.