$ _ so với! $. Đối số cuối cùng của lệnh trước và chuyển hướng đầu ra


28

Câu hỏi là về các biến đặc biệt. Tài liệu nói:

!!:$

chỉ định đối số cuối cùng của lệnh trước . Điều này có thể được rút ngắn thành! $.


( $_, một dấu gạch dưới.) Khi khởi động shell, được đặt thành tên đường dẫn tuyệt đối được sử dụng để gọi tập lệnh shell hoặc shell đang được thực thi như được truyền trong môi trường hoặc danh sách đối số. Sau đó, mở rộng đối số cuối cùng sang lệnh trước đó sau khi mở rộng. Cũng được đặt thành tên đường dẫn đầy đủ được sử dụng để gọi từng lệnh được thực thi và được đặt trong môi trường được xuất sang lệnh đó.

Phải có một số khác biệt tôi không thể nắm bắt được, bởi vì:

$ echo "hello" > /tmp/a.txt
$ echo "!$"
echo "/tmp/a.txt"
/tmp/a.txt

$ echo "hello" > /tmp/a.txt
$ echo $_
hello

Sự khác biệt là gì?


4
! $ là mở rộng lịch sử, không phải là một biến đặc biệt, vì vậy tôi cho rằng mã bash xử lý chúng khác nhau.
Jeff Schaller

2
Tôi không có một câu trả lời dứt khoát cho câu hỏi này, nhưng: ① Ngôn ngữ shell Bourne là một trong, có lẽ các ngôn ngữ lập trình trong nội bộ phù hợp nhất vẫn được sử dụng rộng rãi hiện nay. Cố gắng suy luận các nguyên tắc chung sẽ không đưa bạn đến đâu. Bạn chỉ cần ghi nhớ tất cả các quy tắc đặc biệt. Lấy làm tiếc. Lưu ý các từ "sau khi mở rộng", ngay sau cụm từ bạn đã tô sáng, trong định nghĩa của $_. Điều đó rất quan trọng. Nó có thể không giải thích sự khác biệt đánh đố bạn nhưng nó giải thích một loạt các cách khác $_!$không giống nhau.
zwol

Câu trả lời:


32

!$là một từ chỉ định mở rộng lịch sử, nó mở rộng đến từ cuối cùng của lệnh trước đó trong lịch sử . IOW, từ cuối cùng của mục trước trong lịch sử. Từ này thường là đối số cuối cùng để ra lệnh, nhưng không phải trong trường hợp chuyển hướng. Trong:

echo "hello" > /tmp/a.txt

toàn bộ lệnh 'echo "hello" > /tmp/a.txt'xuất hiện trong lịch sử và /tmp/a.txtlà từ cuối cùng của lệnh đó.

_là một tham số shell, nó mở rộng đến đối số cuối cùng của lệnh trước đó. Ở đây, chuyển hướng không phải là một phần của các đối số được truyền cho lệnh, vì vậy chỉ hellocó đối số được truyền tới echo. Đó là lý do tại sao $_mở rộng sang hello.

_không phải là một trong những thông số đặc biệt tiêu chuẩn shell nữa. Nó hoạt động trong bash, zsh, mkshdashchỉ khi tương tác, ksh93chỉ khi hai lệnh đang trên đường riêng biệt:

$ echo 1 && echo $_
1
/usr/bin/ksh

$ echo 1
1
$ echo $_
1

1
Một hiệu ứng của !$mở rộng so với $_tham số là echo $_luôn hiển thị trong lịch sử echo $_, đồng thời echo !$hiển thị giá trị mà nó được mở rộng. Ví dụ echo one twosau đó echo !$, sau đó nhấn lên chương trình echo two.
Jacktose
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.