新山がふだん使っているスクリプト (shell, perl) をまとめたもの。
あなたの環境でそのまま動くとは限りません。
bash を使っているときは、
`basename $i`
のかわりにシェルの変数置換:
${i/*\//}
が使える。
拡張子だけを削りたいなら
${i/.*/}
なども可能
(ただしこれは abc.def.html を abc
のみにしてしまうので注意)。
lessdir -
ファイルに対しては less、ディレクトリに対しては ls を起動
(実際には新山は「l」という一文字のコマンドにしている、
less のかわりにいつもこれを使っている)
#!/bin/sh
# 環境変数 $PAGER に値が設定されてない場合は、
# デフォルトとして less を使う。
PAGER=${PAGER-less}
# このスクリプトに与えられた引数を見る。
if [ $# -eq 0 ]; then
# 引数がない場合、hoge | lessdir のように起動されたのだと考える。
# $PAGER を起動そのまま起動しておしまい。
# あとはこいつが、このスクリプトの標準入力を継承するだろう。
exec $PAGER
elif [ -d "$1" ]; then
# 最初の引数がディレクトリを表していれば、
# ls モードと解釈する。引数ぜんぶ (最初のも含め) ls に渡しておしまい。
exec ls -F $*
else
# それ以外なら、ページャとして扱われたのだと考える。
# 引数ぜんぶ (最初のも含め) $PAGER に渡しておしまい。
exec $PAGER $*
fi
lessdirauto - lessdir の改良版。端末の大きさに応じて cat と
less を使い分ける
(表示するファイルすべてを一時的に /tmp 以下に保存するので、
あまり長いファイルの表示には向いていない)
#!/bin/sh
# 一時ファイルの名前を変数 t に入れる
# この名前は重複してはまずいので、とりあえず$$を使って
# プロセスIDを含めておく。
t=/tmp/L$$
# 途中でこのプロセスが異常終了したときに、
# 一時ファイルを自動的に消すようにtrapを仕掛ける。
cleanup() {
rm $t; exit 1;
}
trap cleanup INT HUP TERM;
# 実際に表示する内容を、$t で表される一時ファイルに入れる。
# この部分は lessdir と同じだが、exec は使わない。
if [ $# -eq 0 ]; then
# 引数がない場合、hoge | lessdirauto のように起動されたのだと考える。
# cat にこのスクリプトの標準入力を継承させ、入ってきたものを全部
# $t に吐かせる。
cat > $t
elif [ -d "$1" ]; then
# 最初の引数がディレクトリを表していれば、
# ls モードと解釈する。ls の結果をまず全部 $t に吐かせる。
ls -oF $* > $t
else
# それ以外なら、ページャとして扱われたのだと考える。
# 表示するファイルを全部 $t に吐かせる。
cat $* > $t
fi
# (端末の行数 - 2) を変数 height に入れる。
# stty size は「25 80」のように「行数 桁数」の順で出力するので、
# それをまずいったん配列に入れて、最初の要素 ($1) だけを取り出すことで
# これが実現できる。あとは expr に渡して 2 だけ引いてやる。
# (stty を普通に呼ぶと、標準入力がパイプからのリダイレクトであるときに
# うまく動作しない。そこで、/dev/tty をリダイレクトすることで無理矢理端末を
# 見させるようにする。)
set -- `stty size </dev/tty`
height=`expr $1 - 2`
# 一時ファイル $t の行数を変数 lines に入れる。
# wc は「12 435 7880 filename」のように「行数 単語数 文字数 ファイル名」の
# 順で出力するので、これも最初の要素だけを取りだせばよい。
set -- `wc $t`
lines=$1
# 表示する行数 (lines) が端末の行数 (height) より多ければ less -X を、
# そうでなければ cat を使う。
if [ $lines -gt $height ]; then
less -X $t;
else
cat $t;
fi
# 最後に一時ファイルを消して、おしまい。
rm $t;
showhelp - コマンドのヘルプを表示する
(よくコマンドによっては、オプションの長いヘルプを標準エラー出力に
吐くので、less で見ようとしても消えてしまう。このコマンドは
showhelp cdparanoia などとやると、
単に cdparanoia --help を実行してその標準出力および
標準エラー出力を lessdirauto (上記参照) に流すだけのもの)
#!/bin/sh # 与えられたコマンド文字列に --help という引数をつけて実行する。 # このとき標準エラー出力を標準出力にリダイレクトし、エラーメッセージも # 一緒にパイプを流れるようにする。 $* --help 2>&1 | lessdirauto
querycode - ファイルの漢字コードを判定する(新山は自分の書いた web ページの漢字コードが 全部 jis (iso-2022-jp) かどうかをチェックするのにこれを使っている)
#!/bin/sh
# すべての引数についてチェック。
for fname in $*; do
# 安全のため、そのファイルが「普通の」ファイルであることを確認する。
if [ -f $fname ]; then
# ここで nkf を使って、そのファイルを各漢字コードに変換してみる。
# 変換結果と元のファイルを cmp で比較し、同じならば
# nkf に指定した漢字コードを使っていることになる。
# ファイルに日本語が含まれていない場合は、
# デフォルトで jis と判定される。
# これが嫌な場合は nkf の順番を変えること。
if nkf -j $fname | cmp -s $fname; then
# ファイル名を一緒に出力してもいいかも。
echo jis
elif nkf -s $fname | cmp -s $fname; then
echo sjis
elif nkf -e $fname | cmp -s $fname; then
echo euc
else
# どの漢字コードでもなかった場合。
echo unknown
fi
fi
done
#!/bin/sh
exec rsync -Cauvbz --delete --backup-dir ~/.old \
--exclude 'LOCAL' --exclude 'local' \
--include '*.obj' --include '*.Z' \
$*
get host1:dir とすると、host1 上の ~/dir の変更点が
ローカルな ~/dir に反映される。
put host1:dir とすると、ローカルな ~/dir の変更点が
host1 上の ~/dir に反映される。
2つのマシンで作業するときに楽。
#!/bin/sh cd for i in $*; do h=`expr "$i" : '\(.*\):'` d=`expr "$i" : '.*:\(.*\)'` if [ ! "$d" ]; then d=.; fi echo $d if [ "$h" -a -d "$d" ]; then case $0 in *get) rs "$h:$d/" "$d/";; *put) rs "$d/" "$h:$d";; esac fi done
#!/usr/bin/perl
open(IN, "od -tx1 -Ax @ARGV |");
while(<IN>) { chop; @f=split(' ');
print $_," "; shift(@f); $s=''; foreach $i (@f) { $c=pack("H2",$i);
$c='.' if (ord($c)<32); $s.=$c; } print " " x (16-@f); print "$s \n"; }
ときどき、 tar のソースツリーなどを展開すると パーミッションが 444 になっていてむかつくため。
#!/bin/sh find $* -type f | xargs chmod 644 2>/dev/null find $* -type d | xargs chmod 755 2>/dev/null
ucspi-stcp 使用。 プロトコルのチェック等に。
(まずこのスクリプト waitio をインストールしておく必要がある)
#!/usr/bin/perl
open(TTYIN,"<&6"); binmode(TTYIN); select(TTYOUT); $|=1;
open(TTYOUT,">&7"); binmode(STDIN); select(STDOUT); $|=1;
$rin='';
vec($rin,fileno(STDIN),1)=1; vec($rin,fileno(TTYIN),1)=1;
do {
$n=select($rout=$rin,undef,undef,undef);
if (vec($rout,fileno(STDIN),1)) { sysread(STDIN,$_,1024); s/\r//g; print TTYOUT $_; }
if (vec($rout,fileno(TTYIN),1)) { exit if (!sysread(TTYIN,$_,1024)); s/\n/\r\n/g; print STDOUT $_; }
} while(1);
(サーバ側)
#!/bin/sh
p=${1-1111}
echo "waiting on $p..."
exec env - PATH=$PATH tcpserver -vRHl0 -c1 0 $p waitio 6</dev/tty 7>/dev/tty
(クライアント側)
#!/bin/sh if [ $# -lt 2 ]; then echo "usage: client host port"; exit 1; fi exec tcpclient -RHl0 -- $1 $2 waitio
stwm 専用。AucTeX に比べて何がよいかというと、ウインドウマネージャと 結託しているので、何度 xdvi を実行しても余計なウインドウが開かないこと。 後述の ftime 使用。
#!/bin/sh
# atex
wmcmd=stwmcmd
bibtex=${BIBTEX:-jbibtex}
latex=${LATEX:-platex}
xdvi=${XDVI:-xdvi}
mode=dvi
# print usage
usage() {
echo 'usage: atex [-fpdcj] filename
-f: force compile
-c: compile only
-p: preview only
-d: cleanup
-D: cleanup including ps
-j: use jlatex209
-P[printer]: print'
exit 1
}
# check if it is new
isnew() {
test `ftime -m $1` -gt `ftime -m $2`;
return;
}
# clean up
cleanup() {
if isnew $1.tex $1.aux; then
echo "cleanup $1.aux";
rm $1.aux $1.bbl $1.blg $1.toc
fi
rm $1.log
}
# preview
preview() {
if [ "$xdvi" -a "$wmcmd" ]; then
# run xdvi
icon=`$wmcmd -t $xdvi q iconified`
if [ "$icon" ]; then
# xdvi already running
if [ $icon = 0 ]; then
# xdvi not iconified
$wmcmd -t $xdvi stack 1
$wmcmd -t $xdvi warp
else
# xdvi iconified
$wmcmd -t $xdvi iconify 0
fi
else
# xdvi not running
$xdvi $fname.dvi >/dev/null 2>&1 &
fi
fi
}
# compile
compile() {
$latex $fname
if [ `grep '^LaTeX Warning: Citation .*undefined' $fname.log | wc -l` -ne 0 ]; then
$bibtex $fname
$latex $fname
fi
if [ `grep '^LaTeX Warning: Citation .*undefined' $fname.log | wc -l` -ne 0 ]; then
$bibtex $fname
$latex $fname
fi
}
# print
print() {
dvips $fname
if [ $printer = 0 ]; then
mpr $fname.ps
else
lpr -P$printer $fname.ps
fi
}
# get option
set -- `getopt P:fpdDcj $*`
if [ $? != 0 ]; then usage; fi
while [ "$1" != -- ]; do
case $1 in
-f) mode=force;;
-p) mode=preview;;
-d) mode=clean;;
-D) mode=cleanps;;
-c) mode=compile;;
-j) latex=jlatex209;;
-P) mode=print; printer=$2; shift;;
esac
shift
done
shift
if [ ! "$1" ]; then usage; fi
cd `dirname $1`
fname=`basename $1 .tex`
# main
case $mode in
compile)
cleanup $fname
compile;;
preview)
preview;;
clean)
rm -f $fname.dvi $fname.log $fname.aux $fname.bbl \
$fname.blg $fname.toc;;
cleanps)
rm -f $fname.dvi $fname.log $fname.aux $fname.bbl \
$fname.blg $fname.toc $fname.ps;;
force)
if compile; then
preview
fi;;
dvi)
if isnew $fname.tex $fname.dvi; then
cleanup $fname
if compile; then
preview
fi
else
preview
fi;;
print)
if isnew $fname.tex $fname.dvi; then
clean $fname
if compile; then
print
fi
else
print
fi;;
esac
フロッピーに生のtarを書きこむスクリプト。 むかしは Mac で SUNTAR を使っていたため。
#!/bin/sh
case `hostname` in
godot) dev=/dev/fd0;; # linux
snow) dev=/dev/fd0a;;
*) echo "$0: not supported on this machine."; exit;;
esac;
cmd=$1;
if [ ! "$cmd" ]; then cmd=dir; else shift; fi;
case $cmd in
add) exec /usr/local/bin/tar -L 1440 -r -v -f $dev $*;;
new) exec /usr/local/bin/tar -L 1440 -c -v -f $dev $*;;
ext) exec /usr/local/bin/tar -L 1440 -x -v -f $dev $*;;
dir) exec /usr/local/bin/tar -L 1440 -t -v -f $dev;;
*) echo "usage: $0 {add,new,ext,dir} file ...";
esac;
sed を使っています。
#!/bin/sh if [ $# -lt 2 ]; then echo 'usage: formv s/pat1/pat2/ file ..'; exit 1; fi s=$1 shift for i in $*; do j=`echo "$i"|sed "$s"` echo $i "->" $j; mv $i $j done
シェルスクリプトで make もどきをしたい場合に使う。
#!/usr/local/bin/perl
if ($ARGV[0] eq '-a') {
@_ = stat($ARGV[1]);
$a = $_[8];
} elsif ($ARGV[0] eq '-m') {
@_ = stat($ARGV[1]);
$a = $_[9];
} elsif ($ARGV[0] eq '-c') {
@_ = stat($ARGV[1]);
$a = $_[10];
} elsif ($ARGV[0]) {
@_ = stat($ARGV[0]);
$a = $_[9];
} else {
$a = time();
}
if (! $a) { $a = 0; }
print "$a\n";
日本語の検索エンジンや掲示板に入力するときはコレ。
#!/bin/sh export SHELL; SHELL=tcsh kterm -xrm 'KTerm*VT100*translations: #override Ctrl<Key>j: begin-conversion(JAPANESE_CONVERSION)\n' \ -T jlynx -n jlynx -geom 80x50-0-0 -e /usr/local/bin/lynx &
拡張子を見て ps, ps.gz, pdf, テキストを区別し印刷する。
#!/bin/sh
# lpo:
# -P printer : speficy printer
# -m : speficy twocolumns
# -1 : onecolumn
# -p : onecolumn, portlait-duplex
# -2 : twocolumn, landscape-duplex
set -- `getopt P:m1d2 $*`
if [ $? != 0 ]; then
echo "usage: lpo [-Pprinter] [-m1d2] [file ...]"
fi
p=pst
m=0
a=-np
while [ $1 != -- ]; do
case $1 in
-P) shift; p=$1;;
-m) m=1;;
-1) m=0; a=-p; p=ps;;
-p) m=0; a=-p; p=psdp;;
-2) m=1; p=psdl;;
esac
shift;
done
shift;
spool() {
if [ $m = 1 ]; then
psmulti -nodecor $* | lpr -P$p $*;
else
lpr -P$p $*;
fi
}
if [ $# = 0 ]; then
spool; exit;
fi
for i in $*; do
case $i in
*.ps)
spool $i;;
*.ps.gz)
gzip -dc $i | spool;;
*.pdf)
t=/tmp/prt.$$
acroread -toPostScript -size a4 -shrink -pairs $i $t
spool $t
rm $t;;
*.dvi)
/usr/local/bin/dvips -f $i | spool;;
*)
if [ "X$a" = "X-np" ]; then m=0; fi
a2ps $a $i | spool;;
esac
done
むかし、Mac でテキストを書いていたときに使っていたんよ。
#!/bin/sh
if [ ! "$1" ]; then echo "usage: mj filename ..."; exit; fi
while [ "$1" ]; do
if [ \( -h "$1" \) -o \( ! -f "$1" \) ]; then
echo "mj: $1 is not regular file.";
else
echo "mj: convert: $1"
f=/tmp/mj.$$;
mv $1 $f;
tr '\^M' '\
' < $f > $1;
rm $f;
fi;
shift;
done
メールを書くのに .signature ファイルは使っていません。 かわりにこれを使ってファイルをバッファに取りこみます。 こうすると切り換えもできて便利。
#!/bin/sh case $1 in x) echo '-- 東京工業大学 情報理工学研究科 計算工学専攻 新山 祐介 euske@cl.cs.titech.ac.jp';; e) echo 'SHINYAMA Yusuke -- Dept. of Computer Science, Tokyo Inst. of Technology, 2-12-1, Ookayma, Meguro-ku, Tokyo, 152-8552, JAPAN E-MAIL: euske@cl.cs.titech.ac.jp FAX: +81 3-5734-2915';; *) echo '-- 新山 祐介 euske@cl.cs.titech.ac.jp';; esac;
(で、 .emacs には次のように書いておく)
;; signature ;; (defun sig () (interactive) (call-process "sig" nil t t)) (defun xsig () (interactive) (call-process "sig" nil t t "x")) (defun esig () (interactive) (call-process "sig" nil t t "e"))
デフォルトで xterm でなくて kterm を起動する。あと、プロセス ID を 表示するのとエラー出力を ~/.xsession-errors に追加するのが便利。
#!/bin/sh if [ ! "$*" ]; then echo "Usage: xrsh <hostname> [command ...]"; exit 1; fi if [ ! "$DISPLAY" ]; then echo "xrsh: Can't open display."; exit 1; fi target=$1; shift; program="$*"; if [ ! "$program" ]; then program="kterm -T kterm@$target -n $target"; fi; errorfile="$HOME/.xsession-errors"; rsh $target "sh -c 'SHELL=$SHELL DISPLAY=$DISPLAY $program >>$errorfile 2>&1 & echo \"xrsh: $target: \$!\"'";