「サンプルプログラム集」の版間の差分
(→C) |
(ToggleDisplay から mw-collapsible に変更) |
||
(同じ利用者による、間の7版が非表示) | |||
行1: | 行1: | ||
+ | TP の素を揃えておこうかと。 | ||
+ | |||
== C == | == C == | ||
行5: | 行7: | ||
コマンド引き数で与えられた数だけ、ただ寝てるだけのスレッドを生成するプログラム。 | コマンド引き数で与えられた数だけ、ただ寝てるだけのスレッドを生成するプログラム。 | ||
− | ソースコード < | + | <div class="mw-collapsible mw-collapsed"> |
+ | ソースコード | ||
+ | <div class="mw-collapsible-content"> | ||
#include <stdio.h> | #include <stdio.h> | ||
#include <stdlib.h> | #include <stdlib.h> | ||
行36: | 行40: | ||
return 0; | return 0; | ||
} | } | ||
− | </ | + | </div></div> |
− | 実行例 < | + | <div class="mw-collapsible mw-collapsed"> |
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
$ cc -l pthread -o pthread pthread.c | $ cc -l pthread -o pthread pthread.c | ||
$ ./pthread | $ ./pthread | ||
行55: | 行61: | ||
$ kill $! | $ kill $! | ||
[1]+ 終了しました ./pthread 3 | [1]+ 終了しました ./pthread 3 | ||
− | </ | + | </div></div> |
+ | |||
+ | === fork.c === | ||
+ | |||
+ | コマンド引き数で与えられた数だけ fork して、ゾンビ状態で放置するプログラム。 | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | ソースコード | ||
+ | <div class="mw-collapsible-content"> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | #include <sys/types.h> | ||
+ | |||
+ | int main(int argc, char *argv[]) { | ||
+ | int i, num; | ||
+ | pid_t pid; | ||
+ | |||
+ | if (argc < 2) { | ||
+ | printf("Usage %s procs\n", argv[0]); | ||
+ | return 0; | ||
+ | } | ||
+ | if ((num = atoi(argv[1])) < 0) { | ||
+ | printf("arg 1 = %d\n", num); | ||
+ | return 0; | ||
+ | } | ||
+ | for (i = 0; i < num; i++) { | ||
+ | pid = fork(); | ||
+ | if (pid < 0) { | ||
+ | perror("fork"); | ||
+ | return 1; | ||
+ | } else if (pid == 0) { | ||
+ | printf("Child %d\n", i); | ||
+ | //while (1) sleep(1); | ||
+ | return 0; | ||
+ | } else { | ||
+ | printf("Parent %d (PID: %d)\n", i, pid); | ||
+ | } | ||
+ | } | ||
+ | while (1) sleep(1); | ||
+ | return 0; | ||
+ | } | ||
+ | </div></div> | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
+ | $ cc -o fork fork.c | ||
+ | $ ./fork 3 | ||
+ | Child 0 | ||
+ | Parent 0 (PID: 1197) | ||
+ | Child 1 | ||
+ | Parent 1 (PID: 1198) | ||
+ | Child 2 | ||
+ | Parent 2 (PID: 1199) | ||
+ | $ ps -elf | grep fork | ||
+ | 0 S hagio 1196 13327 0 75 0 - 378 - 10:30 pts/5 00:00:00 ./fork 3 | ||
+ | 1 Z hagio 1197 1196 0 76 0 - 0 exit 10:30 pts/5 00:00:00 [fork] <defunct> | ||
+ | 1 Z hagio 1198 1196 0 77 0 - 0 exit 10:30 pts/5 00:00:00 [fork] <defunct> | ||
+ | 1 Z hagio 1199 1196 0 77 0 - 0 exit 10:30 pts/5 00:00:00 [fork] <defunct> | ||
+ | 0 S hagio 1208 31213 0 78 0 - 1245 pipe_w 10:30 pts/4 00:00:00 grep fork | ||
+ | </div></div> | ||
+ | |||
+ | === setro.c === | ||
+ | |||
+ | ioctl のサンプル。ブロックデバイスの読み込み専用フラグを変更するプログラム。 | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | ソースコード | ||
+ | <div class="mw-collapsible-content"> | ||
+ | #include <stdio.h> | ||
+ | #include <fcntl.h> | ||
+ | #include <linux/fs.h> | ||
+ | |||
+ | int main(int argc, char* argv[]) { | ||
+ | int fd, res, flag; | ||
+ | |||
+ | if (argc != 3) { | ||
+ | printf("Usage: %s DEVICE RO_FLAG\n", argv[0]); | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | if ((fd = open(argv[1], O_RDWR)) < 0) { | ||
+ | perror("open"); | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | flag = atoi(argv[2]); | ||
+ | if ((res = ioctl(fd, BLKROSET, &flag)) < 0) { | ||
+ | perror("ioctl"); | ||
+ | close(fd); | ||
+ | return 1; | ||
+ | } | ||
+ | close(fd); | ||
+ | return 0; | ||
+ | } | ||
+ | </div></div> | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
+ | # umount /boot ★いったんアンマウント | ||
+ | # ./setro /dev/sda1 1 ★リードオンリーにセット | ||
+ | # mount /boot | ||
+ | mount: ブロックデバイス /dev/sda1 は書き込み禁止です、読込み専用でマウントします | ||
+ | # umount /boot | ||
+ | # ./setro /dev/sda1 0 ★リードオンリーを解除 | ||
+ | # mount /boot | ||
+ | </div></div> | ||
+ | |||
+ | === signal.c === | ||
+ | |||
+ | 単に受信したシグナル番号を出力するプログラム。 | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | ソースコード | ||
+ | <div class="mw-collapsible-content"> | ||
+ | #include <stdio.h> | ||
+ | #include <signal.h> | ||
+ | |||
+ | void signal_handler(int sig) { | ||
+ | printf("signal: %d\n", sig); | ||
+ | } | ||
+ | int main(void) { | ||
+ | //signal(SIGINT , SIG_IGN); | ||
+ | signal(SIGINT , SIG_DFL); | ||
+ | signal(SIGQUIT, signal_handler); | ||
+ | signal(SIGALRM, signal_handler); | ||
+ | signal(SIGTERM, signal_handler); | ||
+ | alarm(5); | ||
+ | while (1) { | ||
+ | sleep(1); | ||
+ | } | ||
+ | } | ||
+ | </div></div> | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
+ | $ ./signal | ||
+ | signal: 3 | ||
+ | signal: 3 | ||
+ | signal: 15 | ||
+ | signal: 14 | ||
+ | signal: 3 | ||
+ | </div></div> | ||
+ | |||
+ | === shm.c === | ||
+ | |||
+ | 共有メモリの確保と読み書きを行うプログラム。削除は ipcrm で…。 | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | ソースコード | ||
+ | <div class="mw-collapsible-content"> | ||
+ | #include <stdio.h> | ||
+ | #include <sys/ipc.h> | ||
+ | #include <sys/shm.h> | ||
+ | #include <string.h> | ||
+ | |||
+ | #define SHM_SIZE 1024 | ||
+ | |||
+ | int main(int argc, char *argv[]) { | ||
+ | int shmid; | ||
+ | char *shmaddr; | ||
+ | char *data; | ||
+ | |||
+ | if (argc < 2) { | ||
+ | printf("Usage: %s data [shmid]\n", argv[0]); | ||
+ | return 1; | ||
+ | } | ||
+ | data = argv[1]; | ||
+ | if (argc < 3) { | ||
+ | if ((shmid = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666)) < 0) { | ||
+ | perror("shmget"); | ||
+ | return 1; | ||
+ | } | ||
+ | printf("new shmid = %d\n", shmid); | ||
+ | } else { | ||
+ | shmid = atoi(argv[2]); | ||
+ | } | ||
+ | |||
+ | if ((shmaddr = shmat(shmid, NULL, 0)) < 0) { | ||
+ | perror("shmat"); | ||
+ | return 1; | ||
+ | } | ||
+ | printf("shmaddr = %p\n", shmaddr); | ||
+ | printf("current value = %s\n", shmaddr); | ||
+ | |||
+ | strcpy(shmaddr, data); | ||
+ | printf("written value = %s\n", shmaddr); | ||
+ | } | ||
+ | </div></div> | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
+ | $ ./a.out | ||
+ | Usage: ./a.out data [shmid] | ||
+ | $ ./a.out "test data" | ||
+ | new shmid = 655367 | ||
+ | shmaddr = 0xb7fb1000 | ||
+ | current value = | ||
+ | written value = test data | ||
+ | $ ./a.out hoge 655367 | ||
+ | shmaddr = 0xb7f27000 | ||
+ | current value = test data | ||
+ | written value = hoge | ||
+ | $ ./a.out test 655367 | ||
+ | shmaddr = 0xb7fb2000 | ||
+ | current value = hoge | ||
+ | written value = test | ||
+ | $ ipcs -m | ||
+ | |||
+ | ------ 共有メモリセグメント -------- | ||
+ | キー shmid 所有者 権限 バイト nattch 状態 | ||
+ | 0x00000000 229379 hagio 600 393216 2 対象 | ||
+ | 0x00000000 262149 hagio 600 393216 2 対象 | ||
+ | 0x00000000 655367 hagio 666 1024 0 | ||
+ | |||
+ | $ ipcrm -m 655367 | ||
+ | $ ipcs -m | ||
+ | |||
+ | ------ 共有メモリセグメント -------- | ||
+ | キー shmid 所有者 権限 バイト nattch 状態 | ||
+ | 0x00000000 229379 hagio 600 393216 2 対象 | ||
+ | 0x00000000 262149 hagio 600 393216 2 対象 | ||
+ | |||
+ | </div></div> | ||
== Python == | == Python == | ||
行63: | 行295: | ||
簡単な TCP サーバ / クライアントプログラム。例外処理はある程度まで。 | 簡単な TCP サーバ / クライアントプログラム。例外処理はある程度まで。 | ||
− | tcp_server.py < | + | <div class="mw-collapsible mw-collapsed"> |
+ | tcp_server.py | ||
+ | <div class="mw-collapsible-content"> | ||
#!/usr/bin/env python | #!/usr/bin/env python | ||
import sys, socket | import sys, socket | ||
行101: | 行335: | ||
break | break | ||
sock.close() | sock.close() | ||
− | </ | + | </div></div> |
− | tcp_client.py < | + | <div class="mw-collapsible mw-collapsed"> |
+ | tcp_client.py | ||
+ | <div class="mw-collapsible-content"> | ||
#!/usr/bin/env python | #!/usr/bin/env python | ||
import sys, socket | import sys, socket | ||
行136: | 行372: | ||
break | break | ||
sock.close() | sock.close() | ||
− | </ | + | </div></div> |
− | 実行例 < | + | <div class="mw-collapsible mw-collapsed"> |
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
サーバ側: | サーバ側: | ||
$ ./tcp_server.py 12345 | $ ./tcp_server.py 12345 | ||
行153: | 行391: | ||
> | > | ||
> quit | > quit | ||
− | </ | + | </div></div> |
=== memcurses.py === | === memcurses.py === | ||
行159: | 行397: | ||
curses (libcurses) を利用した /proc/meminfo の変化量を表示するスクリプト。 | curses (libcurses) を利用した /proc/meminfo の変化量を表示するスクリプト。 | ||
− | ソースコード < | + | <div class="mw-collapsible mw-collapsed"> |
+ | ソースコード | ||
+ | <div class="mw-collapsible-content"> | ||
#!/usr/bin/env python | #!/usr/bin/env python | ||
import sys, time, curses | import sys, time, curses | ||
行200: | 行440: | ||
if __name__ == "__main__": | if __name__ == "__main__": | ||
sys.exit(main(sys.argv)) | sys.exit(main(sys.argv)) | ||
− | </ | + | </div></div> |
− | 実行例 < | + | <div class="mw-collapsible mw-collapsed"> |
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
$ ./memcurses.py 5 | $ ./memcurses.py 5 | ||
Every 5.0s : Sat Feb 26 01:06:31 2011 | Every 5.0s : Sat Feb 26 01:06:31 2011 | ||
行236: | 行478: | ||
HugePages_Rsvd: 0 | HugePages_Rsvd: 0 | ||
Hugepagesize: 2048 kB | Hugepagesize: 2048 kB | ||
− | </ | + | </div></div> |
=== grep.py === | === grep.py === | ||
行243: | 行485: | ||
標準入力からの入力には非対応。 | 標準入力からの入力には非対応。 | ||
− | ソースコード < | + | <div class="mw-collapsible mw-collapsed"> |
+ | ソースコード | ||
+ | <div class="mw-collapsible-content"> | ||
#!/usr/bin/env python | #!/usr/bin/env python | ||
import sys, re, threading | import sys, re, threading | ||
行264: | 行508: | ||
print "Usage: %s PATTERN FILES.." % sys.argv[0] | print "Usage: %s PATTERN FILES.." % sys.argv[0] | ||
sys.exit(1) | sys.exit(1) | ||
− | </ | + | </div></div> |
− | 実行例 < | + | <div class="mw-collapsible mw-collapsed"> |
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
$ ./grep.py | $ ./grep.py | ||
Usage: ./grep.py PATTERN FILES.. | Usage: ./grep.py PATTERN FILES.. | ||
行283: | 行529: | ||
tcp_server.py:8:while 1: | tcp_server.py:8:while 1: | ||
tcp_server.py:13: while True: | tcp_server.py:13: while True: | ||
− | </ | + | </div></div> |
=== wc.py === | === wc.py === | ||
行289: | 行535: | ||
Python で作った wc コマンド。 | Python で作った wc コマンド。 | ||
− | ソースコード < | + | <div class="mw-collapsible mw-collapsed"> |
+ | ソースコード | ||
+ | <div class="mw-collapsible-content"> | ||
#!/usr/bin/env python | #!/usr/bin/env python | ||
import sys, getopt | import sys, getopt | ||
行373: | 行621: | ||
print " %5d" % total_L, | print " %5d" % total_L, | ||
print "total" | print "total" | ||
− | </ | + | </div></div> |
− | 実行例 < | + | <div class="mw-collapsible mw-collapsed"> |
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
$ ./wc.py -h | $ ./wc.py -h | ||
Usage: ./wc.py [-cmlLw] FILES | Usage: ./wc.py [-cmlLw] FILES | ||
行404: | 行654: | ||
1101 3225 27588 27588 129 total | 1101 3225 27588 27588 129 total | ||
lines words chars bytes maxlen | lines words chars bytes maxlen | ||
− | </ | + | </div></div> |
=== calc_buddy.py === | === calc_buddy.py === | ||
行411: | 行661: | ||
タイムスタンプを付けて記録したファイルにも対応。 | タイムスタンプを付けて記録したファイルにも対応。 | ||
− | ソースコード < | + | パイプで less などに繋いだ後に Broken Pipe のエラーが出ないように修正。 |
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | ソースコード | ||
+ | <div class="mw-collapsible-content"> | ||
#!/usr/bin/env python | #!/usr/bin/env python | ||
import sys | import sys | ||
行424: | 行678: | ||
for file in files: | for file in files: | ||
for line in file: | for line in file: | ||
− | if len(line) | + | try: |
− | + | 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, | ||
+ | except IOError: | ||
+ | break | ||
file.close() | file.close() | ||
− | </ | + | </div></div> |
− | 実行例 < | + | <div class="mw-collapsible mw-collapsed"> |
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
$ ./calc_buddy.py | $ ./calc_buddy.py | ||
Node 0, zone DMA 46 5 3 0 0 0 0 1 1 1 0 3856 KB | 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 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 | Node 0, zone HighMem 78051 15607 279 2 59 17 2 0 0 0 0 448052 KB | ||
− | </ | + | </div></div> |
=== dec2bin.py === | === dec2bin.py === | ||
行447: | 行706: | ||
10 進数を 2 進数に変換するスクリプト。32 ビット限定。 | 10 進数を 2 進数に変換するスクリプト。32 ビット限定。 | ||
− | ソースコード < | + | <div class="mw-collapsible mw-collapsed"> |
+ | ソースコード | ||
+ | <div class="mw-collapsible-content"> | ||
#!/usr/bin/env python | #!/usr/bin/env python | ||
import sys | import sys | ||
行469: | 行730: | ||
print "Invalid number" | print "Invalid number" | ||
sys.exit(1) | sys.exit(1) | ||
− | </ | + | </div></div> |
− | 実行例 < | + | <div class="mw-collapsible mw-collapsed"> |
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
+ | $ ./dec2bin.py | ||
+ | Usage: ./dec2bin.py dec | ||
$ ./dec2bin.py 12345 | $ ./dec2bin.py 12345 | ||
11000000111001 | 11000000111001 | ||
行479: | 行744: | ||
11111111111111110000000000000000 | 11111111111111110000000000000000 | ||
$ ./dec2bin.py 2147483647 | $ ./dec2bin.py 2147483647 | ||
− | 1111111111111111111111111111111 | + | 1111111111111111111111111111111 // 先頭の 0 は省かれている |
$ ./dec2bin.py -2147483648 | $ ./dec2bin.py -2147483648 | ||
10000000000000000000000000000000 | 10000000000000000000000000000000 | ||
− | </ | + | </div></div> |
+ | |||
+ | === int2bin.py === | ||
+ | |||
+ | 上の dec2bin.py を利用して、8, 10, 16 進数に対応させたもの。 | ||
+ | コメントアウトしている最後の出力はビット位置確認用。 | ||
+ | |||
+ | dec2bin の名前の付け方が悪かったな。 | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | ソースコード | ||
+ | <div class="mw-collapsible-content"> | ||
+ | #!/usr/bin/env python | ||
+ | import sys | ||
+ | from dec2bin import dec2bin | ||
+ | |||
+ | def usage(): | ||
+ | print "Usage: %s DEC|'0x'HEX|'0'OCT" % sys.argv[0] | ||
+ | sys.exit(1) | ||
+ | |||
+ | if __name__ == "__main__": | ||
+ | if len(sys.argv) < 2: | ||
+ | usage() | ||
+ | num = sys.argv[1] | ||
+ | try: | ||
+ | if num[:2] == "0x": | ||
+ | b = dec2bin(int(sys.argv[1], 16)) | ||
+ | elif num[0] == "0": | ||
+ | b = dec2bin(int(sys.argv[1], 8)) | ||
+ | else: | ||
+ | b = dec2bin(int(sys.argv[1], 10)) | ||
+ | except ValueError: | ||
+ | usage() | ||
+ | l = len(b) | ||
+ | s = '' | ||
+ | for i in range(0, l, 1): | ||
+ | r = i % 4 | ||
+ | s = str(2 ** r) + s | ||
+ | #print s | ||
+ | print b | ||
+ | </div></div> | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed"> | ||
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
+ | $ ./int2bin.py | ||
+ | Usage: ./int2bin.py DEC|'0x'HEX|'0'OCT | ||
+ | $ ./int2bin.py 255 | ||
+ | 11111111 | ||
+ | $ ./int2bin.py -255 | ||
+ | 11111111111111111111111100000001 | ||
+ | $ ./int2bin.py 0x12ab | ||
+ | 1001010101011 | ||
+ | $ ./int2bin.py 0xdeadbeef | ||
+ | 11011110101011011011111011101111 | ||
+ | $ ./int2bin.py 0755 | ||
+ | 111101101 | ||
+ | </div></div> | ||
== bash == | == bash == | ||
行491: | 行813: | ||
ほとんど awk だけど。 | ほとんど awk だけど。 | ||
− | スクリプト < | + | <div class="mw-collapsible mw-collapsed"> |
+ | スクリプト | ||
+ | <div class="mw-collapsible-content"> | ||
#!/bin/bash | #!/bin/bash | ||
IFS=$'\n' | IFS=$'\n' | ||
行516: | 行840: | ||
' $FILE | ' $FILE | ||
done | done | ||
− | </ | + | </div></div> |
− | 実行例 < | + | <div class="mw-collapsible mw-collapsed"> |
+ | 実行例 | ||
+ | <div class="mw-collapsible-content"> | ||
$ cgrep -r shrink_slab mm | $ cgrep -r shrink_slab mm | ||
mm/vmscan.c:177: | mm/vmscan.c:177: | ||
行546: | 行872: | ||
static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) | ||
while (shrink_slab(sc.nr_scanned, gfp_mask, order) && | while (shrink_slab(sc.nr_scanned, gfp_mask, order) && | ||
− | </ | + | </div></div> |
2015年3月21日 (土) 09:27時点における最新版
TP の素を揃えておこうかと。
目次
C
pthread.c
コマンド引き数で与えられた数だけ、ただ寝てるだけのスレッドを生成するプログラム。
ソースコード
#include <stdio.h> #include <stdlib.h> #include <pthread.h> void *thread_func(void *arg) { printf("Thread %d\n", (int) arg); while (1) sleep(1); } int main(int argc, char *argv[]) { int i, num; pthread_t *th; if (argc < 2) { printf("Usage: %s threads\n", argv[0]); return 1; } if ((num = atoi(argv[1])) < 1) { printf("arg 1 = %d\n", num); return 1; } th = (pthread_t *) malloc(sizeof(pthread_t) * num); for (i = 0; i < num; i++) { pthread_create(&th[i], NULL, &thread_func, (void *) i); } for (i = 0; i < num; i++) { pthread_join(th[i], NULL); } return 0; }
実行例
$ cc -l pthread -o pthread pthread.c $ ./pthread Usage: ./pthread threads $ ./pthread 3 & [1] 580 Thread 0 Thread 1 Thread 2 $ ps -elfL | grep pthread 0 S hagio 580 13327 580 0 4 77 0 - 8117 - 09:59 pts/5 00:00:00 ./pthread 3 1 S hagio 580 13327 582 0 4 75 0 - 8117 - 09:59 pts/5 00:00:00 ./pthread 3 1 S hagio 580 13327 583 0 4 75 0 - 8117 - 09:59 pts/5 00:00:00 ./pthread 3 1 S hagio 580 13327 584 0 4 75 0 - 8117 - 09:59 pts/5 00:00:00 ./pthread 3 0 S hagio 602 13327 602 0 1 77 0 - 1245 pipe_w 09:59 pts/5 00:00:00 grep pthread $ kill $! [1]+ 終了しました ./pthread 3
fork.c
コマンド引き数で与えられた数だけ fork して、ゾンビ状態で放置するプログラム。
ソースコード
#include <stdio.h> #include <unistd.h> #include <sys/types.h> int main(int argc, char *argv[]) { int i, num; pid_t pid; if (argc < 2) { printf("Usage %s procs\n", argv[0]); return 0; } if ((num = atoi(argv[1])) < 0) { printf("arg 1 = %d\n", num); return 0; } for (i = 0; i < num; i++) { pid = fork(); if (pid < 0) { perror("fork"); return 1; } else if (pid == 0) { printf("Child %d\n", i); //while (1) sleep(1); return 0; } else { printf("Parent %d (PID: %d)\n", i, pid); } } while (1) sleep(1); return 0; }
実行例
$ cc -o fork fork.c $ ./fork 3 Child 0 Parent 0 (PID: 1197) Child 1 Parent 1 (PID: 1198) Child 2 Parent 2 (PID: 1199) $ ps -elf | grep fork 0 S hagio 1196 13327 0 75 0 - 378 - 10:30 pts/5 00:00:00 ./fork 3 1 Z hagio 1197 1196 0 76 0 - 0 exit 10:30 pts/5 00:00:00 [fork] <defunct> 1 Z hagio 1198 1196 0 77 0 - 0 exit 10:30 pts/5 00:00:00 [fork] <defunct> 1 Z hagio 1199 1196 0 77 0 - 0 exit 10:30 pts/5 00:00:00 [fork] <defunct> 0 S hagio 1208 31213 0 78 0 - 1245 pipe_w 10:30 pts/4 00:00:00 grep fork
setro.c
ioctl のサンプル。ブロックデバイスの読み込み専用フラグを変更するプログラム。
ソースコード
#include <stdio.h> #include <fcntl.h> #include <linux/fs.h> int main(int argc, char* argv[]) { int fd, res, flag; if (argc != 3) { printf("Usage: %s DEVICE RO_FLAG\n", argv[0]); return 1; } if ((fd = open(argv[1], O_RDWR)) < 0) { perror("open"); return 1; } flag = atoi(argv[2]); if ((res = ioctl(fd, BLKROSET, &flag)) < 0) { perror("ioctl"); close(fd); return 1; } close(fd); return 0; }
実行例
# umount /boot ★いったんアンマウント # ./setro /dev/sda1 1 ★リードオンリーにセット # mount /boot mount: ブロックデバイス /dev/sda1 は書き込み禁止です、読込み専用でマウントします # umount /boot # ./setro /dev/sda1 0 ★リードオンリーを解除 # mount /boot
signal.c
単に受信したシグナル番号を出力するプログラム。
ソースコード
#include <stdio.h> #include <signal.h> void signal_handler(int sig) { printf("signal: %d\n", sig); } int main(void) { //signal(SIGINT , SIG_IGN); signal(SIGINT , SIG_DFL); signal(SIGQUIT, signal_handler); signal(SIGALRM, signal_handler); signal(SIGTERM, signal_handler); alarm(5); while (1) { sleep(1); } }
実行例
$ ./signal signal: 3 signal: 3 signal: 15 signal: 14 signal: 3
shm.c
共有メモリの確保と読み書きを行うプログラム。削除は ipcrm で…。
ソースコード
#include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <string.h> #define SHM_SIZE 1024 int main(int argc, char *argv[]) { int shmid; char *shmaddr; char *data; if (argc < 2) { printf("Usage: %s data [shmid]\n", argv[0]); return 1; } data = argv[1]; if (argc < 3) { if ((shmid = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666)) < 0) { perror("shmget"); return 1; } printf("new shmid = %d\n", shmid); } else { shmid = atoi(argv[2]); } if ((shmaddr = shmat(shmid, NULL, 0)) < 0) { perror("shmat"); return 1; } printf("shmaddr = %p\n", shmaddr); printf("current value = %s\n", shmaddr); strcpy(shmaddr, data); printf("written value = %s\n", shmaddr); }
実行例
$ ./a.out Usage: ./a.out data [shmid] $ ./a.out "test data" new shmid = 655367 shmaddr = 0xb7fb1000 current value = written value = test data $ ./a.out hoge 655367 shmaddr = 0xb7f27000 current value = test data written value = hoge $ ./a.out test 655367 shmaddr = 0xb7fb2000 current value = hoge written value = test $ ipcs -m ------ 共有メモリセグメント -------- キー shmid 所有者 権限 バイト nattch 状態 0x00000000 229379 hagio 600 393216 2 対象 0x00000000 262149 hagio 600 393216 2 対象 0x00000000 655367 hagio 666 1024 0 $ ipcrm -m 655367 $ ipcs -m ------ 共有メモリセグメント -------- キー shmid 所有者 権限 バイト nattch 状態 0x00000000 229379 hagio 600 393216 2 対象 0x00000000 262149 hagio 600 393216 2 対象
Python
tcp_server.py / tcp_client.py
簡単な TCP サーバ / クライアントプログラム。例外処理はある程度まで。
tcp_server.py
#!/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()
tcp_client.py
#!/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()
実行例
サーバ側: $ ./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
memcurses.py
curses (libcurses) を利用した /proc/meminfo の変化量を表示するスクリプト。
ソースコード
#!/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))
実行例
$ ./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
grep.py
grep -Hn
と同様の出力となるスクリプト。
標準入力からの入力には非対応。
ソースコード
#!/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)
実行例
$ ./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:
wc.py
Python で作った wc コマンド。
ソースコード
#!/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"
実行例
$ ./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
calc_buddy.py
/proc/buddyinfo のそれぞれのゾーンの合計サイズを計算するスクリプト。 タイムスタンプを付けて記録したファイルにも対応。
パイプで less などに繋いだ後に Broken Pipe のエラーが出ないように修正。
ソースコード
#!/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: try: 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, except IOError: break file.close()
実行例
$ ./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
dec2bin.py
10 進数を 2 進数に変換するスクリプト。32 ビット限定。
ソースコード
#!/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)
実行例
$ ./dec2bin.py Usage: ./dec2bin.py dec $ ./dec2bin.py 12345 11000000111001 $ ./dec2bin.py 1024 10000000000 $ ./dec2bin.py -65536 11111111111111110000000000000000 $ ./dec2bin.py 2147483647 1111111111111111111111111111111 // 先頭の 0 は省かれている $ ./dec2bin.py -2147483648 10000000000000000000000000000000
int2bin.py
上の dec2bin.py を利用して、8, 10, 16 進数に対応させたもの。 コメントアウトしている最後の出力はビット位置確認用。
dec2bin の名前の付け方が悪かったな。
ソースコード
#!/usr/bin/env python import sys from dec2bin import dec2bin def usage(): print "Usage: %s DEC|'0x'HEX|'0'OCT" % sys.argv[0] sys.exit(1) if __name__ == "__main__": if len(sys.argv) < 2: usage() num = sys.argv[1] try: if num[:2] == "0x": b = dec2bin(int(sys.argv[1], 16)) elif num[0] == "0": b = dec2bin(int(sys.argv[1], 8)) else: b = dec2bin(int(sys.argv[1], 10)) except ValueError: usage() l = len(b) s = for i in range(0, l, 1): r = i % 4 s = str(2 ** r) + s #print s print b
実行例
$ ./int2bin.py Usage: ./int2bin.py DEC|'0x'HEX|'0'OCT $ ./int2bin.py 255 11111111 $ ./int2bin.py -255 11111111111111111111111100000001 $ ./int2bin.py 0x12ab 1001010101011 $ ./int2bin.py 0xdeadbeef 11011110101011011011111011101111 $ ./int2bin.py 0755 111101101
bash
cgrep
パターンが呼ばれている関数を検索するスクリプト。 ほとんど awk だけど。
スクリプト
#!/bin/bash IFS=$'\n' RESULT=$(grep -nH $@) for l in $RESULT; do FILE=$(echo "$l" | cut -d: -f 1) LINE=$(echo "$l" | cut -d: -f 2) gawk -v line=$LINE -v file=$FILE ' NR < line && /^\w/ && !/:/ { cand = $0 cand_line = NR } NR == line { if ($0 ~ /^\w/) { print file ":" line ":" } else { print file ":" cand_line ":" print cand } gsub("\t", " ") print $0 exit } ' $FILE done
実行例
$ cgrep -r shrink_slab mm mm/vmscan.c:177: unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, mm/vmscan.c:1026: unsigned long try_to_free_pages(struct zone **zones, gfp_t gfp_mask) shrink_slab(sc.nr_scanned, gfp_mask, lru_pages); mm/vmscan.c:1134: static unsigned long balance_pgdat(pg_data_t *pgdat, int order) nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, mm/vmscan.c:1426: unsigned long shrink_all_memory(unsigned long nr_pages) shrink_slab(nr_pages, sc.gfp_mask, lru_pages); mm/vmscan.c:1426: unsigned long shrink_all_memory(unsigned long nr_pages) shrink_slab(sc.nr_scanned, sc.gfp_mask, lru_pages); mm/vmscan.c:1426: unsigned long shrink_all_memory(unsigned long nr_pages) shrink_slab(nr_pages, sc.gfp_mask, lru_pages); mm/vmscan.c:1626: static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) * shrink_slab() does not currently allow us to determine how mm/vmscan.c:1626: static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) * Note that shrink_slab will free memory on all zones and may mm/vmscan.c:1626: static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) while (shrink_slab(sc.nr_scanned, gfp_mask, order) &&