Tại sao diff không thành công khi được gọi từ Makefile?


7

Thu hẹp vấn đề vá lỗi Tôi đang cố gắng khắc phục sự cố: Chỉ có hai tệp, mỗi tệp có kích thước 1 byte:

  • tập tin a(chứa 'a')
  • tập tin b(chứa 'b') và

Mục đích là để thực hiện và sau đó áp dụng một bản vá đó sẽ thay đổi giá trị của 'b'để 'a'. Nội dung của Makefile là:

patch:
        diff -u b a > b2a.patch
        patch -o b.corrected b < b2a.patch
        diff a b.corrected

clean:
        rm -f b2a.patch b.corrected

Cho ở trên, makethất bại với đầu ra sau:

$ make
diff -u b a > b2a.patch
make: *** [patch] Error 1

Tuy nhiên, nếu tôi thực thi các lệnh trong Makefile lần lượt từng lệnh khác trên shell bash, thì không có vấn đề gì cả.


1
những gì exit codecủa diffkhi bạn chạy nó bằng tay?
umläute

@umlaute đó là 1
Marcus Junius Brutus

@umlaute ok vì vậy thay thế 'diff' bằng '-diff' sửa nó - đó là một điều Makefile
Marcus Junius Brutus

Tôi không biết tại sao bạn muốn thực hiện và sau đó áp dụng ngay bản vá ... ví dụ: tại sao không sử dụng cp? Vì điều đó không thực sự có ý nghĩa nhiều, tôi cho rằng đây là một trường hợp thử nghiệm đơn giản hóa.
derobert

@derobert giả định của bạn là chính xác. Tôi lưu ý nhiều như vậy ở đầu bài viết của tôi ("Thu hẹp ..")
Marcus Junius Brutus

Câu trả lời:


11

Giả sử rằng mã thoát là 0 có nghĩa là thành công, bất cứ điều gì khác có nghĩa là thất bại. Đây là quy ước tiêu chuẩn được sử dụng bởi hầu hết các công cụ dòng lệnh.

Thật không may, diffkhông phải là một trong số đó. Kiểm tra trang thông tin khác biệt của GNU và mục nhập "diff" của Thông số kỹ thuật Unix đơn , 0 có nghĩa là không tìm thấy sự khác biệt nào, 1 có nghĩa là sự khác biệt được tìm thấy và ≥2 có nghĩa là lỗi.

Bạn có thể nói Make để bỏ qua trạng thái thoát hoàn toàn bằng cách thêm tiền tố lệnh bằng dấu gạch nối, như bạn đã làm trong nhận xét của mình, nhưng điều này sẽ bỏ qua các lỗi thực tế có thể không phải là điều bạn muốn. Thay vào đó, bạn có thể:

patch:
        diff -u b a > b2a.patch; [ $$? -eq 1 ]
        patch -o b.corrected b < b2a.patch
        diff a b.corrected; [ $$? -eq 1 ]

Lưu ý ; [ $$? -eq 1 ]bit tôi đã thêm vào cuối của hai dòng khác nhau. Bạn có thể sử dụng ; test $$? -eq 1là tốt, tất nhiên. Biến $?shell là $$?do các quy ước thoát Makefile bình thường. Lưu ý điều này cũng từ chối trạng thái thoát 0 (không có sự khác biệt), đó có thể là những gì bạn muốn.

BTW: có vẻ như điều này thực sự phải là:

patch: b.corrected
        diff …
b.corrected: b2a.patch
        patch …
b2a.patch: a b
        diff …

để các sửa đổi của a và b được chọn, và các tệp được phục hồi chính xác.


@Bananguin Cảm ơn bạn đã chỉnh sửa, điều đó có lẽ đúng. Tôi không hoàn toàn chắc chắn những gì OP đang cố gắng thực hiện ...
derobert

Thật ra tôi chỉ cảm thấy tệ vì phiên bản của bạn không sai, chỉ là một góc quá nhiều để tôi xử lý trước bữa tối. Tuy nhiên, bây giờ nó được đánh vần nhiều hơn: D
Bananguin

Quy ước Unix cho mã trả về rộng hơn một chút so với 0 thành công,> 0 cho thất bại. Đối với các lệnh trả về kết quả boolean, quy ước là 0 0 cho có, 1 cho không,> 1 cho thất bại. difflà một ví dụ của việc này, cũng như grep, test, ...
Gilles 'Somali dừng tà ác'

@Gilles Vâng, diffsẽ hỏi "các tệp này có khác nhau không?" ... Có thể cho rằng, diff là ngược. Nhưng tôi đoán cả nó và cmpcả hai trả về 0 cho trận đấu, 1 cho khác nhau.
derobert

@derobert diffcmphỏi những tập tin này có giống nhau không?
Gilles 'SO- ngừng trở nên xấu xa'
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.