2014-08-27 14 views
7

Tôi mới bắt đầu viết kịch bản và học tập thông qua một số ví dụ. Một trong những ví dụ mà tôi thấy đang sử dụng một nếu-tuyên bố để kiểm tra nếu một tập tin đầu ra giao trước đây là hợp lệ, như thế này:Điều gì sẽ xảy ra nếu tuyên bố từ tập lệnh bash?

if [ -n "$outputFile" ] && ! 2>/dev/null : >> $outputFile ; then 
    exit 1 
fi 

tôi hiểu những gì [ -n "$outputFile" ] làm nhưng không phải là phần còn lại của điều kiện. Ai đó có thể giải thích những gì ! 2>/dev/null : >> $outputFile có nghĩa là gì?

Tôi đã googled cho câu trả lời nhưng hầu hết các liên kết được tìm thấy là giải thích về chuyển hướng I/O, chắc chắn có liên quan nhưng vẫn chưa rõ ràng về cấu trúc ! : >>.

+0

Bạn đã xem nó ở đâu? Và nó đã nói gì? –

+0

Có thể viết lại thành 'if [[$ outputFile]] && [[! -w $ outputFile]]; sau đó thoát ra; fi' –

+0

@glennjackman: '-w' giả định tệp đã tồn tại, vì vậy nó không giống hệt nhau. – FatalError

Trả lời

5

Đó là một số mã được viết kỳ lạ!

Lệnh : được tích hợp vào bash. Nó tương đương với true; nó không thành công gì cả.

: >> $outputFile 

không cố gắng làm gì và thêm đầu vào (trống) vào $outputFile - đã được xác nhận là chuỗi không trống. Nhà điều hành chuyển hướng >> sẽ tạo tệp nếu nó chưa tồn tại.

Chuyển hướng I/O như 2>/dev/null có thể xuất hiện ở bất kỳ đâu trong một lệnh đơn giản; họ không phải ở cuối. Vì vậy, giá trị của lệnh : (trống) được nối vào $outputFile và bất kỳ đầu ra stderr nào được chuyển hướng đến/dev/null. Bất kỳ đầu ra stderr như vậy sẽ là kết quả của một sự thất bại trong chuyển hướng, vì lệnh : chính nó không có gì và sẽ không làm như vậy. Tôi không biết lý do tại sao việc chuyển hướng stdout (vào cuối $outputFile và chuyển hướng của stderr (để /dev/null) là trên các cạnh đối diện của lệnh :

Nhà điều hành ! là một logic "không";. Nó kiểm tra . dù lệnh sau đây đã thành công, và sẽ đảo ngược kết quả

kết quả ròng, viết bằng văn bản tiếng Anh-ish là:

nếu "$ outputFile" lấy bối cảnh và không phải là một chuỗi rỗng, nếu chúng ta không có quyền ghi vào nó, sau đó chấm dứt tập lệnh với trạng thái 1.

Tóm lại, nó sẽ kiểm tra xem chúng tôi có thể viết thư cho $outputFile và không được gửi nếu không.

+1

Một phần cho giải thích kỹ lưỡng! Về lý do tại sao "chuyển hướng của stderr (đến/dev/null) là ở phía đối diện của: lệnh", tôi đã làm một số thử nghiệm. Một tập tin chỉ đọc/tmp/bob được tạo ra và tôi chạy cả hai '2>/dev/null: >>/tmp/bob' và': >>/tmp/bob 2>/dev/null'. Các bản in cũ không có gì và bản in thứ hai in 'bash:/tmp/bob: Quyền bị từ chối'. – BigHead

+0

@GongyuWang: Thật kỳ quặc; sau '2>/dev/null: >>/tmp/bob' Tôi nhận' $? '= 0 (và một tệp'/tmp/bob' trống). Tôi nhận được '$?' = 1 nếu lần đầu tiên tôi tạo '/ tmp/bob' làm thư mục hoặc như một tệp mà tôi không thể viết (mà bây giờ tôi thực sự đọc toàn bộ nhận xét của bạn, tôi nhận ra đó là những gì bạn đã làm). –

+1

@GongyuWang: Tôi có thể tránh thông báo lỗi bằng cách sử dụng ': 2>/dev/null >>/tmp/bob'. '2>/dev/null' phải đặt trước' >>/tmp/bob'; nó không phải đặt trước lệnh ':'. –

4

Tập lệnh đang cố gắng đảm bảo $outputFile có thể ghi theo cách không rõ ràng.

: là lệnh rỗng trong bash, không có gì. Thực tế là stderr được chuyển hướng đến /dev/null chỉ đơn giản là để ngăn chặn sự cho phép bị từ chối lỗi, nên một xảy ra.

Nếu tệp không ghi được, thì lệnh không thành công, điều này làm cho điều kiện trở thành true vì bị phủ nhận bằng ! và tập lệnh thoát.

+0

Câu trả lời hay và ngắn gọn! Cảm ơn. – BigHead

Các vấn đề liên quan