Hiểu ý nghĩa của `$ _`


12

Bạn có thể giải thích các câu sau đây từ hướng dẫn Bash về $_, đặc biệt là các phần in đậm, có thể với một số ví dụ?

  1. 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 được thực thi như được truyền trong môi trường hoặc danh sách đối số .

  2. Sau đó , mở rộng đến đối số cuối cùng cho lệnh trước đó, sau khi mở rộng.

  3. 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được đặt trong môi trường được xuất sang lệnh đó .

  4. Khi kiểm tra thư , tham số này giữ tên của tệp thư.


4
-1 câu hỏi không rõ ràng & không được nghiên cứu kỹ lưỡng. Bạn đã thử những gì? Đâu là kỳ vọng của bạn không đúng với văn bản? Bạn không thành thật hiểu từ 'sau đó'? Nếu một người dùng mới hỏi cùng câu hỏi này, tôi sẽ có cùng câu hỏi với họ (mặc dù sự tò mò bẩm sinh tương tự của tôi là chính xác cách mọi thứ hoạt động).
Jeff Schaller

Câu trả lời:


20

Tôi đồng ý nó không rõ ràng lắm.

1. Khi khởi động shell,

  • nếu _biến là trong môi trường bashnhận được , thì bashnó không bị ảnh hưởng.

    Đặc biệt, nếu đó là bashvỏ được gọi bởi một bash vỏ (mặc dù zsh, yashvà một số kshhiện thực cũng làm điều đó), sau đó bashvỏ sẽ thiết lập các _biến môi trường đến đường dẫn của lệnh được thực thi (đó là điểm thứ 3 trong câu hỏi của bạn). Chẳng hạn, nếu bashđược gọi để diễn giải một tập lệnh là kết quả của bashviệc diễn giải shell khác :

    bash-script some args

    Điều đó bashsẽ được thông qua _=/path/to/bash-scriptrong môi trường được cung cấp bash-scriptvà đó là giá trị ban đầu của $_ bashbiến sẽ nằm trong bashlớp vỏ diễn giải tập lệnh đó.

    $ env -i _=whatever bash -c 'echo "$_"'
    whatever
  • Bây giờ, nếu ứng dụng gọi không vượt qua _biến môi trường , trình bashvỏ được gọi sẽ khởi tạo $_cho ứng argv[0]dụng nhận nó có thể bash, /path/to/bashhoặc /path/to/some-scripthoặc bất cứ thứ gì khác (trong ví dụ trên, đó sẽ là /bin/bashnếu tập lệnh của tập lệnh được #! /bin/bash hoặc /path/to/bash-script tùy thuộc vào hệ thống ).

    Vì vậy, văn bản đó là sai lệch vì nó mô tả hành vi của người gọi mà bashkhông có quyền kiểm soát. Ứng dụng được gọi bashrất có thể hoàn toàn không được thiết lập $_(trong thực tế, chỉ có một số shell và một vài ứng dụng tương tác hiếm, execlp()không , chẳng hạn), hoặc nó có thể sử dụng nó cho một cái gì đó hoàn toàn khác (ví dụ, ksh93đặt nó thành *pid*/path/to/command).

    $ env bash -c 'echo "$_"'
    /usr/bin/env   (env did not set it to /bin/bash, so the value we
                   get is the one passed to env by my interactive shell)
    $ ksh93 -c 'bash -c "echo \$_"'
    *20042*/bin/bash

2. Sau đó

Các Sau đó không phải là rất rõ ràng một trong hai. Trong thực tế, đó là ngay khi bashdiễn giải một lệnh đơn giản trong môi trường shell hiện tại.

  • Trong trường hợp của một vỏ tương tác , đó sẽ là lệnh đơn giản đầu tiên được giải thích từ /etc/bash.bashrcví dụ.

    Chẳng hạn, tại dấu nhắc của trình bao tương tác:

     $ echo "$_"
     ]      (the last arg of the last command from my ~/.bashrc)
     $ f() { echo test; }
     $ echo "$_"
     ]      (the command-line before had no simple command, so we get
             the last argument of that previous echo commandline)
     $ (: test)
     $ echo "$_"
     ]      (simple command, but in a sub-shell environment)
     $ : test
     $ echo "$_"
     test
  • Đối với hệ vỏ không tương tác , nó sẽ là lệnh đầu tiên trong $BASH_ENVhoặc của mã được đưa vào vỏ đó nếu $BASH_ENVkhông được đặt.

