2009-04-14 43 views
17

Tôi sử dụng Makefile (với GNU chạy dưới Linux) để tự động hóa công việc grunt của tôi khi tái cấu trúc một tập lệnh Python. Kịch bản lệnh tạo tệp đầu ra và tôi muốn đảm bảo rằng tệp đầu ra vẫn không thay đổi khi đối mặt với các phép tái cấu trúc của tôi.Mã trạng thái vỏ trong thực hiện

Tuy nhiên, tôi không tìm thấy cách nào để lấy mã trạng thái của lệnh để ảnh hưởng đến trình bao tiếp theo nếu lệnh.

Nguyên tắc sau đây minh họa các vấn đề:

check-cond-codes: 
    diff report2008_4.csv report2008_4.csv-save-for-regression-testing; echo no differences: =$$!= 
    diff -q poalim report2008_4.csv; echo differences: =$$!= 

Đầu tiên 'diff' so sánh hai tập tin bằng nhau, và điều thứ hai so sánh hai tập tin khác nhau. Đầu ra là:

diff report2008_4.csv report2008_4.csv-save-for-regression-testing; echo no differences: =$!= 
no differences: == 
diff -q poalim report2008_4.csv; echo differences: =$!= 
Files poalim and report2008_4.csv differ 
differences: == 

Vì vậy, rõ ràng là '$$!' là biến sai để nắm bắt mã trạng thái của 'diff'. Thậm chí sử dụng SHELL: =/bin/bash khi bắt đầu Makefile không giải quyết được sự cố.

Biến trở về giá trị, mà tôi cần, sẽ (nếu tồn tại ở tất cả) được sử dụng trong lệnh 'if' trong quy tắc thực.

Việc thay thế việc tạo một kịch bản lệnh shell đặc biệt nhỏ thay cho việc viết tất cả các lệnh nội tuyến trong Makefile là không mong muốn, nhưng tôi sẽ sử dụng nó như một phương sách cuối cùng.

liên quan:

Trả lời

4

Sử dụng '$$?' thay vì '$$!' (nhờ câu trả lời thứ 4 của Exit Shell Script Based on Process Exit Code)

+0

tôi không thể tìm thấy bất cứ điều gì về '$$' trong liên kết mà bạn cung cấp!. Bạn có thể vui lòng cụ thể hơn bằng cách sửa đổi URL và cung cấp cho người trực tiếp chỉ câu trả lời 'đến thứ 4 của Exit Shell Script dựa trên Process Exit Code' bằng cách sử dụng liên kết' share' bên dưới câu trả lời thứ 4 nếu nó vẫn ở vị trí thứ 4 vị trí – SebMa

0

Biến bash là $?, nhưng tại sao bạn vẫn muốn in mã trạng thái?

-4

Hãy thử `\ $? ' Tôi nghĩ rằng $$ đang được giải thích bởi makefile

3

Đừng quên rằng mỗi lệnh của bạn đang được chạy trong các vỏ con riêng biệt.

Đó là lý do tại sao bạn khá thường xuyên nhìn thấy cái gì đó như:

my_target: 
    do something \ 
    do something else \ 
    do last thing. 

Và khi gỡ lỗi, đừng quên mỗi tùy chọn -n hữu ích mà sẽ in các lệnh nhưng không thực hiện chúng và tùy chọn -p mà sẽ cho bạn thấy môi trường làm hoàn chỉnh bao gồm các bit và phần khác nhau đã được đặt.

HTH

cổ vũ,

+1

Tại sao đây không phải là câu trả lời được chấp nhận? Áp phích gốc @Omer Zak hoạt động từ 2 ngày trước. Mặc dù nó không cung cấp câu trả lời sao chép-dán, nó trình bày chính xác kỹ thuật cần thiết để giải quyết vấn đề (Bash nhiều dòng). –

34

Tôi nghĩ rằng bạn đang tìm kiếm các biến $? vỏ, mang đến cho mã lối ra của lệnh trước đó.Ví dụ:

$ diff foo.txt foo.txt 
$ echo $? 
0 

Để sử dụng này trong makefile của bạn, bạn sẽ phải thoát khỏi $, như trong $$?:

all: 
    diff foo.txt foo.txt ; if [ $$? -eq 0 ] ; then echo "no differences" ; fi 

Đừng lưu ý rằng mỗi lệnh trong cơ thể quy tắc của bạn trong thực hiện được chạy trong một vỏ bọc riêng biệt. Ví dụ, sau đây sẽ không làm việc:

all: 
    diff foo.txt foo.txt 
    if [ $$? -eq 0 ] ; then echo "no differences" ; fi 

diffif lệnh được thực hiện trong quá trình shell khác nhau. Nếu bạn muốn sử dụng trạng thái đầu ra từ lệnh, bạn phải làm như vậy trong ngữ cảnh của cùng một shell, như trong ví dụ trước của tôi.

+0

Động lực của $$ rất hữu ích. – Arun

+1

Đồng bằng 'diff foo.txt foo.txt && echo" không có sự khác biệt "' trông mỏng hơn :) –

+0

THẬN TRỌNG: Tôi quan sát thấy rằng 'echo $$? ; 'gây ra $$? để trở thành 0 sau tiếng vang, có lẽ vì tiếng vang là một thành công. Điều này khiến cho câu lệnh if của tôi luôn đúng, để xác nhận tôi đã thử nghiệm 'echo $$ ?; echo $$ ?; 'trong trường hợp errorlevel = 1 thì echo 1 thì 0 – SketchBookGames

2

Nếu bạn đang đi qua các mã kết quả đến một if, bạn chỉ có thể làm:

all: 
    if diff foo.txt foo.txt ; then echo "no differences" ; fi 
Các vấn đề liên quan