`(Backquote / backtick) có nghĩa là gì trong các lệnh?


160

Tôi đã xem qua lệnh sau:

sudo chown `id -u` /somedir

và tôi tự hỏi: ý nghĩa của `biểu tượng là gì. Tôi nhận thấy rằng trong khi lệnh trên hoạt động tốt, thì lệnh bên dưới không:

sudo chown 'id -u' /somedir

Câu trả lời:


201

Đây là một backtick . Một backtick không phải là một dấu hiệu trích dẫn. Nó có một ý nghĩa rất đặc biệt. Mọi thứ bạn nhập giữa các backticks đều được đánh giá (được thực thi) bởi shell trước lệnh chính (như chowntrong ví dụ của bạn) và đầu ra của thực thi đó được sử dụng bởi lệnh đó, giống như khi bạn nhập đầu ra đó vào vị trí đó trong dòng lệnh.

Vậy thì sao

sudo chown `id -u` /somedir

chạy hiệu quả (tùy thuộc vào ID người dùng của bạn ) là:

sudo chown 1000 /somedir
  \    \     \     \
   \    \     \     `-- the second argument to "chown" (target directory)
    \    \     `-- your user ID, which is the output of "id -u" command
     \    `-- "chown" command (change ownership of file/directory)
      `-- the "run as root" command; everything after this is run with root privileges

Hãy xem câu hỏi này để tìm hiểu lý do tại sao, trong nhiều tình huống, không nên sử dụng backticks.

Btw, nếu bạn đã từng muốn sử dụng backtick theo nghĩa đen, ví dụ như trong một chuỗi, bạn có thể thoát nó bằng cách đặt dấu gạch chéo ngược ( \) trước nó.


36
Điều này giải thích backticks khá tốt, nhưng sử dụng $(your expression)là một cách tốt hơn để làm điều tương tự như $()cho phép bạn lồng các biểu thức. ví dụ: cd $(dirname $(type -P touch))sẽ đưa bạn vào thư mục chứa touchlệnh
Khaja Minhajuddin

11
@KhajaMinhajuddin Bạn chắc chắn đúng về việc làm tổ - câu hỏi được đề cập ở trên bao gồm nó một cách chi tiết. Nhưng mặc dù tôi nghĩ rằng đó là một cách thực hành tốt để sử dụng $()trong hầu hết các tình huống, nhưng nó không làm cho backticks trở thành một điều tồi tệ hơn . Đối với các mục đích thực tế, người ta phải thừa nhận rằng họ gõ nhanh hơn nhiều trên dòng lệnh (2 lần nhấn phím so với ít nhất 5, bao gồm Shift).
rozcietrzewiacz

2
@rozcietrzewiacz Nhận xét sau của bạn có lẽ đúng với hầu hết các bàn phím nhưng $( )chắc chắn dễ gõ hơn ` `ít nhất là trên bàn phím tiếng Pháp.
jlliagre

1
@KhajaMinhajuddin Bạn có thể lồng backticks, nhưng bạn cần thoát khỏi backticks cấp 2, và lồng cấp 2 bạn cần 3 backticks, cấp 3 lồng 5 backticks, cấp 4 7, & c.
JustinCB

66

Tôi muốn thêm vài điểm ở đây.

Backtick `…`thực sự được gọi là thay thế lệnh . Mục đích của việc thay thế lệnh là để đánh giá lệnh được đặt bên trong backtick và cung cấp kết quả của nó như là một đối số cho lệnh thực tế.

Việc thay thế lệnh có thể được thực hiện theo hai cách một là sử dụng $(…)và cách khác là `…`. Cả hai đều hoạt động như nhau, nhưng $(…)hình thức là cách hiện đại và có sự rõ ràng và dễ đọc hơn.

Và như vậy

sudo chown $(id -u) /somedir

có thể được ưa thích hơn khác.

Và một điều nữa bạn cần lưu ý ở đây là mối quan hệ thay thế lệnh với các quy tắc trích dẫn bash như được đề cập trong tài liệu bash .

Nếu sự thay thế xuất hiện trong dấu ngoặc kép, việc tách từ và mở rộng tên tệp sẽ không được thực hiện trên kết quả.


8
Ngoài ra, $(...)tổ tốt hơn.
Kusalananda

$()"``"không hoạt động theo cùng một cách
Kun

10

Một lưu ý làm rõ hiếm khi được đề cập:

Backticks (đôi khi còn được gọi là Graves vì ​​nó tăng gấp đôi như một giọng phổ biến trong tiếng Pháp và các ngôn ngữ khác) chỉ thay thế Đầu ra tiêu chuẩn , nhưng không phải là Lỗi tiêu chuẩn.

Vì vậy, để tiếp tục ví dụ trước:

file `which hostname`

sẽ làm việc như mong đợi, nhưng trong:

file `which hostnameX`

whichsẽ trả về một lỗi và đầu ra đó chuyển sang lỗi tiêu chuẩn, thay vì thay thế vào dòng lệnh bên cạnh file; sẽ không có đầu ra tiêu chuẩn nào cả, mà bạn có thể xác nhận bằng cách chạy:

which hostnameX

which hostnameX 2>/dev/null

Trong trường hợp này,

file `which hostnameX` 

sẽ tạo ra hai thông báo lỗi (cái đầu tiên, do which hostnameXvà cái thứ hai ngay sau cái trước, do chính tệp đó, phát hiện ra rằng tên tệp bị thiếu và do đó, toàn bộ lệnh

về cơ bản sẽ giảm xuống chỉ:

file

trong đó, tất nhiên, là sử dụng kém và sẽ trả về lỗi sử dụng.

(nếu bạn muốn tự mình kiểm tra, bạn có thể thử:

file `which hostnameX 2>/dev/null`    # just the file-command bad-usage error msg is printed

file `which hostnameX 2>/dev/null` 2>/dev/null  # now nothing is printed on the screen :)

4

Backtick `chạy nội dung của chuỗi đính kèm, vì vậy một cái gì đó như thế này

file `which hostname`

sẽ tìm ra đường dẫn đến lệnh hostname, và sau đó cho bạn biết nó được xây dựng như thế nào.

Lệnh mà bạn đặt trong câu hỏi của bạn chạy id -uđể có được id người dùng hiệu quả và sau đó thay đổi quyền sở hữu / somedir cho người dùng đó.


2

Biểu tượng này có nghĩa là bất cứ điều gì bên trong nó được hiểu là kết quả của lệnh đó.

ví dụ:

$ls /home
one two
$pwd
/usr/three
$cp `pwd` /home
$ls /home
one two three

Các kết quả trên trong threethư mục được sao chép vào /homethư mục của tôi .


1

Các backticks giống như thay thế lệnh. Cú pháp backticks này là cổ xưa và biết ký hiệu đô la với hai dấu ngoặc đơn là phổ biến : $().

Thay thế lệnh là gì?

Thay thế lệnh là một hoạt động đơn lẻ với cú pháp chuyên dụng để vừa thực thi một lệnh và để đầu ra của nó được lưu trữ vào một biến để sử dụng sau này.

Một ví dụ với ngày:

thedate=$(date)

Sau đó, chúng tôi có thể in kết quả: 'Ngày là% s \ n' "$ thedate" `.

  1. Cú pháp thay thế lệnh là $().
  2. Lệnh chính nó là date.
  3. Kết hợp cả hai chúng ta có được $(date)đầu ra của nó là sự thay thế.
  4. Chúng tôi hiển thị giá trị đầu ra được giữ bởi biến với printf, theo lệnh trên.
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.