Shell script không thể awk tạo tập tin


7

Tôi đang cố gắng tạo một số kịch bản kiểm tra pass / fail đơn giản, nhưng tôi đang gặp một số thách thức như được nêu dưới đây. Mục đích của tôi là lấy toàn bộ kết quả của một lệnh (chẳng hạn như ping) vào một results.txttệp để giữ, nhưng cũng phân tích results.txttệp để kiểm tra khác nhau nếu phát hiện ra vấn đề:

#!/bin/bash
ping -c 20 google.com > results.txt
packetloss = `awk '/packet loss/{x=$6} END{print x}' results.txt`
echo "$packetloss" >> debug.txt
#  if packetloss > 0, add to an error.txt to fail
#  if avg ping time > 5ms, add to an error.txt to fail

Biến packloss không nhận được awkthông tin từ results.txttệp (gửi đến tệp gỡ lỗi để xem xét). Tôi đã tự hỏi nếu có một cái gì đó về kịch bản shell sẽ ngăn chặn điều này và một cách giải quyết liên quan?

Chạy thủ công awkvới results.txtlợi nhuận '0%', đó là kết quả mong đợi.

Câu trả lời:


11

Không gian không được phép xung quanh =!

Vì thế:

#!/bin/bash
ping -c 20 google.com > results.txt
packetloss=$(awk '/packet loss/{print $6}' results.txt)
echo "$packetloss" >> debug.txt

Hoặc thậm chí ngắn hơn:

ping -c 20 google.com |
    awk '/packet loss/{sub(/%/, "");print $6 >> "debug.txt"}'

GHI CHÚ:

  • Không cần gán xbiến; bạn có thể in $6trực tiếp
  • Bản thân AWK có thể tạo các tệp mới với đầu ra của nó
  • Các backquote
    `
    được sử dụng để thay thế lệnh kiểu cũ, ví dụ:
foo = `lệnh`

Các foo=$(command)cú pháp được khuyến khích để thay thế. Xử lý dấu gạch chéo ngược bên trong $()ít gây ngạc nhiên hơn và $()dễ dàng hơn để làm tổ.

Kiểm tra http://mywiki.wooledge.org/BashFAQ/082

Giải pháp bổ sung sử dụng Perl :

ping -c 20 google.com |
    perl -lne '/(\d+)%\s+packet\s+loss/ and print $1' >> debug.txt

1
bingo - đó phải là vấn đề số một với các lập trình viên ngôn ngữ biên dịch đang cố gắng viết các tập lệnh :-P
dhartford

chỉ để biết thêm, có cách nào để sử dụng awk để không bao giờ hiển thị '%' hoặc các ký tự tương tự không?
dhartford

Có, POST được chỉnh sửa tương ứng, kiểm trasub()
Gilles Quenot

1
#!/usr/bin/perl
my $host=shift or die("Usage $0 host\n");

open(PING , "-|", "ping -c 20 $host") or die;
open(DEBUG, ">>", "debug.txt"       ) or die; 

while(<PING>){
  if(m!(\d+)% packet loss!     ){ $Lost=$1 }
  if(m!rtt.*= (.+?)/(.+?)/(.+)!){ $Avg=$2  }
}

if   ( $Lost > 0 ) { print DEBUG "not ok: lost pcks ($Lost%)\n"    }
elsif( $Avg  > 5 ) { print DEBUG "not ok: too slow  ($Avg)\n"      }
else               { print DEBUG "ok: ping\n"                      }

Xử lý tập tin toàn cầu nên tránh. Thay vào đó hãy sử dụng:open my $debug, ">>", "debug.txt" or die $!;
Gilles Quenot

@sputnick: cảm ơn bạn. Bạn đúng hoặc tất nhiên. Tôi chỉ cố làm cho nó trông đơn giản hơn ... (luôn là một lựa chọn nguy hiểm) :)
JJoao 31/12/14
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.