Sử dụng lệnh sau đây, ai đó có thể vui lòng giải thích chính xác mục đích cho dấu ngoặc nhọn kết thúc ({}) và dấu cộng (+) là gì không?
Và làm thế nào để lệnh hoạt động khác nhau nếu chúng bị loại khỏi lệnh?
find . -type d -exec chmod 775 {} +
Sử dụng lệnh sau đây, ai đó có thể vui lòng giải thích chính xác mục đích cho dấu ngoặc nhọn kết thúc ({}) và dấu cộng (+) là gì không?
Và làm thế nào để lệnh hoạt động khác nhau nếu chúng bị loại khỏi lệnh?
find . -type d -exec chmod 775 {} +
Câu trả lời:
Các dấu ngoặc nhọn sẽ được thay thế bằng kết quả của find
lệnh và chmod
sẽ được chạy trên mỗi hàm. Các +
làm cho find
cố gắng chạy càng ít lệnh càng tốt (như vậy, chmod 775 file1 file2 file3
như trái ngược với chmod 755 file1
, chmod 755 file2
, chmod 755 file3
). Không có chúng, lệnh sẽ chỉ báo lỗi. Tất cả điều này được giải thích trong man find
:
-exec command ;
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 sẽ
find
được coi là đối số cho lệnh cho đến khi;
gặp phải đố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ố của lệnh, không chỉ trong các đối số chỉ có một mình, như trong một số phiên bảnfind
. Giáo dục
-exec command {} +
Biến thể
-exec
hà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 tạo 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. Giáo dục
Ngoài câu trả lời của terdon,
-exec …
phải chấm dứt với một dấu chấm phẩy ( ;
) hoặc dấu cộng ( +
). Dấu chấm phẩy là một nhân vật đặc biệt trong vỏ (hoặc, ít nhất, mỗi shell Tôi đã từng sử dụng), do đó, nếu nó được sử dụng như một phần của find
lệnh , nó phải được thoát ra hoặc trích dẫn ( \;
, ";"
hoặc ';'
).Với -exec … ;
, {}
chuỗi có thể xuất hiện bất kỳ số lần nào trong lệnh, bao gồm 0 hoặc hai hoặc nhiều hơn, ở bất kỳ vị trí nào.
Xem điều này
để biết ví dụ về lý do tại sao bạn có thể muốn làm -exec
mà không sử dụng {}
.
Có hai hoặc nhiều lần xuất hiện là hữu ích chủ yếu bởi vì, trong (ít nhất) một số phiên bản của find
, {}
không cần phải là một từ; nó có thể có các nhân vật khác ở đầu hoặc cuối; ví dụ,
find . -type f -exec mv {} {}.bak ";"
Với -exec … +
, {}
chuỗi phải xuất hiện như là đối số cuối cùng trước +
. Một lệnh như
find . -name "*.bak" -exec mv {} backup_folder +
kết quả trong find: missing argument to ‘-exec’
thông báo lỗi bí ẩn .
Một cách giải quyết cho điều này đặc trưng cho các lệnh cp
và mv
là
find . -name "*.bak" -exec mv -t backup_folder {} +
hoặc là
find . -name "*.bak" -exec mv --target-directory=backup_folder {} +
Các {}
phải là một từ bằng cách riêng của mình; nó không thể có các ký tự khác ở đầu hoặc cuối. Và, trong (ít nhất) một số phiên bản find
, bạn có thể không có nhiều hơn một {}
.
Một lưu ý tỉnh táo: Bạn có thể nói
tìm thấy . -name "* .sh" -type f -executable -exec {} tùy chọn đối số ở đây ";"
để chạy từng tập lệnh của bạn. Nhưng
tìm thấy . -name "* .sh" -type f -executable -exec {} +
chạy một trong các tập lệnh của bạn, với tên của tất cả các tập lệnh khác làm tham số. Điều này tương tự như nói
./*.sh
như một lệnh shell, ngoại trừ find
không đảm bảo rằng nó sắp xếp kết quả của nó, vì vậy bạn không được đảm bảo chạy aaa.sh
( *.sh
tệp đầu tiên theo thứ tự bảng chữ cái của bạn ) như khi bạn chạy ./*.sh
.
Một khía cạnh của find
điều đó có thể không hoàn toàn rõ ràng đối với người mới bắt đầu là dòng lệnh, một cách hiệu quả, là một câu lệnh thực thi trong một ngôn ngữ phức tạp. Ví dụ,
find . -name "*.sh" -type f -executable -print
có nghĩa
for each file
if the file’s name matches `*.sh` (i.e., if it ends with `.sh`)
then
if it is a plain file (i.e., not a directory)
then
if it is executable (i.e., the appropriate `---x--x--x` bit is set)
then
print the file’s name
end if
end if
end if
end loop
hoặc đơn giản,
for each file
if the file’s name matches `*.sh` AND it is a plain file AND it is executable
then
print the file’s name
end if
end loop
Một số -
từ khóa là cả một hành động thực thi và kiểm tra. Đặc biệt, điều này đúng cho -exec … ;
; ví dụ,
find . -type f -exec grep -q cat {} ";" -print
Dịch sang
cho mỗi tập tin nếu nó là một tập tin đơn giản (nghĩa là không phải là một thư mục) sau đó thực hiện tên tập tin mèo grep -q nếu quá trình thành công (nghĩa là thoát với trạng thái 0) sau đó in tên tập tin kết thúc nếu kết thúc nếu kết thúc vòng lặp
mà sẽ in tên của tất cả các file có chứa chuỗi “ cat
”. Và, trong khi đây là điều grep
có thể tự làm (với tùy chọn -l
(chữ thường L
)), có thể hữu ích khi sử dụng nó find
để tìm các tệp có chứa một chuỗi nhất định VÀ có kích thước nhất định VÀ được sở hữu bởi một chủ sở hữu nhất định VÀ đã được sửa đổi trong một phạm vi thời gian nhất định, Hoài.
Tuy nhiên, điều này không làm việc cho -exec … +
. Vì -exec … +
thực thi một lệnh cho nhiều tệp, không có nghĩa gì khi sử dụng nó làm điều kiện logic bên trong một for each file …
vòng lặp.
find
thường thoát với trạng thái thoát là 0 trừ khi bạn đưa ra các đối số không hợp lệ hoặc nó gặp một thư mục mà nó không thể đọc được. Ngay cả khi một chương trình mà bạn thực thi không thành công (thoát với trạng thái thoát khác không),
find
sẽ thoát với trạng thái thoát là 0.
Ngoại trừ nếu một chương trình mà bạn thực hiện -exec … +
không thành công (thoát với trạng thái thoát khác không),
find
sẽ thoát với trạng thái thoát không bằng không.Ngoài một triệu phiên bản find(1)
và thử nghiệm những gì find
thực sự có trên một vài hệ thống,
Phiên bản Thông số kỹ thuật cơ sở nhóm mở số 7, 2013 Edition
cung cấp một số thông tin về những gì find
phải, có thể và không được làm.
... -exec mv {} {}.bak ...
không được đảm bảo để hoạt động như mong đợi với tất cả cácfind
triển khai. Các trạng thái tiêu chuẩn POSIX{}
phải xuất hiện một mình để luôn được nhận dạng, nếu không, hành vi được tự do giữ các ký tự không thay đổi hoặc thay thế chúng bằng tên đường dẫn. Trong trường hợp trước, toàn bộ lệnh của bạn về cơ bản sẽ xóa tất cả các tệp nhưng lệnh cuối cùng được tìm thấy ...