Việc sử dụng dấu ngoặc nhọn {} làm đối số cho các lệnh và tùy chọn của chúng


11

Ví dụ

Gần đây tôi đã tìm thấy các ví dụ về việc sử dụng các cặp dấu ngoặc nhọn {}, không có gì ở giữa dấu ngoặc mở và đóng, làm đối số cho các lệnh và thậm chí cho các tùy chọn của chúng:

cat foo | xargs -I{} echo {}

find . -size 0 -exec rm -i {} \;

Không có tài liệu

Vấn đề của tôi là tôi không thể tìm thấy một tài liệu trong Hướng dẫn sử dụng GNU Bash mô tả việc sử dụng {}trong ngữ cảnh như trong các ví dụ ở trên.

Tôi không nghĩ rằng đó là một mở rộng tham số , bởi vì một ký hiệu đô la phải đi trước các dấu ngoặc nhọn trong một mở rộng tham số như trong ${}.

Nó cũng không thể là một mở rộng cú đúp , bởi vì nó có hình thức {x..y[..incr]}, ở đâu xykhông phải là tùy chọn.

Nó cũng không thể là một nhóm lệnh , bởi vì {}được sử dụng làm đối số.

Câu hỏi

  1. {}Nói chung, một cặp niềng răng kèm theo có ý nghĩa gì, như là một đối số cho bất kỳ lệnh nào chấp nhận nó?

  2. Tôi có thể tìm tài liệu mô tả việc sử dụng {}làm đối số ở đâu?


Một số lệnh có các tùy chọn này {}- có nghĩa là targetshành động, với findlệnh, đó là xóa / rmtìm thấy tệp.
Tuyên Phạm

Câu trả lời:


16

Những dấu ngoặc nhọn này được để lại một mình bởi bash; chúng thuộc findxargs, tương ứng, và được mô tả trong trang người đàn ông của họ.

man find

-exec chỉ huy ;

Thực thi lệnh ; đúng nếu trạng thái 0 được trả về. Tất cả các đối số sau đây cần tìm được lấy làm đối số cho lệnh cho đến khi gặp một đối số bao gồm ;. Chuỗi {}được thay thế bằng tên tệp hiện tại đang được xử lý ở mọi nơi nó xuất hiện trong các đối số cho lệnh, không chỉ trong các đối số chỉ có một mình, như trong một số phiên bản find. Cả hai công trình này có thể cần phải được thoát ra (với a \) hoặc được trích dẫn để bảo vệ chúng khỏi sự mở rộng của vỏ. Xem phần EXAMPLES để biết ví dụ về việc sử dụng -exectùy chọn. Các quy định lệnhđược chạy một lần cho mỗi tệp phù hợp. Lệnh được thực thi trong thư mục bắt đầu. Có những vấn đề bảo mật không thể tránh khỏi xung quanh việc sử dụng -exec hành động; bạn nên sử dụng -execdirtùy chọn thay thế.

-exec chỉ huy {} +

Biến thể -exechành động này chạy lệnh được chỉ định trên các tệp đã chọn, nhưng dòng lệnh được xây dựng bằng cách nối thêm từng tên tệp đã chọn ở cuối; tổng số lệnh gọi của lệnh sẽ ít hơn nhiều so với số lượng tệp được khớp. Dòng lệnh được xây dựng theo cách tương tự như cách xargsxây dựng các dòng lệnh của nó. Chỉ một trường hợp {}được cho phép trong lệnh. Lệnh được thực thi trong thư mục bắt đầu. Nếu findgặp lỗi, điều này đôi khi có thể gây ra lối thoát ngay lập tức, do đó một số lệnh đang chờ xử lý có thể không được chạy. Biến thể này -execluôn luôn trả về đúng sự thật.

-execdir chỉ huy ;

-execdir chỉ huy {} +

