Trước hết, không sử dụng lsđầu ra như một danh sách tập tin . Sử dụng mở rộng vỏ hoặc find. Xem dưới đây để biết hậu quả tiềm năng của ls + xargs lạm dụng và ví dụ về hợp xargssử dụng.
1. Cách đơn giản: cho vòng lặp
Nếu bạn muốn xử lý chỉ các tệp bên dưới A/, thì một forvòng lặp đơn giản là đủ:
for file in A/*.dat; do ./a.out < "$file" > "${file%.dat}.ans"; done
2. pre1 Tại sao không ls | xargs ?
Dưới đây là một ví dụ về cách điều xấu có thể bật nếu bạn sử dụng lsvới xargscho công việc. Hãy xem xét một kịch bản sau đây:
đầu tiên, hãy tạo một số tệp trống:
$ touch A/mypreciousfile.dat\ with\ junk\ at\ the\ end.dat
$ touch A/mypreciousfile.dat
$ touch A/mypreciousfile.dat.ans
xem các tập tin và chúng không chứa gì:
$ ls -1 A/
mypreciousfile.dat
mypreciousfile.dat with junk at the end.dat
mypreciousfile.dat.ans
$ cat A/*
chạy một lệnh ma thuật bằng cách sử dụng xargs:
$ ls A/*.dat | xargs -I file sh -c "echo TRICKED > file.ans"
kết quả:
$ cat A/mypreciousfile.dat
TRICKED with junk at the end.dat.ans
$ cat A/mypreciousfile.dat.ans
TRICKED
Vì vậy, bạn chỉ cần ghi đè lên cả hai mypreciousfile.datvà mypreciousfile.dat.ans. Nếu có bất kỳ nội dung nào trong các tệp đó, nó sẽ bị xóa.
2. Sử dụng xargs : cách thích hợp với find
Nếu bạn muốn nhấn mạnh vào việc sử dụng xargs, hãy sử dụng -0(tên kết thúc null):
find A/ -name "*.dat" -type f -print0 | xargs -0 -I file sh -c './a.out < "file" > "file.ans"'
Lưu ý hai điều:
- bằng cách này, bạn sẽ tạo các tệp có
.dat.anskết thúc;
- điều này sẽ phá vỡ nếu một số tên tệp chứa dấu ngoặc kép (
").
Cả hai vấn đề có thể được giải quyết bằng cách gọi shell khác nhau:
find A/ -name "*.dat" -type f -print0 | xargs -0 -L 1 bash -c './a.out < "$0" > "${0%dat}ans"'
3. Tất cả được thực hiện trong find ... -exec
find A/ -name "*.dat" -type f -exec sh -c './a.out < "{}" > "{}.ans"' \;
Điều này, một lần nữa, tạo ra .dat.anscác tệp và sẽ phá vỡ nếu tên tệp chứa ". Để thực hiện điều đó, hãy sử dụng bashvà thay đổi cách nó được gọi:
find A/ -name "*.dat" -type f -exec bash -c './a.out < "$0" > "${0%dat}ans"' {} \;