Vấn đề của tôi (trong một tập lệnh với #!/bin/sh
) là như sau: Tôi cố kiểm tra tất cả các tệp trong một thư mục cho mục đích lưu trữ. Tệp tổng kiểm tra (trong trường hợp của tôi là sha1) với tất cả tên tệp sẽ nằm trong cùng một thư mục. Hãy nói rằng chúng tôi có một thư mục ~/test
với các tập tin f1
và f2
:.
mkdir ~/test
cd ~/test
echo "hello" > f1
echo "world" > f2
Bây giờ tính toán tổng kiểm với
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum
thực hiện chính xác những gì tôi muốn, nó chỉ liệt kê tất cả các tệp của thư mục hiện tại và tính toán tổng sha1 (maxdepth có thể được thay đổi sau). Đầu ra trên STDOUT là:
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
Thật không may, khi cố lưu nó vào một tệp với
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum > sums.sha1
tệp kết quả sẽ hiển thị tổng kiểm tra cho chính nó:
da39a3ee5e6b4b0d3255bfef95601890afd80709 sums.sha1
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
và do đó thất bại sau đó shasum --check
, vì vấn đề rõ ràng về sửa đổi tệp bổ sung khi lưu số tiền cuối cùng.
Tôi nhìn xung quanh và bằng cách sử dụng -p
cờ cho xargs
, tôi phát hiện ra rằng bằng cách nào đó nó tạo ra tệp đầu ra trước khi thực hiện lệnh find, do đó tệp bổ sung được tìm thấy và sẽ được kiểm tra lại ...
Tôi biết rằng như một cách giải quyết, tôi có thể lưu tổng kiểm tra vào một vị trí khác (thư mục tạm thời thông qua mktemp
) hoặc loại trừ nó một cách cụ thể, nhưng tôi muốn hiểu tại sao nó hoạt động theo cách của nó - điều này trong mắt tôi không hữu ích, ví dụ: nếu lệnh đầu tiên sẽ kiểm tra xem tệp đầu ra đã có trên đĩa chưa, nó sẽ không bao giờ có câu trả lời đúng ...
sh
yêu cầu là cần thiết. Lưu ý rằng bạn cần một đối số cho $0
trước {}
.
tee
đã biến mất? Tôi đã thử nó và nó hoạt động tốt, tôi cũng đã loại bỏ STDOUT bằng cách thêm 1>/dev/null
. Có điều gì đó sai với câu trả lời hoặc đó là một lỗi?
xargs
, chính shell tạo ra tệp này, bởi vì trước khi bất kỳ lệnh nào được thực thi, trước tiên shell sẽ chuyển hướng tất cả đầu vào, đầu ra và đường ống, để khifind
bắt đầu tệp đầu ra đã tồn tại. Sử dụng-exec
thay thế:find -maxdepth 1 -type f -exec sh -c 'shasum "$@" > sums.sha1' {} +