2012-01-16 40 views
10

Tôi rất mới để bash script, và cho nỗ lực kịch bản đầu tiên của tôi tôi đang gửi tập tin vào dropbox của giáo sư của tôi trong cùng một máy chủ.Lỗi Bash Script Bắt

Mã này là thế này:

#! /bin/bash 
echo "Submit Lab$1? \c" 

read choice 

if [ $choice = "y" ]; then 
    echo "Sending to Prof's dropbox..." 
    cp -r /path/to/lab$1 /path/to/dropbox 
else 
    echo "Submission terminated." 
fi 

động sử dụng cho lệnh chỉ đơn giản là "$ submit 1" (1 là một số nguyên duy nhất, tương ứng với đó phòng thí nghiệm tôi muốn gửi)

Các kịch bản bash gắn thêm đã nhập đối số (một số nguyên) vào tên tệp cần thiết (thư mục), sau đó gửi thư mục đó tới tài khoản đăng của tôi bằng cách sử dụng cp.

Hơn nữa vì lợi ích của việc học hơn là cần thiết tuyệt đối, tôi muốn tạo một dấu nhắc rõ ràng sẽ bắt bất kỳ lỗi cp (chẳng hạn như tệp không tồn tại) và có thể xuất thông báo lỗi của riêng tôi.

Vì vậy, về cơ bản, một cái gì đó như:

echo "Submit lab$1?" 

read choice 

echo "Send to Prof's dropbox" 
cp -rv /path/to/lab$1 /path/to/dropbox 

<catch any errors from cp> 

if [ cp has errors ] 

    echo "Submission failed." 

else if [ cp has no errors ] 

    echo "Submission successful." 

And so on... 

Tôi hiểu rằng tôi có thể sử dụng chế độ verbose, và rằng cp tự in ra sai sót, nhưng như đã nói trước đây, tôi đang làm điều này với mục đích lỗi học bắt đầu và có thể tạo dấu nhắc rõ ràng.

Mọi trợ giúp sẽ được đánh giá cao.

Cảm ơn!


Ngoài ra: Tôi có một kịch bản tương tự mà nộp các phòng thí nghiệm từ máy tính xách tay của tôi, sử dụng scp. Giả sử tôi có câu hỏi này được trả lời, tôi có thể áp dụng các giải pháp để scp chính xác theo cùng một cách?

EDIT: Tôi không muốn cp lỗi xuất ra trình bao! Lỗi phổ biến nhất có thể là "không thể stat blah: không có tệp hoặc thư mục như vậy". Tôi muốn gặp lỗi đó và chỉ cần nói "Nội dung gửi không thành công".

EDIT # 2: câu trả lời của jcollado là chính xác, vấn đề là một phần của tôi. Đã không kết thúc lồng nhau if-else với đúng "fi".

Sau khi sửa chữa, nó hoạt động như dự định. Vẫn cần phải nắm bắt đầu ra lỗi nhưng tôi tin rằng tôi biết nơi tôi cần phải đi tìm con số đó một mình, vì vậy câu hỏi này được trả lời theo như tôi quan tâm.

CHỈNH SỬA CUỐI CÙNG: Ah, cái quái gì - chuyển hướng thật dễ dàng, tôi đã tìm ra giải pháp ở đây. Nếu sử dụng Linux, chỉ cần thêm "2>/dev/null" (nếu bạn không muốn thông báo lỗi được lưu trong bất kỳ tập tin) sau khi cp để làm "cp -r /first/path /second/path 2>/dev/null"

Trả lời

23

Mặc dù bạn có thể kiểm tra $ ?, bạn cũng có thể kiểm tra trạng thái thoát của một lệnh trực tiếp:

if cp -rv /path/to/lab$1 /path/to/dropbox 
then echo Submission successful 
fi 
exit $? 

Các lỗi đã được báo cáo với tiêu chuẩn lỗi của cp. exit được hiển thị sẽ thoát với trạng thái 0 (thành công) nếu cp thành công; nếu không, nó sẽ thoát với trạng thái cp đã thoát.

Rõ ràng, bạn có thể quấn vòng lặp đó nếu bạn muốn hoặc bạn có thể làm cho nó không tương tác (nhưng bất kỳ lối thoát nào đều chấm dứt tập lệnh).

+0

Cảm ơn giải pháp thay thế. Câu trả lời hay nhất dựa trên sự đơn giản. – skippr

+0

Tôi tin rằng mã thoát ở trên sẽ luôn bằng không. Nếu 'cp' thất bại (trả về non-0) thì' if' sẽ trả về 0. bash của 'echo' luôn trả về 0. Từ trang man, về' if': * Trạng thái thoát là trạng thái thoát của lệnh cuối cùng được thực hiện , hoặc bằng không nếu không có điều kiện nào được kiểm tra đúng. * –

+1

@ mr.spuratic: Có vẻ như bạn đã đúng. Chạy 'nếu đúng; sau đó lặp lại đúng; fi; echo $? 'trong Bash, Korn shell, Heirloom shell in true và sau đó là 0; thay thế nó bằng 'if false; sau đó lặp lại đúng; fi; echo $? 'và nó chỉ in 0. Vì vậy, trạng thái' $? 'không bảo toàn trạng thái thoát của lệnh được thực hiện trong' if'. Có những cách xung quanh đó, của sự thanh lịch lớn hơn hoặc ít hơn. Một cái như vậy là 'status = 0; nếu đúng; sau đó lặp lại đúng; trạng thái khác = 1; fi; echo $ status'. Hoặc bạn có thể làm nghịch đảo: 'status = 1; nếu đúng; sau đó lặp lại đúng; status = 0; fi; echo $ status'. –

8

Để kiểm tra mã trở về từ lệnh trước đó, bạn có thể sử dụng $? biến đặc biệt như sau:

if [ "$?" -ne "0" ]; then 
    echo "Submission failed" 
    exit 1 
fi 

echo "Submission successful." 

Ngoài ra, nếu bạn muốn có một dấu nhắc sạch, bạn có thể redired stderr như được giải thích here.

Cuối cùng, bạn cũng có thể sử dụng điều này trong tập lệnh sử dụng scp, vì nó hoạt động bất kể lệnh bạn đang sử dụng.

+0

Cảm ơn lời nhắc (không có ý định chơi chữ)! Tôi sẽ xem xét nhiều hơn trong các chuyển hướng stderr, vì đó dường như là nơi giải pháp "sạch dấu nhắc" nằm. Tuy nhiên, mã bạn cung cấp không hoạt động đối với các lần gửi không thành công. Nó không in "Không gửi được." khi cp thất bại. Nó tuy nhiên, bỏ qua các "Submission thành công" khi cp không thành công. – skippr

+0

Tôi nhận thấy rằng khi không thành công, không có gì sau khi nó thực thi. – skippr

+0

Ah, vấn đề là một phần của tôi. Giờ đã hiểu. Cảm ơn! – skippr

2
echo "Submit lab$1?" 

read choice 

echo "Send to Prof's dropbox" 
cp -rv /path/to/lab$1 /path/to/dropbox &>/dev/null 

[ $? -eq 0 ] && { #success, do something } || { #fail, do something } 

Và vân vân ...