シェルスクリプト総合 その5
レス数が900を超えています。1000を超えると表示できなくなるよ。
0001名無しさん@お腹いっぱい。
2006/01/21(土) 09:00:29スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。
□お約束
・特記なき場合はbourne shがデフォルトです。
bash/csh/tcsh/zsh/ksh/ashなどに依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashなので特に注意。
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
manや参考リンクを見ましょう。
aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
0811名無しさん@お腹いっぱい。
2006/03/19(日) 01:47:49man test
0812名無しさん@お腹いっぱい。
2006/03/19(日) 04:34:39if [ -d あるディレクトリ ]
then
○○
else
停止
fi
0813名無しさん@お腹いっぱい。
2006/03/19(日) 06:04:35A = 'ps ax | grep あるディレクトリ | wc -l'
if [ $A ]; then
○○
else
停止
fi
0814名無しさん@お腹いっぱい。
2006/03/19(日) 06:05:20A = 'ls | grep あるディレクトリ | wc -l'
if [ $A ]; then
○○
else
停止
fi
0815名無しさん@お腹いっぱい。
2006/03/19(日) 09:02:40何がしたいんだ? >>812の正解のあとで間違った答えを出して
0816名無しさん@お腹いっぱい。
2006/03/19(日) 09:26:290817名無しさん@お腹いっぱい。
2006/03/19(日) 09:26:39君も man test
0818名無しさん@お腹いっぱい。
2006/03/19(日) 09:32:34>>812 正解。
>>813-814 初心者かな? >>812 の正解を参照汁。
それだとディレクトリがなくても wc -l の結果の 0 が Aに入るので、
ifで常に結果が真になる。grepでの判定も曖昧。
そんなことしなくても [ -d hoge ] でできることを覚えろ。
0819名無しさん@お腹いっぱい。
2006/03/19(日) 09:34:42おまえら一生manだけ読んでろ。manを読むばかりで手を動かさない机上の空論者だな。
0820名無しさん@お腹いっぱい。
2006/03/19(日) 09:40:23はぁ?
>>806 はfind実行する前に ` `が展開されるよ。
しかも、find の -exec のあとは直接のコマンドであって、
シェルスクリプトではないため、
-execの実行時には一切のシェルの解釈を受け付けない。
だから、仮に ` ` がfindの実行前に展開されていないとすると、
逆に -exec の時に ` ` がエラーになる。
いずれにしても、>>806 は大間違い。
俺は正解を知ってるが、回答者バトルのために敢えて書かない。
わかるモン居たら書いてみろ。
0821名無しさん@お腹いっぱい。
2006/03/19(日) 09:50:160822名無しさん@お腹いっぱい。
2006/03/19(日) 10:45:01熱くなりすぎ。>>808は>>807への突っ込みだと取ったんだが。
0823名無しさん@お腹いっぱい。
2006/03/19(日) 13:05:49それに突っ込んでる >>808 は間違い。
おおもとの >>806 が間違いなのは言うまでもないが。
0824名無しさん@お腹いっぱい。
2006/03/20(月) 12:00:36私英語苦手・・・・じゃなくて、日本語苦手。
0825名無しさん@お腹いっぱい。
2006/03/20(月) 14:43:210826名無しさん@お腹いっぱい。
2006/03/20(月) 16:27:410827名無しさん@お腹いっぱい。
2006/03/20(月) 16:36:01アンカー先間違えてる?
818にそう言っても話が繋がらないのだが・・
0828名無しさん@お腹いっぱい。
2006/03/20(月) 16:51:180829名無しさん@お腹いっぱい。
2006/03/20(月) 21:22:48カレントディレクトリ以下(サブディレクトリ含)にある.c,.cc,.cppのファイル数を知りたいのですが、どうしたらよいのでしょうか。
find ./* -name *.c | wc -l
をそれぞれの拡張子で、では無く、一発で3種類のファイル数を求める方法を知りたいです。
後、
./script < inputfile
と入力した時、inputfileの中身をscript内で使うにはどうしたらよいでしょうか。
./script 1 2
とやると$1に1、というようになりますが、ファイルに
1
2
とあり、そのファイルを入力として渡す時はどのようにして1や2を得るのでしょうか。
0830名無しさん@お腹いっぱい。
2006/03/20(月) 21:40:01Q1 何故、findの機能を調べようとしないんだ?
Q2 何故、そのスクリプトエンジンの機能を調べようとしないんだ?
0831名無しさん@お腹いっぱい。
2006/03/20(月) 22:28:060832名無しさん@お腹いっぱい。
2006/03/20(月) 22:33:50そういうお答えはご遠慮願います。
ちゃんとわかる方のみ、ご回答よろしくお願いします。
0833名無しさん@お腹いっぱい。
2006/03/20(月) 22:38:06一問目は、man shかman bashして、
パス名展開(Pathname Expantion) のところ読んでね。
0834名無しさん@お腹いっぱい。
2006/03/20(月) 22:44:35>>829 の1問目は、「一発で3種類のファイル数を(それぞれ)求める方法」
らしいから、それは shの「パス名展開」を読んでも解決にならないだろ。
0835名無しさん@お腹いっぱい。
2006/03/20(月) 22:47:220836名無しさん@お腹いっぱい。
2006/03/20(月) 22:48:35死ねよ。クズ。
0837829
2006/03/20(月) 22:49:10忠告ありがとうございます。
findの方は -o -name の追加でなんとかなりました。
ファイル入力の方、ファイル名がスクリプト内で取得可能ならexecでどうこう出来る、
というのを見つけたのですが、肝心のファイル名をどうやって知ればいいのかわからんです。
なんか検索ヒント下さい。
0838名無しさん@お腹いっぱい。
2006/03/20(月) 22:52:35「それぞれ」で無くてもよかったのだけど、その場合一発で出来るんですかね。
0839名無しさん@お腹いっぱい。
2006/03/20(月) 22:54:221問目:
「一発で」というならfindやシェルスクリプトでは無理。
3回もfindしたくないということなら、
近い方法として、
find . -name '*.c' -o -name '*.cpp' -or -name '*.cc'
の結果をシェル変数またはテンポラリファイルに一旦取り込み、
その内容を
grep '\.c$' | wc -l
grep '\.cc$' | wc -l
grep '\.cpp$' | wc -l
すればよい。
2問目:
./scriptの中で readコマンドで標準入力の内容が1行ずつ読み込める。
普通、while readみたいにして使う。
0840名無しさん@お腹いっぱい。
2006/03/20(月) 22:57:06「それぞれ」でなくていいなら、
find . -name '*.c' -o -name '*.cpp' -or -name '*.cc' | wc -l
で一発。
0841名無しさん@お腹いっぱい。
2006/03/20(月) 22:59:190842名無しさん@お腹いっぱい。
2006/03/20(月) 23:02:07使われてるって現実もあるし。微妙な所か。
0843829
2006/03/20(月) 23:12:56>>839
while read var
して$varを全部echoしてみたのですが、最初の値が0になっている。こういうものなの?
一つ目を無視すれば済むのだろうけど。
0844名無しさん@お腹いっぱい。
2006/03/20(月) 23:18:14おそらく、whileループの「外」でechoしてるんだろう、とエスパーしてみる。
while readする場合にはちょっと癖があって、
while文の部分がサブシェルで実行されるので、
varに値を入れても、
whileループを抜けると消えてしまう(←ちょっと不正確な表現)んだよ。
うまく工夫してそれを避けるしかない。
0845名無しさん@お腹いっぱい。
2006/03/20(月) 23:19:32find . \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' \) -exec basename {} \; | \
( c=0 ; cc=0 ; cpp=0 ; while read i; do case $i in *.c ) c=`expr $c + 1`;; *.cc) cc=`expr $cc + 1`;; *.cpp) cpp=`expr $cpp + 1`;; esac; done; printf '*.c = %d\n*.cc = %d\n*.cpp = %d\n' $c $cc $cpp )
長すぎたので途中で折り返してる。
てか1行で書く必要は無いのか?
0846名無しさん@お腹いっぱい。
2006/03/20(月) 23:20:04この場合は while readを使わずに、
set `cat`
で読み込め。
これで、引数で起動したのと同じように
そのまま $1 $2 ... に代入されるよ。
0847845
2006/03/20(月) 23:20:140848829
2006/03/21(火) 00:06:34なんかよく分からないけど0が消えました。
さっき全く同じコードの筈なんだけどな。
入力ファイルの頭が0だった、なんて事は無いです。
while read var
do
echo $var
done
で0無しで動きました。不安なので再現狙ってみます。
>>845
長いからスクリプト書いた方が とか
でも一行で書けるものなんだと驚いたのも確か
>>846
うまいこと行きました。便利ですねこれ。さんくすです。
みなさんありがとうございました
0849名無しさん@お腹いっぱい。
2006/03/21(火) 00:10:20ちょっと作ってみた
--
find . -type f | egrep '\.(c|cc|cpp)$' | \
rev | cut -d. -f1 | rev | sort | uniq -c | sort -nr
--
egrepの部分に集計したい拡張子追加してね。
0850名無しさん@お腹いっぱい。
2006/03/21(火) 00:37:22rev | cut -d. -f1 | rev
の部分、面白いと思うけど、
プロセス3つも使うの無駄っぽいから、俺なら、
sed 's/.*\.\(.*\)$/\1/'
にするかな。
0851名無しさん@お腹いっぱい。
2006/03/21(火) 00:49:35それならもっと簡単に書ける。
sed 's/.*\.//'
0852名無しさん@お腹いっぱい。
2006/03/21(火) 00:55:46アイデアが膨らんで、スレのレベルが上がるねぇー。
0853名無しさん@お腹いっぱい。
2006/03/21(火) 01:07:00訊き捨ての香具師にはman嫁でじゅーぶん
0854名無しさん@お腹いっぱい。
2006/03/21(火) 01:41:260855名無しさん@お腹いっぱい。
2006/03/21(火) 01:45:48egrep のところは find -regex を使った方がお手軽だと思う。
>>850-851 のアイディアも加えるとこんな感じ?
find . -type f -regex '.*\.\(c\|cc\|cpp\)' | sed 's/.*\.//' | sort | uniq -c | sort -nr
0856名無しさん@お腹いっぱい。
2006/03/21(火) 02:41:54したいんだったら、egrep 使った方がいいよ。
OS 依存でいいなら構わんが。
0857名無しさん@お腹いっぱい。
2006/03/21(火) 02:53:14egrepってOS非依存か?
0858名無しさん@お腹いっぱい。
2006/03/21(火) 03:35:450859名無しさん@お腹いっぱい。
2006/03/21(火) 03:47:17-regex って GNU 拡張だったんだ。
憶えておくよ。
egrep と grep -E ってどっちがポータブルなの?
0860名無しさん@お腹いっぱい。
2006/03/21(火) 03:50:09もう少しポータブルだけどね。4.4BSD 系 OS のマニュアルには、
拡張機能だと明記してあるんだが。
egrep と grep -E では、egrep の方がポータブル。
0861名無しさん@お腹いっぱい。
2006/03/21(火) 07:38:290862名無しさん@お腹いっぱい。
2006/03/21(火) 09:39:23findの -regexがダメというなら、パイプで egrepするよりは、
find自身で -name '*.c' -o -name '*.cc' -o -name '*.cpp'
でいいと思う。ちゃんと書き直すと、
find . -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' \) \
| sed 's/.*\.//' | sort | uniq -c | sort -nr
かな。
findの -type fを省略していいなら、その後の \( \) も省略できる。
0863名無しさん@お腹いっぱい。
2006/03/21(火) 11:19:300864名無しさん@お腹いっぱい。
2006/03/21(火) 11:25:04よし、存分に語れ。
0865名無しさん@お腹いっぱい。
2006/03/21(火) 11:29:26それはそれは…是非ご教授願いたい。
0866名無しさん@お腹いっぱい。
2006/03/21(火) 11:40:07POSIX!何ですかそれは!是非ご啓示ください!!
0867名無しさん@お腹いっぱい。
2006/03/21(火) 11:46:58実際の各種OSで使われているシェルやコマンドは、
POSIXと同じではない。
だから、そもそもPOSIXと同じではない各種OS間のポータビリティを
考えるなら、POSIX云々ではなく、実際に各種OSでの状況を調べて
対応するのが実践的で現実的。
0868名無しさん@お腹いっぱい。
2006/03/21(火) 13:34:460869名無しさん@お腹いっぱい。
2006/03/21(火) 14:09:32登録は必要だけど、無料だよ。
ttp://www.unix.org/version3/online.html
0870名無しさん@お腹いっぱい。
2006/03/21(火) 14:38:19POSIX新聞?うちは取らないよ。
0871名無しさん@お腹いっぱい。
2006/03/21(火) 15:47:04>・特記なき場合はbourne shがデフォルトです。
今どき、bourne shをデフォルトにしているのなんて、
Solarisくらいしかないじゃん。
0872名無しさん@お腹いっぱい。
2006/03/21(火) 15:54:560873名無しさん@お腹いっぱい。
2006/03/21(火) 16:04:460874名無しさん@お腹いっぱい。
2006/03/21(火) 16:08:57> egrep と grep -E では、egrep の方がポータブル。
嘘おっしゃい。
0875名無しさん@お腹いっぱい。
2006/03/21(火) 16:09:180876名無しさん@お腹いっぱい。
2006/03/21(火) 16:30:18するようなプログラム作るとめっさ速そうなんだけど。無理?
0877名無しさん@お腹いっぱい。
2006/03/21(火) 16:41:16Linux とか POSIX の仕様しか知らない最近の人だと、そう思うかも
しれないね。SUSv3 を見ると egrep は載ってなくて grep -E だけ
が書いてあるし。
でも、もともと egrep と grep は別のコマンドで、使っているアル
ゴリズムも egrep は DFA、grep は NFA で異なっていた。10年くらい
前だと、grep に -E オプションがない OS も沢山あったよ。
これに対し、egrep はベル研 UNIX 時代から存在する由緒あるコマンド
で、事実上すべての UNIX に存在するはず。
ttp://www.bookshelf.jp/texi/autoconf-ja/autoconf-ja_10.html
> POSIX 1003.1-2001では,もはやegrepを要求していませんが,より古いホスト
> の多くはまだPOSIXのgrep -Eでの置換をサポートしていません.この問題を回
> 避するため,AC_PROG_EGREP を呼び出し,$EGREPを使用してください
0878名無しさん@お腹いっぱい。
2006/03/21(火) 16:48:05Solarisだと/usr/xpg4/bin/grepにしか-Eオプションは無くて/usr/bin/grepでは-Eは使えない。
他のOSでも使えるようにgrep -Eをスクリプトに書くのはちょいめんどくさいな。
0879名無しさん@お腹いっぱい。
2006/03/21(火) 16:54:26まずはPOSIXを読めな? ごたくはそれからだ。
0880名無しさん@お腹いっぱい。
2006/03/21(火) 17:01:07pthread使ったファイル検索プログラムがButenhofのpthread本に
載ってたような。
0881名無しさん@お腹いっぱい。
2006/03/21(火) 18:53:18>>877 見ても、POSIXよりも autoconfの方がよほど現実的というところか。
0882名無しさん@お腹いっぱい。
2006/03/21(火) 21:15:57相変わらず
0883名無しさん@お腹いっぱい。
2006/03/21(火) 21:27:27鬱ですねぇ。
0885名無しさん@お腹いっぱい。
2006/03/22(水) 02:14:100886名無しさん@お腹いっぱい。
2006/03/22(水) 09:40:58その後は究極のProxy★ガブリエナイで優雅にproxy生活だったさ!!
0887名無しさん@お腹いっぱい。
2006/03/22(水) 18:01:04分野 : セキュリティ > ネットワーク
インターネット上で公開されている操作が簡単なクラックツールを利用して、興味
本位の不正アクセスを試みる「幼稚な」クラッカー。
クラックツールは既に広く知られているセキュリティホールを悪用するように作成されているため、
セキュリティパッチを確実に適用することで、ほとんどのスクリプトキディによる攻撃は防止できる。
クラックツールを使えば深い知識や高度な技術がなくても簡単に攻撃を行なうことができるため、
数の上ではクラッカーのほとんどはスクリプトキディであると言われる。
0888名無しさん@お腹いっぱい。
2006/03/23(木) 15:38:21という理解でよろしいでしょうか?
0889名無しさん@お腹いっぱい。
2006/03/23(木) 15:39:590890名無しさん@お腹いっぱい。
2006/03/24(金) 02:30:15いえ Korn Shell です。
0891名無しさん@お腹いっぱい。
2006/03/24(金) 07:37:06まあそんなに汎用性気にするならPerl使えという気もするが。
0892774
2006/03/24(金) 07:55:17http://news18.2ch.net/test/read.cgi/news4plus/1143149170/
0893名無しさん@お腹いっぱい。
2006/03/24(金) 08:08:44一番移植性が高いのはBourne Shellということで合ってる。
当たり前過ぎて誰も答えなかっただけ。
>>890
初心者が本気にするかも知れないから、そういう嘘書くのやめろ。
0894名無しさん@お腹いっぱい。
2006/03/24(金) 09:31:20では移植性の高さを定量的に比較し提示してください。
0895名無しさん@お腹いっぱい。
2006/03/24(金) 09:42:42誰もが常識として知っていることをあなたに説明して教える筋合いはない。
知りたければ自分で知ろうとする努力をしなさい。
0896名無しさん@お腹いっぱい。
2006/03/24(金) 09:45:05つまり根拠なき妄言てことですな。自白乙。
0897名無しさん@お腹いっぱい。
2006/03/24(金) 09:48:12大丈夫。みんな妄想してるから。
0898名無しさん@お腹いっぱい。
2006/03/24(金) 10:42:36「kshが移植性が一番高い」などとマジで言ってるなら重症だぞ。
ヨソでそんなこと言って恥かくなよ。
0899名無しさん@お腹いっぱい。
2006/03/24(金) 10:50:45汎用性と移植性は違う気がする。
汎用性は用途の広さだよね。
それならどのシェルもほとんど変わらない気がする。
0900名無しさん@お腹いっぱい。
2006/03/24(金) 10:53:40$ ssh freebsd-host
freebsd$ ksh
ksh: not found
freebsd$ exit
$ ssh linux-host
linux$ ksh
ksh: not found
linux$ exit
....noway, what more can I say ?
0901名無しさん@お腹いっぱい。
2006/03/24(金) 11:18:12お前のマシンに当該シェルがあるかどうかなんて聞いちゃいねー
0902名無しさん@お腹いっぱい。
2006/03/24(金) 11:25:36そのとおりだが、漏れもpdkshなんて使わんからアンインストールしてるよ。
0903名無しさん@お腹いっぱい。
2006/03/24(金) 11:29:27はぁ?
どんなホストでも、誰のホストでも、
デフォで動くというのが「移植性」の必須条件なわけだが。
0904名無しさん@お腹いっぱい。
2006/03/24(金) 11:31:390905名無しさん@お腹いっぱい。
2006/03/24(金) 11:34:37そういう標準化の為に色々大人が事情をつくるのよ
どんなUNIX95のホストでもとか
POSIXに準拠したホストでもとか
0906名無しさん@お腹いっぱい。
2006/03/24(金) 11:50:29だからPOSIXって実際には使えないわけですね。
0907名無しさん@お腹いっぱい。
2006/03/24(金) 13:38:490908名無しさん@お腹いっぱい。
2006/03/24(金) 13:57:13たくさん釣れましたね。
確かに、本当にKorn Shellが移植性が高かったら良かったかも知れませんね。
でも現実にはもう遅いですね。
0909名無しさん@お腹いっぱい。
2006/03/24(金) 14:24:020910名無しさん@お腹いっぱい。
2006/03/24(金) 21:56:42レス数が900を超えています。1000を超えると表示できなくなるよ。