3. Khi Bash thực thi một lệnh

Điểm thứ ba là một cái gì đó khác biệt và được gợi ý trong các cuộc thảo luận ở trên.

bash, giống như một số shell khác sẽ truyền một _biến môi trường cho các lệnh mà nó thực thi có chứa đường dẫn bashđược sử dụng làm đối số đầu tiên cho các execve()cuộc gọi hệ thống.

$ env | grep '^_'
_=/usr/bin/env

4. Khi kiểm tra thư

Điểm thứ tư được mô tả chi tiết hơn trong phần mô tả MAILPATHbiến:

'MAILPATH'

Một danh sách tên tệp được phân tách bằng dấu hai chấm mà shell định kỳ kiểm tra thư mới .

Mỗi mục nhập danh sách có thể chỉ định thư được in khi thư mới đến trong tệp thư bằng cách tách tên tệp khỏi thư bằng '?'. Khi được sử dụng trong văn bản của tin nhắn, '$ _' sẽ mở rộng thành tên của tệp thư hiện tại.

Thí dụ:

$ MAILCHECK=1 MAILPATH='/tmp/a?New mail in <$_>' bash
bash$ echo test >> /tmp/a
New mail in </tmp/a>

4

Hãy thử ví dụ đơn giản này:

echo "$_"
echo "test"
echo "$_"

Chạy nó bằng cách cho đường dẫn tuyệt đối ( /home/$USERNAME/test.sh); đầu ra:

/home/$USERNAME/test.sh
test
test

Đầu tiên $_chứa đường dẫn bạn đã sử dụng để gọi tập lệnh và cái thứ hai chứa đối số thứ nhất ở giữa echo. Đối với mục thứ ba trong danh sách, nếu bạn khởi động một thiết bị đầu cuối mới và gõ echo, $_ nó sẽ hiển thị biến chứa chứa PATHthường được sử dụng để tra cứu và gọi các lệnh (trong máy Ubuntu của tôi) trong một vỏ bình thường hoặc đường dẫn tuyệt đối đến .bashrstệp của bạn trong một vỏ đăng nhập.

Đối với mục bốn từ trang bash man:

Khi được sử dụng trong văn bản của tin nhắn, $_mở rộng thành tên của mailfile hiện tại.


Cảm ơn. (1) bạn có thể giải thích trường hợp thứ ba với các ví dụ? (2) Khi tôi mở tab thiết bị đầu cuối gnome mới, đầu ra của echo $_EDITORvà tại sao lại như vậy? Trường hợp nào nó làm theo? (3) Bạn có thể đưa ra một ví dụ về cách kiểm tra thư và sử dụng $_trong trường hợp này không?
Tim

Mở của bạn .bashrcvà nhận xét ra mỗi dòng ở đó. Chỉ giữ một dòng duy nhất chứa một lệnh giống echo "test"hoặc tương tự. Lưu và đóng. Sau đó chạy bashvà ngay lập tức echo $_. Tiếng vang cuối cùng này sẽ in thử nghiệm trong đầu ra.
coffeMug

Đối với phần thư tôi chưa sử dụng thư Unix và hiện chưa cài đặt thư hoạt động trên hệ thống của tôi nên không thể đưa ra ví dụ cho bạn. Nhưng nên rõ ràng nếu bạn làm theo mô tả MAILPATHtrong linuxcommand.org/lc3_man_pages/bash1.html
coffeMug

1
FYI, phiên bản chính thức, cập nhật của hướng dẫn sử dụng bash là: gnu.org/software/bash/manual/bashref.html . Đây là phiên bản 4.3 trong khi trang linuxcommand là 4.1.
Jeff Schaller

1

Đối với trường hợp 2, một ví dụ có giá trị bằng một ngàn từ:

mkdir my_long_dir
cd $_

Liệu những gì bạn đoán / hy vọng. Cung cấp cho tôi một trình giữ chỗ đơn giản khi tôi ở trên dòng lệnh để cứu tôi phải lặp lại chính mình.

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.