Giống như -exec, nhưng lệnh được chỉ định được chạy từ thư mục con chứa tệp phù hợp, thường không phải là thư mục mà bạn bắt đầu tìm thấy. Đây là một phương pháp an toàn hơn nhiều để gọi các lệnh, vì nó tránh các điều kiện chạy đua trong khi giải quyết các đường dẫn đến các tệp phù hợp. Như với -exec hành động, + hình thức -execdir sẽ xây dựng một dòng lệnh để xử lý nhiều hơn một tệp phù hợp, nhưng bất kỳ lệnh gọi nào được đưa ra sẽ chỉ liệt kê các tệp tồn tại trong cùng thư mục con. Nếu bạn sử dụng tùy chọn này, bạn phải đảm bảo rằng $PATHbiến môi trường của bạn không tham chiếu.; mặt khác, kẻ tấn công có thể chạy bất kỳ lệnh nào chúng thích bằng cách để lại tệp có tên thích hợp trong thư mục mà bạn sẽ chạy -execdir. Điều tương tự cũng áp dụng cho việc có các mục trong $PATHđó trống hoặc không phải là tên thư mục tuyệt đối. Nếu findgặp lỗi, điều này đôi khi có thể gây ra lối thoát ngay lập tức, do đó một số lệnh đang chờ xử lý có thể không được chạy. Kết quả của hành động phụ thuộc vào việc biến thể +hoặc ;biến thể đang được sử dụng; -execdir lệnh {} + luôn trả về true, trong khi -execdir lệnh chỉ {} ; trả về true nếu lệnh trả về 0.

man xargs

-I thay thế

Thay thế các lần xuất hiện của str-str trong các đối số ban đầu bằng các tên được đọc từ đầu vào tiêu chuẩn. Ngoài ra, khoảng trống không được trích dẫn không chấm dứt các mục đầu vào; thay vào đó dấu phân cách là ký tự dòng mới. Ngụ ý -x-L 1.

-i[ thay thế-str ], --replace[ =thay thế-str ]

Tùy chọn này là một từ đồng nghĩa với -Ithay thế nếu str-str được chỉ định. Nếu đối số str-str bị thiếu, hiệu ứng sẽ giống như -I{}. Tùy chọn này không được chấp nhận; sử dụng -Ithay thế.

Chỉnh sửa: và ở đây TẠI SAO bash bỏ qua các dấu ngoặc nhọn:

man bash

{ danh sách; }

danh sách được thực hiện đơn giản trong môi trường shell hiện tại. danh sách phải được chấm dứt bằng một dòng mới hoặc dấu chấm phẩy. Điều này được gọi là một lệnh nhóm. Trạng thái trả về là trạng thái thoát của danh sách. Lưu ý rằng không giống như các siêu ký tự () , {} là các từ dành riêng và phải xảy ra khi một từ dành riêng được phép được công nhận. Vì chúng không gây ra ngắt từ, chúng phải được tách ra khỏi danh sách bằng khoảng trắng hoặc metacharacter vỏ khác.

Để nhấn mạnh: danh sách phải được chấm dứt bằng một dòng mới hoặc dấu chấm phẩy .


1
Cảm ơn bạn! Tôi bực mình vì bất cứ ai viết man xargsthậm chí không bận tâm giải thích ý {}nghĩa thực sự của nó, tác giả cũng không chuyển hướng (không có ý định chơi chữ) cho người đọc để giải thích -exectrong trang của find.
Niko Gambt

@NikoGambt - Tôi thông cảm ...
tink

5
@NikoGambt Chà, {} thực sự không có ý nghĩa gì với xargs, ngoại trừ việc là giá trị mặc định cho -i, không được dùng nữa. Tôi không chắc lời giải thích nào là cần thiết ngoài điều đó. Trong ví dụ bạn đã đăng, nó cũng có thể đã được xargs -Iab echo ab; đó là một sự lựa chọn hoàn toàn tùy ý.
Random832

@ Random832 Sau khi thực hiện thêm một số thử nghiệm với -I, bây giờ tôi hiểu tùy chọn đó thực sự làm gì. Vâng, {}là tùy ý, như bạn đã nói. Tôi chỉ bối rối bởi lời giải thích If the replace-str argument is missing, the effect is the same as -I{}. Nếu -Ikhông có đối số giống như -I{}, thì cat foo | xargs -I echo {}sẽ tạo ra kết quả tương tự như khi chạy cat foo | xargs -I{} echo {}. Tuy nhiên, chúng không giống nhau. Cái trước là một lỗi, và điều làm tôi bối rối hơn nữa là thông báo lỗi xargs: {}: No such file or directory, nhưng đó chỉ là do thực hiện.
Niko Gambt

1
@NikoGambt -I(chữ hoa I) không thể chạy mà không có đối số. Đối số -Iecho. Đây là sự khác biệt chính giữa -I-i(và lý do -i không được chấp nhận, vì các tùy chọn với các đối số không bắt buộc là không phổ biến và khó hiểu)
Random832
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.