シェルスクリプト総合 その6
■ このスレッドは過去ログ倉庫に格納されています
0001うはwwwww
2006/03/26(日) 00:56:22スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashなので特に注意。
・csh/tcshのシェルスクリプトは推奨されません。
(理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
manや参考リンクを見ましょう。
aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
0569名無しさん@お腹いっぱい。
2006/06/03(土) 08:32:25dcは出来る子。
0570名無しさん@お腹いっぱい。
2006/06/03(土) 11:44:41exprは出来る子。
0571名無しさん@お腹いっぱい。
2006/06/03(土) 12:02:320572名無しさん@お腹いっぱい。
2006/06/03(土) 14:21:54なんでつかわないんだろ。
0573名無しさん@お腹いっぱい。
2006/06/03(土) 14:43:15最近ようやくどの新しいOSにでも入ってる状態になったってことは、
後10年くらいしたらどこで使っても問題ないかなって感じだ。
0574名無しさん@お腹いっぱい。
2006/06/03(土) 17:10:36自分は今Solarisを使っているんだが、 実は2.5.1にはすでに入ってたのね。知らなかった。
0575名無しさん@お腹いっぱい。
2006/06/03(土) 19:13:50ありがとう。
ps で実行したコマンドのプロセスを確認と絡めて
うまい具合に作れました。
0576名無しさん@お腹いっぱい。
2006/06/03(土) 23:48:49#!/bin/sh
echo "$@" | bc
0577名無しさん@お腹いっぱい。
2006/06/03(土) 23:53:140578名無しさん@お腹いっぱい。
2006/06/17(土) 01:14:46finde ./ の結果が
AAA
AAA/BBB
AAA/BBB/hoge1.txt
AAA/BBB/hoge2.txt
AAA/BBB/hoge3.txt
AAA/BBB/CCC/hoge4.txt
AAA/BBB/CCC/DDD
AAA/BBB/CCC/DDD/EEE
AAA/BBB/FFF/GGG/hoge5.txt
AAA/BBB/FFF/GGG/hoge6.txt
AAA/BBB/FFF/GGG/HHH
AAA/BBB/FFF/III/hoge7.txt
AAA/BBB/FFF/III/JJJ
AAA/BBB/FFF/III/JJJ/KKK
AAA/BBB/FFF/III/JJJ/KKK/LLL
AAA/BBB/FFF/III/JJJ/KKK/LLL/MMM
となっていて、ツリーにファイルを持たないフォルダのみを
抜き出したいです。
0579名無しさん@お腹いっぱい。
2006/06/17(土) 01:15:24AAA/BBB/CCC/DDD
AAA/BBB/CCC/DDD/EEE
AAA/BBB/FFF/GGG/HHH
AAA/BBB/FFF/III/JJJ
AAA/BBB/FFF/III/JJJ/KKK
AAA/BBB/FFF/III/JJJ/KKK/LLL
AAA/BBB/FFF/III/JJJ/KKK/LLL/MMM
先輩は、find . -type d -emptyと言い残して旅に出ましたが
動きませんでした…
OSはこれです。シェルがどうこうはよくわかりません。。。
SunOS devcvs01 5.9 Generic_118558-05 sun4u sparc SUNW,UltraAX-i2
0580名無しさん@お腹いっぱい。
2006/06/17(土) 02:56:59実はちゃんと動いている、に1票。
動かしてみたらどうなったか具体的に書いてみ。
あと、次に>>578がここに戻ってくるときまでには、
先輩が教えたオプションの意味をman見て100%理解しとけよ。
0581名無しさん@お腹いっぱい。
2006/06/17(土) 08:52:40先輩はガソリンが空っぽになったので探しながら旅をしてる
まで読んだ
0582578
2006/06/17(土) 08:55:24また、UNIXのコマンドのfindのとこに-emptyオプションがなかったです。
0583名無しさん@お腹いっぱい。
2006/06/17(土) 09:22:500584名無しさん@お腹いっぱい。
2006/06/17(土) 10:25:12AAA/BBB/CCC/DDD/EEE
AAA/BBB/FFF/GGG/HHH
AAA/BBB/FFF/III/JJJ/KKK/LLL/MMM
になるはず。AAA/BBB/CCC/DDD の下に AAA/BBB/CCC/DDD/EEE があるから
-empty でひっかからない。
-type d でひっかかったディレクトリのそれぞれにファイルがあるかどうかを
ひとつずつ地道に調べるしかないんじゃ?
0585名無しさん@お腹いっぱい。
2006/06/17(土) 11:18:240586578
2006/06/17(土) 11:49:13地道に調べてるのですが、いかんせんフォルダが10000くらいあって
そのうちの500フォルダくらいが空のようですが、目視はなんとも精度が低く
>>585
すみません、どんな感じにやるのですか?
0587名無しさん@お腹いっぱい。
2006/06/17(土) 12:06:31find $1 -type f|grep '^$' >/dev/null
みたいなシェルスクリプトを使うのか?
0588名無しさん@お腹いっぱい。
2006/06/17(土) 12:14:16Solarisのfindには、-emptyオプションが無い件については、
↓で代用できる。
find . -type d -links 2
で、サブディレクトリがあって空の場合に、
親ディレクトリは引っかからないという問題はあるけど、
どうせ、その空のディレクトリを消したいんだろ?
なら、末端の空のディレクトリを消して、再び
↑のfindをすることを数回繰り返せば、目的は果たせる。
0589578
2006/06/17(土) 12:18:16一覧をこさえて提出しないと、鬼が怒るという問題があるのです
-emptyないのですか…
0590名無しさん@お腹いっぱい。
2006/06/17(土) 15:12:39use File::Find;
no warnings File::Find;
do {
my %not_empty;
find({'bydepth'=>1, 'no_chdir'=>1,
'wanted'=>sub {
my $dir = $File::Find::dir;
my $name = $File::Find::name;
if (-d $name) {
return if (defined ($deleted{$name}));
if (! defined ($not_empty{$name})) {
$deleted{$name} = 1;
return;
}
}
$not_empty{$dir} = 1;
}},'.');
$old = $new;
$new = length(keys %not_empty);
} while ($old!=$new);
print join("\n",sort keys %deleted) ,"\n";
長過ぎ。シェルスクリプトじゃないし。しかも、この出力をrm -rf できないし。
0591名無しさん@お腹いっぱい。
2006/06/17(土) 15:50:18#!/bin/sh
for x in `find $1 -type d` ; do
find $x -maxdepth 1 -type f | grep . > /dev/null
if [ $? -eq 0 ] ; then
continue
fi
echo $x
done
環境が違うんでgrepの違いとかは適当に直して呉
リンクの有無とかもチェックするなら3-6行を増やせ
>589
結果に責任は持たんから怒られる覚悟はしとけw
0592591
2006/06/17(土) 16:01:10実はあのままだと怒られるパターンがあるが、詳しく書かないでおく。
0593名無しさん@お腹いっぱい。
2006/06/17(土) 17:04:33Solarisの findには -maxdepthオプションがないというのがオチ。
あと、シェル変数を " " してないから、いろいろ危ない。
0594名無しさん@お腹いっぱい。
2006/06/17(土) 17:23:242 find でディレクトリ以外の一覧を得る find . ! -type d > b
3 2 で得られたものから、dirname の一覧を作る
cat b | sed 's,/[^/]*$,,' > c1
cat c1 | sed 's,/[^/]*$,,') > c2
以下、最も深い階層回繰り返し。
4 1 にしか含まれないものを創る cat a c1 c1 c2 c2 ... |sort |uniq -u
0595名無しさん@お腹いっぱい。
2006/06/17(土) 19:13:07それを find から -exec で起動するかな
0596名無しさん@お腹いっぱい。
2006/06/17(土) 19:43:52ディレクトリの末尾に余計なコロンがついてるが気にするな。
最上位のディレクトリだけはディレクトリだけあってファイルがひとつもなくても
結果に出てこないがそれ以外は正しいはず。目視で確認してくれ。
改行コードを含むディレクトリだとかコロンで終わるファイルとかあると
おかしな結果になるがそれ以外は正しいはず。そんなファイルを作るな(w
0597名無しさん@お腹いっぱい。
2006/06/17(土) 20:22:53あと、サ(ry
0598名無しさん@お腹いっぱい。
2006/06/17(土) 20:39:00でいいじゃん
0599名無しさん@お腹いっぱい。
2006/06/18(日) 00:04:44だめだろ。duじゃディレクトリが空か判定できんぞ。
0600名無しさん@お腹いっぱい。
2006/06/18(日) 00:20:510601名無しさん@お腹いっぱい。
2006/06/18(日) 00:58:37rsync -avn
find
diff
0602名無しさん@お腹いっぱい。
2006/06/18(日) 06:21:08使用ファイルサイズで分かる。
0603名無しさん@お腹いっぱい。
2006/06/18(日) 06:45:04あ、-maxdepthなんか無い方が目的に適うことに気づいてしまったw
0604名無しさん@お腹いっぱい。
2006/06/18(日) 20:05:24いや、わからないですね。
ディレクトリ内のファイルの作成削除の履歴&OSによるディレクトリ管理の方法によっては、
ファイルが全くなくてもディレクトリのサイズが巨大になる場合がありえるものなんです。
0605名無しさん@お腹いっぱい。
2006/06/19(月) 16:52:37メモリ制限やプロセス数制限でプロセス生成に失敗すると、
シェルスクリプト本体が終了してしまいますが、
終了させずに次の行へ処理を進める方法はありますか?
一定時間ウェイトしてから、リトライさせたいのですが…
0606名無しさん@お腹いっぱい。
2006/06/19(月) 17:13:55サンプル希望
0607名無しさん@お腹いっぱい。
2006/06/19(月) 17:41:23FAT
0608名無しさん@お腹いっぱい。
2006/06/19(月) 17:51:34$ uname -a
FreeBSD xxx 7.0-CURRENT FreeBSD 7.0-CURRENT #13: Tue May 9 14:37:19 JST 2006 xxx i386
$ mkdir /tmp/testdir
$ ls -ld /tmp/testdir
drwxr-xr-x 2 xxxx xxxx 512 Jun 19 17:40 /tmp/testdir
$ for f in $(jot 1000);do touch /tmp/testdir/$f;done
$ ls -ld /tmp/testdir
drwxr-xr-x 2 xxxx xxxx 12288 Jun 19 17:41 /tmp/testdir
$ rm /tmp/testdir/*
$ ls -ld /tmp/testdir
drwxr-xr-x 2 xxxx xxxx 12288 Jun 19 17:41 /tmp/testdir
他人にサンプル要求してるんだから「使用ファイルサイズで分かる」サンプルも提示しろよ。
0609名無しさん@お腹いっぱい。
2006/06/19(月) 19:36:34Linuxなんだけど
$mkdir -p /tmp/testdir/test{1,2}
$for aa in `seq 10`; do mkdir /tmp/testdir/test1/aa$aa; done
$du -b /tmp/testdir/ |sort -nr
53248 /tmp/testdir
45056 /tmp/testdir/test1
4096 /tmp/testdir/test2
4096 /tmp/testdir/test1/aa9
4096 /tmp/testdir/test1/aa8
4096 /tmp/testdir/test1/aa7
4096 /tmp/testdir/test1/aa6
4096 /tmp/testdir/test1/aa5
4096 /tmp/testdir/test1/aa4
4096 /tmp/testdir/test1/aa3
4096 /tmp/testdir/test1/aa2
4096 /tmp/testdir/test1/aa10
4096 /tmp/testdir/test1/aa1
空のディレクトリは最小サイズだよ。
0610名無しさん@お腹いっぱい。
2006/06/19(月) 20:03:50touch /tmp/testdir/test2/hoge
してファイルを作成してみるとどうなるか。
0611名無しさん@お腹いっぱい。
2006/06/19(月) 20:06:56おんなじことを Linux-2.4.20 で追試させてもらった。
やっぱ同様にファイルが1つもないのに/tmp/testdirが12288と大きいままだったわい。
0612名無しさん@お腹いっぱい。
2006/06/19(月) 23:40:21空じゃないディレクトリでも最小サイズだな。
もっとも真に空のディレクトリが存在したらファイルシステムが壊れているという事だけど。
$ mkdir /tmp/testdir
$ ls -ld /tmp/testdir
drwxr-xr-x 2 xxxx xxxx 4096 Jun 20 00:54 /tmp/testdir
$ touch /tmp/testdir/1
$ ls -ld /tmp/testdir
drwxr-xr-x 2 xxxx xxxx 4096 Jun 20 00:54 /tmp/testdir
0613名無しさん@お腹いっぱい。
2006/06/20(火) 00:05:48linux の reiserfs3 だと
mkdir a
drwxr-xr-x 2 xxxx xxxx 48 Jun 20 00:03 a/
touch a/hoge
drwxr-xr-x 2 xxxx xxxx 72 Jun 20 00:03 a/
rm a/hoge
drwxr-xr-x 2 xxxx xxxx 48 Jun 20 00:03 a/
0614604
2006/06/20(火) 00:31:51おっしゃるとおりです。OSとか「ファイルシステムによる」わけです。
だから、そういうことに依存したスクリプトは書いてはいけないでしょう。
最低限、>>598,602のような表明には、「XXXファイルシステムとか△△△OSでは」
という条件を付さねばならなかったわけです。
0616名無しさん@お腹いっぱい。
2006/06/20(火) 00:42:59% ls -ld
drwxr-xr-x 2 xxxx users 512 Jun 20 00:38 .
% touch `yes '' | head -1000 | cat -n` ; ls -ld
drwxr-xr-x 2 xxxx users 12288 Jun 20 00:38 .
% rm * ; ls -ld
drwxr-xr-x 2 xxxx users 12288 Jun 20 00:38 .
みたいにサイズが戻らないけど、swapfs(仮想メモリディスク)上だと
% ls -ld
drwxr-xr-x 2 xxxx users 117 Jun 20 00:37 .
% touch `yes '' | head -1000 | cat -n`; ls -ld
drwxr-xr-x 2 xxxx users 60010 Jun 20 00:37 .
% rm *; ls -ld
drwxr-xr-x 2 xxxx users 117 Jun 20 00:37 .
みたいに元に戻る。
0617名無しさん@お腹いっぱい。
2006/06/20(火) 10:41:17>608 の jot って coreutils ( sh-utils だった ?) の seq みたいなのですか ?
0618名無しさん@お腹いっぱい。
2006/06/20(火) 11:08:27http://www.jp.freebsd.org/cgi/mroff.cgi?subdir=man&lc=1&cmd=&man=jot&dir=jpman-5.4.0%2Fman§=0
0619名無しさん@お腹いっぱい。
2006/06/20(火) 11:09:14そうです。
JOT(1) FreeBSD General Commands Manual JOT(1)
NAME
jot -- print sequential or random data
SYNOPSIS
jot [-cnr] [-b word] [-w word] [-s string] [-p precision]
[reps [begin [end [s]]]]
0620名無しさん@お腹いっぱい。
2006/06/20(火) 12:02:340621名無しさん@お腹いっぱい。
2006/06/20(火) 12:20:580622名無しさん@お腹いっぱい。
2006/06/20(火) 12:22:19>618-619 ありがとうございました。
0623名無しさん@お腹いっぱい。
2006/06/20(火) 13:29:03だそうだ。
0624名無しさん@お腹いっぱい。
2006/06/20(火) 19:34:24というシェルスクリプトきぼんぬ
0625名無しさん@お腹いっぱい。
2006/06/20(火) 19:44:01echo hoge|mail aho
fi
0626名無しさん@お腹いっぱい。
2006/06/20(火) 20:00:15$ [ -e hoge.txt ]
test: argument expected
$ uname -sr
SunOS 5.10
0627名無しさん@お腹いっぱい。
2006/06/20(火) 21:46:25そりゃ、SunOSみたいな古いOSじゃ動かないかもね。Solaris使えよ。
0628名無しさん@お腹いっぱい。
2006/06/20(火) 22:09:18お前、それがとても恥ずかしい発言だってわかってる? 晒し上げ www
0629名無しさん@お腹いっぱい。
2006/06/20(火) 22:24:250630名無しさん@お腹いっぱい。
2006/06/21(水) 08:49:430631名無しさん@お腹いっぱい。
2006/06/21(水) 08:58:580632名無しさん@お腹いっぱい。
2006/06/21(水) 09:54:480633名無しさん@お腹いっぱい。
2006/06/21(水) 10:32:01pgr
0634名無しさん@お腹いっぱい。
2006/06/21(水) 10:49:16>>627 を笑うものの方が逆に恥ずかしいみたいだから。
0635名無しさん@お腹いっぱい。
2006/06/21(水) 15:39:160636名無しさん@お腹いっぱい。
2006/06/21(水) 16:59:40sedで地道にやる以外になんかカッコイイのない?
echo -n "ほげ" | od -t x2 -A n | tr -d ' ' | sed 's/\([0-9a-z][0-9a-z]\)\([0-9a-z][0-9a-z]\)/%\2%\1/g'
↑はどっかで拾ってきたやつだけど、
変換しなくていい文字とか、スペースと+の変換とかまで考慮したのを
スマートに誰か書いてちょーだい
0637名無しさん@お腹いっぱい。
2006/06/21(水) 17:13:38それ以前に、その拾ってきた奴というのがバイトオーダーの問題で
環境によっては動かないはずだが。
0638名無しさん@お腹いっぱい。
2006/06/21(水) 17:20:10RubyかPerlでやれば?
0639名無しさん@お腹いっぱい。
2006/06/21(水) 19:42:56Solaris9=SunOS5.9
Solaris8=SunOS5.8
Solaris7=SunOS5.7
0640名無しさん@お腹いっぱい。
2006/06/21(水) 19:49:59Solaris 11
0641名無しさん@お腹いっぱい。
2006/06/21(水) 20:15:43Linux 2.4
0642名無しさん@お腹いっぱい。
2006/06/21(水) 20:41:140643名無しさん@お腹いっぱい。
2006/06/21(水) 21:14:47ttp://jp.rubyist.net/magazine/?0001-NoraTutorial#l10
0644名無しさん@お腹いっぱい。
2006/06/21(水) 21:54:47Darwin 8.6.2
0645名無しさん@お腹いっぱい。
2006/06/21(水) 22:27:13放っておくとtcshのシェルスクリプトを書くような連中なので
tcsh/csh/zshのシェルスクリプトは禁止する予定なのですが、
ターゲットはSunOSなので放っておくとbash固有の機能を使いかねません。
ボーンシェルのシェルスクリプトの仕様を提示したいのですがどこかにあるでしょうか?
0646名無しさん@お腹いっぱい。
2006/06/21(水) 22:57:510647名無しさん@お腹いっぱい。
2006/06/21(水) 23:04:57マシンも環境も同じにするのがプロの発注。
0648名無しさん@お腹いっぱい。
2006/06/21(水) 23:25:53理由はわからぬ。
0649名無しさん@お腹いっぱい。
2006/06/21(水) 23:34:17現物(マシン+OS+sh)を貸し出してこれで動くようにしろ、
というのが確実。
で、cshで書いてしまうような外注は捨てて、
もっとマシな所に発注するのがもっとも確実。
0650645
2006/06/21(水) 23:40:59元請の弊社は発注元と下請けの間の調整もせず勝手にやってというのが
基本姿勢のクズ会社なのでどっちもどっちなのです。
ポータビリティは考えずに、動作するコーンシェルのバージョンを指定しようと思います。
0651名無しさん@お腹いっぱい。
2006/06/22(木) 00:12:29…英語の仕様書が読めるわけもないか。
0652名無しさん@お腹いっぱい。
2006/06/22(木) 04:08:140653名無しさん@お腹いっぱい。
2006/06/22(木) 09:36:23ヘボじゃない奴はcshではスクリプト書きにくいのにすぐ気がついて書かなくなるから
当然の帰結じゃないか。
0654名無しさん@お腹いっぱい。
2006/06/22(木) 09:44:09を使っているのはみたことがある。
0655名無しさん@お腹いっぱい。
2006/06/22(木) 11:57:13cshは恐くない
0656名無しさん@お腹いっぱい。
2006/06/22(木) 12:00:510657名無しさん@お腹いっぱい。
2006/06/22(木) 12:14:55cshはUNIXの汚点
0658名無しさん@お腹いっぱい。
2006/06/22(木) 12:47:42それはチューリングマシンでCGIを書くことに匹敵するほど実りの無いこと。
0659名無しさん@お腹いっぱい。
2006/06/22(木) 15:19:23Solarisからむなら普通ksh
0660名無しさん@お腹いっぱい。
2006/06/22(木) 15:21:57>>650
ただし、「kshの同じバージョン」はSolaris以外では用意できないと思われ。
Linuxにあるksh(pdkshじゃなくてkshだよ)は、Solarisのkshとは
結構動作が違う。
0661名無しさん@お腹いっぱい。
2006/06/23(金) 22:15:00いまの下請けはLinux で開発すんの?
0662名無しさん@お腹いっぱい。
2006/06/23(金) 22:26:580663名無しさん@お腹いっぱい。
2006/06/23(金) 23:08:390664名無しさん@お腹いっぱい。
2006/06/28(水) 17:24:430665名無しさん@お腹いっぱい。
2006/06/28(水) 17:32:070666名無しさん@お腹いっぱい。
2006/06/28(水) 17:43:33できました. でも質問が間違ってました. 改めて
2行以上連続する空行は1行に縮め,
1行だけの空行はその行を削除するにはどうすればいいですか?
0667名無しさん@お腹いっぱい。
2006/06/28(水) 18:03:340668名無しさん@お腹いっぱい。
2006/06/28(水) 19:35:20■ このスレッドは過去ログ倉庫に格納されています