http://people.cs.nctu.edu.tw/~huanghs/course/sysadm2011/slides/hw3.pdf
hw3-1
作業是一個分析 sockstat 指令的 sh one liner
Use one-line command to show per-user socket statistic
在 apua 提示下用 awk 完成了...
sockstat | tail -n+2 | sort | awk '{print $1" "$2}' | xargs | awk '{split($0,a);for (i=1;i<=NF;i+=2){c[a[i]" "a[i+1]]++;} for (i in c) {print c[i]" "i}}' | sort -k2 | xargs | awk '{split($0,a);for(i=1;i<=NF;i+=3){b[a[i+1]]+=a[i];c[a[i+1]]=sprintf("%s %s",c[a[i+1]],a[i+2]);} for (i in b){printf("%s: %s (%s )\n", i, b[i],c[i]);}}' | sort -nk2 -r | awk -v T=$THRESHOLD '{if ($2 > T) print $0}'
http://pastie.org/2794451
一步一步分析
sockstat | # 這步不用說吧XD tail -n+2 | # 從第2行開始印 # 把 USER COMMAND PID .... 濾掉 sort | # 對第一欄 (user) 排序 awk '{print $1" "$2}' | # 取出前兩欄 xargs | # 把東西通通黏起來 awk ' { split($0,a); # 東西全部裝進 a 這個 hash 裡面 for (i = 1; i <= NF; i += 2) { c[a[i]" "a[i+1]]++; # 把 "user process" 做為 key 並統計 } for (i in c) { print c[i]" "i # 印出 "sum user process" } }' | sort -k2 | # 對 user 做排序 xargs | # 黏起來 awk '{ split($0,a); # 通通裝進 a for(i=1;i<=NF;i+=3){ b[a[i+1]]+=a[i]; # 算出所有開啟 sock 數 c[a[i+1]]=sprintf("%s %s",c[a[i+1]],a[i+2]); # append 其他 process 到後面 } for (i in b){ printf("%s: %s (%s )\n", i, b[i],c[i]); 印答案出來 } }' | sort -nk2 -r | # 降序 sort awk -v T=$THRESHOLD '{ # 處理 THRESHOLD if ($2 > T) print $0 }'
===========================================
結論
把 awk 當成 Perl 來寫就沒問題囉 ^.<
作業二是比較麻煩的 zfs Snapshot Management
然後順便玩玩 parsing 指令參數這樣
這個作業學到 logger 指令的用法、然後也更熟悉 zfs 了XD
#!/bin/sh # get args d=0 count=0 while getopts f:n:c:d op do case $op in f) fs=$OPTARG;; n) name=$OPTARG;; c) count=$OPTARG;; d) d=1;; *) echo "TAs are so evil Q____Q" echo "Usage: sudo ./zfsSnap.sh -f <fs> -n <name> <-c <count> | -d>." exit 1; ;; esac done # $count should be digits and can't start by 0 count=`echo $count | grep -v [^0-9] | grep -v ^0` # all args are not NULL strings if [ -z $count ] || [ -z $fs ] || [ -z $name] ; then echo "TAs are so evil Q____Q" echo "Usage: sudo ./zfsSnap.sh -f <fs> -n <name> <-c <count> | -d>." exit 1; fi # rolling if [ $count -gt 0 ] ; then # i don't know how to write && in shell script :( if [ $d -eq 0 ] ; then # list of snapshots we want shotlist=`zfs list -r -t snapshot | cut -f1 -d' ' | tail -n+2 | grep $fs | grep $name | sort` # how many lines line=`zfs list -r -t snapshot | cut -f1 -d' ' | tail -n+2 | grep $fs | grep $name | wc -l | xargs` num=$count # need to delete something del=1 # don't need to delete if [ $line -lt $num ] ; then num=$line del=0 fi # create $num .. 0 and store it in $num while [ $num -ge 0 ] do echo $num >> QQ # TA changed requirements, so i feel Q____Q num=$(( $num -1 )) done done num=`cat QQ` rm QQ # rolling (J.K. ?) for i in $num do old=$(( $i-1 )) if [ $i -gt 0 ] ; then zfs rename $fs@$name.$old $fs@$name.$i logger -p local7.notice "zfsSnap.sh [$$]: Old snapshot: $fs@$name.$old rotated" fi done # kil oldest shot if [ $del -eq 1 ] ; then zfs destroy $fs@$name.$count logger -p local7.notice "zfsSnap.sh [$$]: Delete snapshots: $fs@$name.$(($count - 1))" fi # make a new one zfs snapshot $fs@$name.0 logger -p local7.notice "zfsSnap.sh [$$]: New snapshot: $fs@$name.0" fi fi # delete if [ $d -eq 1 ] ; then # fine all shots and just destroy them shotlist=`zfs list -r -t snapshot | cut -f1 -d' ' | tail -n+2 | grep $fs | grep $name` for i in $shotlist do zfs destroy $i logger -p local7.notice "zfsSnap.sh [$$]: Delete snapshots: $i" done fi
作業三是最好玩也是最麻煩的
RSS Feed Reader!
用 shell script 的 cdialog 做出一個 command line 底下的 RSS feed reader
為了避免麻煩,助教ㄉㄉ很 nice 的有用 Python 寫了一個 RSS parser 工具
不過我那時候還不會 Python,同時也是為了挑戰自己,用 Perl hack 了一個XD
這個 code 版本少了當初修好的 bug ...
demo 時的 code 忘記丟到哪了 orz 現在留下來的版本是後來改給 Ubuntu 的
read 功能沒有濾掉 RSS 吐給我的 XML 標籤,後還是用 sed 解決的
sed -e 's/<[^>]*>//g'
#!/bin/sh # welcome msg cdialog --title "Welcome" --msgbox "Hello world!" 5 40 # main manu menu () { cdialog --title "Main Menu" --menu "Choose Action" 12 45 5 \ R "Read - read subscribed feeds" \ S "Subscrib - new subscription" \ D "Delete - delete subscription" \ U "Update - update subscription" \ Q "Bye~" 2>/tmp/menuitem menuitem=`cat /tmp/menuitem` rm /tmp/menuitem case $menuitem in R ) return 1 ;; S ) return 2 ;; D ) return 3 ;; U ) return 4 ;; Q ) return 5 ;; esac } Read () { cdialog --title "Read" --menu "choose subscription" 12 45 5 `cat who | awk '{print NR" "$1}'` 2>/tmp/menuitem menuitem=`cat /tmp/menuitem` rm /tmp/menuitem # cdialog --title "Read" --menu "foo" 20 45 10 `cat iamben/titles | awk '{print "\""NR"\" \""$0"\""}'` 2>/tmp/menuitem # menuitem=`cat /tmp/menuitem` # rm /tmp/menuitem cdialog --msgbox "$menuitem" 5 40 } Update () { # i did it with a Perl script ./fetchRSS.pl > /dev/null } Subscrib () { cdialog --title "Subscrib" --inputbox "Enter feed url" 8 60 2>/tmp/url url=`cat /tmp/url` rm /tmp/url cdialog --title "Subscrib" --inputbox "Enter feed name" 8 60 2>/tmp/name name=`cat /tmp/name` rm /tmp/name echo $name >> who echo $url >> subscription Update } Delete () { cdialog --title "Delete" --menu "choose subscription" 12 45 5 `cat who | awk '{print NR" "$1}'` 2>/tmp/menuitem menuitem=`cat /tmp/menuitem` rm /tmp/menuitem rm -r $menuitem cat subscription | awk -v m=$menuitem '{if ( NR == m ) ; else print $0}' > s cat who | awk -v m=$menuitem '{if (NR == m) ; else print $0}' > w rm subscription rm who mv s subscription mv w who } # an infinity loop while [ 1 ] ; do menu m=$? case $m in 1 ) Read;; 2 ) Subscrib;; 3 ) Delete ;; 4 ) Update ;; 5 ) exit 0;; esac done
#!/usr/bin/perl use strict; use LWP::Simple; use XML::Feed; my @subs = (); open SUBSCRIPTION , "subscription" or die "file subscription open error: $!"; while (<SUBSCRIPTION>) { chomp; push @subs, $_; } while (<*>) { chomp; if (-d $_) { chdir $_; system ("rm *"); chdir ".."; rmdir $_ or die "QQ:$_ $!"; } } my $z = 1; for my $sub (@subs) { my $feed = XML::Feed->parse(URI->new($sub)) or die XML::Feed->errstr; mkdir $z or die "can't write directory [$z]: $!"; chdir $z or die "can't cd to directory [$z]: $!"; system("rm titles"); for my $entry ($feed->entries) { open W, sprintf(">>titles") , or die "can't write file [$z/titles] :$!"; print W $entry->title, "\n"; close W; } my $count = 1; for my $entry ($feed->entries) { open W, sprintf(">%s", $count) , or die "can't write file [$z/$count] :$!"; print W "---\n"; print W "Title: ", $entry->title, "\n"; print W "Link: \n ", $entry->link, "\n"; print W "---\n"; print W $entry->content->body, "\n"; $count++; close W; } chdir ".."; $z++; }
No comments:
Post a Comment