サンプルプログラム集

提供: Wikinote
2011年2月26日 (土) 03:03時点におけるHagio (トーク | 投稿記録)による版 (Python)

移動: 案内検索

C

Python

tcp_server.py / tcp_client.py

簡単な TCP サーバ / クライアントプログラム。例外処理はある程度まで。

tcp_server.py <toggledisplay>

#!/usr/bin/env python
import sys, socket

port = 55555
if len(sys.argv) > 1:
    try:
        port = int(sys.argv[1])
    except:
        print "Ivalid port number"
        sys.exit(1)

try:
    sock = socket.socket()
    sock.bind(("", port))
    sock.listen(5)
except socket.error, msg:
    print msg
    sys.exit(1)
    
while True:
    print "Waiting for a connection (port: %d)..." % port
    try:
        csock, addr = sock.accept()
        print "Connected by %s:%d" % addr
        while True:
            try:
                buf = csock.recv(1024)
                if not buf:
                    print "Disconnected."
                    break
                print "Received : %s" % buf
            except KeyboardInterrupt:
                break
        csock.close()
    except KeyboardInterrupt:
        break
sock.close()

</toggledisplay>

tcp_client.py <toggledisplay>

#!/usr/bin/env python
import sys, socket

if len(sys.argv) < 2:
    print "Usage: %s host [port]" % sys.argv[0]
    sys.exit(1)

host = sys.argv[1]
port = 55555
if len(sys.argv) > 2:
    try:
        port = int(sys.argv[2])
    except ValueError:
        print "Invalid port number"
        sys.exit(1)

try:
    sock = socket.socket()
    sock.connect((host, port))
except socket.error, msg:
    print msg
    sys.exit(1)
print "Connected to %s:%d" % (host, port)
while True:
    try:
        buf = raw_input("> ")
        if buf == "q":
            break
        sock.send(buf)
    except KeyboardInterrupt:
        break
sock.close()

</toggledisplay>

実行例 <toggledisplay>

サーバ側:
$ ./tcp_server.py 12345
Waiting for a connection (port: 12345)...
Connected by 127.0.0.1:51522
Received : test data
Disconnected.
Waiting for a connection (port: 12345)...

クライアント側:
$ ./tcp_client.py localhost 12345
Connected to localhost:12345
> test data
> 
> quit

</toggledisplay>

memcurses.py

curses (libcurses) を利用した /proc/meminfo の変化量を表示するスクリプト。

ソースコード <toggledisplay>

#!/usr/bin/env python
import sys, time, curses

def main(argv):
    win = curses.initscr()
    if len(argv) > 1:
        interval = int(argv[1])
    else:
        interval = 1

    f = open("/proc/meminfo", "r")
    prev = []
    while True:
        win.clear()
        win.addstr(0, 0, "Every %d.0s : %s" % (interval, time.ctime()))
        i = 0
        try:
            for line in f:
                win.addstr(i+2, 0, line[:-1])
                cur = line.split()[1]
                try:
                    if cur != prev[i]:
                        win.addstr(" %+d" % (int(cur) - int(prev[i])))
                        prev[i] = cur
                except IndexError:
                    prev.append(cur)
                i += 1
            win.addstr("\n")
            win.refresh()
            f.seek(0)
            time.sleep(interval)
        except KeyboardInterrupt:
            break

    curses.endwin()
    f.close()
    return 0

if __name__ == "__main__":
    sys.exit(main(sys.argv))

</toggledisplay>

実行例 <toggledisplay>

$ ./memcurses.py 5
Every 5.0s : Sat Feb 26 01:06:31 2011

MemTotal:      5968984 kB
MemFree:        458472 kB
Buffers:        292224 kB +8
Cached:        4135716 kB
SwapCached:          0 kB
Active:        2248520 kB +44
Inactive:      2798728 kB
HighTotal:     5241152 kB
HighFree:       449732 kB
LowTotal:       727832 kB
LowFree:          8740 kB
SwapTotal:     6144852 kB
SwapFree:      6144716 kB
Dirty:             456 kB
Writeback:           0 kB
AnonPages:      619336 kB +32
Mapped:        1179140 kB +112
Slab:           111936 kB -44
PageTables:      12296 kB +52
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:   9129344 kB
Committed_AS:  1629408 kB
VmallocTotal:   116728 kB
VmallocUsed:     19364 kB
VmallocChunk:    97136 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     2048 kB

</toggledisplay>

grep.py

grep -Hn と同様の出力となるスクリプト。 標準入力からの入力には非対応。

ソースコード <toggledisplay>

#!/usr/bin/env python
import sys, re, threading

def grep(reg, path):
    f = open(path, "r")
    row = 1
    for line in f:
        if reg.search(line):
            print "%s:%d:%s" % (path, row, line),
        row += 1
    f.close()

if __name__ == "__main__":
    if len(sys.argv) > 2:
        reg = re.compile(sys.argv[1])
        for path in sys.argv[2:]:
            grep(reg, path)
    else:
        print "Usage: %s PATTERN FILES.." % sys.argv[0]
        sys.exit(1)

</toggledisplay>

実行例 <toggledisplay>

$ ./grep.py
Usage: ./grep.py PATTERN FILES..
$ ./grep.py while *.py
graph.py:9:    while 1:
memcurses.py:13:    while True:
memstat.py:12:    while True:
ncurses.py:8:    while True:
netmonitor.py:32:    while 1:
netstat.py:67:        while True:
netstat.py:132:while True:
open.py:12:while True:
pystat.py:85:while True:
sdx.py:9:    while (q > 0):
tcp_client.py:13:while True:
tcp_server.py:8:while 1:
tcp_server.py:13:        while True:

</toggledisplay>

wc.py

Python で作った wc コマンド。

ソースコード <toggledisplay>

#!/usr/bin/env python
import sys, getopt

def usage():
    print "Usage: %s [-cmlLw] FILES" % sys.argv[0]

def wc(f):
    (c, m, l, L, w) = (0, 0, 0, 0, 0)
    for line in f:
        c += len(line)
        m += len(line.decode('UTF-8'))
        l += 1
        L  = max(L, len(line)-1)
        w += len(line.split())
    return (c, m, l, L, w)

if __name__ == "__main__":
    try:
        opts, args = getopt.getopt(sys.argv[1:], "cmlLw")
    except getopt.GetoptError:
        usage()
        sys.exit(1)

    # set defaults
    opt_c = True  # bytes
    opt_m = False # chars 
    opt_l = True  # lines
    opt_L = False # max-line-length
    opt_w = True  # words

    if opts:
        (opt_c, opt_l, opt_w) = (False, False, False)
    for (opt, val) in opts:
        if opt == "-c":
            opt_c = True
        elif opt == "-m":
            opt_m = True
        elif opt == "-l":
            opt_l = True
        elif opt == "-L":
            opt_L = True
        elif opt == "-w":
            opt_w = True

    (total_c, total_m, total_l, total_L, total_w) = (0, 0, 0, 0, 0)
    if not args:
        args.append("-")
    for arg in args:
        if arg == "-":
            f = sys.stdin
        else:
            f = open(arg, "r")
        (c, m, l, L, w) = wc(f)
        f.close()
        if opt_l:
            print " %5d" % l,
        if opt_w:
            print " %5d" % w,
        if opt_m:
            print " %5d" % m,
        if opt_c:
            print " %5d" % c,
        if opt_L:
            print " %5d" % L,
        print arg
        total_c += c
        total_m += m
        total_l += l
        total_L = max(total_L, L)
        total_w += w

    if len(args) > 1:
        if opt_l:
            print " %5d" % total_l,
        if opt_w:
            print " %5d" % total_w,
        if opt_m:
            print " %5d" % total_m,
        if opt_c:
            print " %5d" % total_c,
        if opt_L:
            print " %5d" % total_L,
        print "total"

</toggledisplay>

実行例 <toggledisplay>

$ ./wc.py -h
Usage: ./wc.py [-cmlLw] FILES
$ ./wc.py -clmwL *.py | addspace 
    29     80    438    438     45 awk.py
    28     82    719    719     59 buddy.py
    23     70    531    531     65 calc_buddy.py
     4     12     79     79     28 compare.py
    21     55    444    444     43 dec2bin.py
    35     98   1000   1000     49 decode_actlog.py
    87    255   2287   2287     51 graph.py
    20     58    475    475     55 grep.py
    24     78    498    498     43 hex2bin.py
    79    207   1790   1790     71 mail.py
   127    347   3129   3129    109 mail2pens.py
    40     91   1003   1003     71 memcurses.py
    38     77    881    881     63 memstat.py
    21     35    398    398     41 ncurses.py
    54    134   1463   1463    101 netmonitor.py
   144    590   4967   4967    129 netstat.py
    19     30    246    246     40 open.py
    33    105    916    916     57 pygrep.py
   124    376   2977   2977     80 pystat.py
    24     73    510    510     52 sdx.py
    19     43    331    331     40 tcp_client.py
    24     52    523    523     46 tcp_server.py
    84    277   1983   1983     67 wc.py
  1101   3225  27588  27588    129 total
 lines  words  chars  bytes maxlen

</toggledisplay>

calc_buddy.py

/proc/buddyinfo のそれぞれのゾーンの合計サイズを計算するスクリプト。 タイムスタンプを付けて記録したファイルにも対応。

ソースコード <toggledisplay>

#!/usr/bin/env python
import sys

if len(sys.argv) == 1:
    files = [ open('/proc/buddyinfo', 'r') ]
    ts_shift = 4;
else:
    files = [ open(f) for f in sys.argv[1:] ]
    ts_shift = 6;

for file in files:
    for line in file:
        if len(line) > 1:
            print line[:-1],
            fields = line.split()
            total = 0
            for val in range(0,11):
                total += int(fields[ts_shift + val]) * 4 * 2**val
            print total, "KB"
        else:
            print line,
    file.close()
</toggledisplay>

実行例 <toggledisplay>

$ ./calc_buddy.py 
Node 0, zone      DMA     46      5      3      0      0      0      0      1      1      1      0  3856 KB
Node 0, zone   Normal    327      2      1      1      1      1      1      0      0      0      1  5916 KB
Node 0, zone  HighMem  78051  15607    279      2     59     17      2      0      0      0      0  448052 KB

</toggledisplay>

dec2bin.py

10 進数を 2 進数に変換するスクリプト。32 ビット限定。

ソースコード <toggledisplay>

#!/usr/bin/env python
import sys

def dec2bin(dec):
    ret = ""
    for i in range(31, -1, -1):
        if dec & (1 << i):
            ret += "1"
        elif ret:
            ret += "0"
    return ret

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print "Usage: %s dec" % sys.argv[0]
        sys.exit(1)
    try:
        print dec2bin(int(sys.argv[1]))
    except ValueError:
        print "Invalid number"
        sys.exit(1)

</toggledisplay>

実行例 <toggledisplay>

$ ./dec2bin.py 12345
11000000111001
$ ./dec2bin.py 1024
10000000000
$ ./dec2bin.py -65536
11111111111111110000000000000000
$ ./dec2bin.py 2147483647
1111111111111111111111111111111
$ ./dec2bin.py -2147483648
10000000000000000000000000000000

</toggledisplay>