トップページunix
1001コメント305KB

シェルスクリプト総合 その14

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。2009/01/29(木) 06:54:48
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。


□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashなので特に注意。
FreeBSDユーザは/bin/shの正体がashなので注意。
v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/
http://heirloom.sourceforge.net/sh.html
・csh/tcshのシェルスクリプトは推奨されません。
(理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
 manや参考リンクを見ましょう。
 aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)

□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。

前スレ落ちたみたいなのでリンク省略。
0488名無しさん@お腹いっぱい。2009/04/19(日) 01:42:00
純正だしw
0489名無しさん@お腹いっぱい。2009/04/19(日) 03:39:34
>>487
awkやRATFORは当時凄くシンプルで仕様の美しい言語。
0490名無しさん@お腹いっぱい。2009/04/19(日) 08:27:53
>>484
> 英語でコメント書かないといけない理由は分からん。

当然社内に外国人担当者もいる。
書いたスクリプトが海外の支社に回ることもある。
コンソールなど日本語が通らない環境でもスクリプトを読みたい時がある。
シェルによってはコメントに日本語が入ったスクリプトをLANG=Cで実行すると発狂する
日本語だと、EUCかUTF-8かJISかSJIS(←これはないが)か悩む必要がある。
0491名無しさん@お腹いっぱい。2009/04/19(日) 11:04:10
偽英語で意味不明のコメント書かれるよりは…
コメント書くために時間かけられるよりは…
時間書けるのを避けるために嘘コメントが残るよりは…
というわけで、母国語のコメント推奨。

必要な時に翻訳すれば良い。
0492名無しさん@お腹いっぱい。2009/04/19(日) 11:09:32
ローマ字を使えば全て解決
0493名無しさん@お腹いっぱい。2009/04/19(日) 15:45:28
>>482
\\\\の処理具体的にどういう話?
どんだけトリッキーなのか、簡単な処理でいいので解説してちょ
>>491
技術文書なんだから中学英語でいいじゃん
英語説明に不安なら同じ説明を違う言い方で二回書けばいいんじゃねえ?
それか、使い方の例を載せるとか

エロイ人は計詳細設計も英語onlyなのかな?
日本語でしっかり書いて、英語で簡単な説明を書くみたいな感じ?
>>491
母国語のコメント推奨とかいうヤツってマジで害悪だよ
母国語の説明に飢えているなら、readme_jp.txtで簡単な説明を書いてもらえいいんじゃない
0494名無しさん@お腹いっぱい。2009/04/19(日) 16:03:59
>>493
日本がいやなら出てけよ。
0495名無しさん@お腹いっぱい。2009/04/19(日) 16:50:33
bashみたいなshに変な機能が追加されてるシェルで悩むくらいなら
cshで書いてしまったほうが圧倒的な汎用性を得られる。
0496名無しさん@お腹いっぱい。2009/04/19(日) 16:56:24
>>495
釣りとしても面白くない。

最近のLinuxには (t)cshがデフォではインストールされていない。
0497名無しさん@お腹いっぱい。2009/04/19(日) 16:59:29
>>495
さすがに論外なんじゃない?
それならLL言語で書いてもらったほうがいい。

Perlだとちょっとこわいけど。
0498名無しさん@お腹いっぱい。2009/04/19(日) 17:13:56
>>494
プログラマーの共通言語は英語。
0499名無しさん@お腹いっぱい。2009/04/19(日) 17:25:26
>>494
1世紀ちょっと前にちょんまげを切ったんだから、そろそろ近代化しようぜ
0500名無しさん@お腹いっぱい。2009/04/19(日) 17:49:34
ダクラス・マッカーサーが「アメリカがもう40代なのに対して日本は12歳の少女だ」
と表現したのを知らないの?
実際、そうだったわけだが。

今は、いくつなんだろうか。大学卒業したぐらい?
0501名無しさん@お腹いっぱい。2009/04/19(日) 18:36:15
>>500
それは民主主義の成熟度に対して言ったものなので
全然話が違いますがな。
0502名無しさん@お腹いっぱい。2009/04/19(日) 18:43:05
40のオッサンが12歳の少女をレイプしまくった訳ですね
0503名無しさん@お腹いっぱい。2009/04/19(日) 19:03:28
国家としての成熟度じゃ、日欧にかないませんわな、アメリカは。どう足掻いても。

まぁその欧の中でも英国は大陸の神話とかに対し憧れとかあるらしいが。トールキンに
関する話によれば。
0504名無しさん@お腹いっぱい。2009/04/19(日) 19:36:07
>>501
明治になって、至ってまともな民主主義だったと言われているよ。
朝日だって最初は反戦だったけど、反戦だと売れないから戦争に賛成になったわけで。
本だって発禁されても、出版社は発禁本と逆に名乗って、商売して儲けたらしいし。
改憲派の中でも明治憲法が理想の人は結構多いと思うよ。

そりゃあ、西欧の民主主義と比べたら歴史の年数が違うから成熟したとは、言い難いし。
宗教や人種で30世紀近くさんざん揉めている国々との外交力の差は明らかだよね。

なんというシェルスクリプトスレw
明治憲法みたいに真面目に設計すればいいものはできるという話かw
後任者の保守運用が・・・
0505名無しさん@お腹いっぱい。2009/04/19(日) 19:57:15
2chは末期だな
0506名無しさん@お腹いっぱい。2009/04/19(日) 20:26:19
>>500
奴隷制度現役だった国に言われたくはないわw
0507名無しさん@お腹いっぱい。2009/04/19(日) 20:31:34
>>504
法学板にでも行きなされ。うざいよ。

ところで、読む相手が日本人しかいないと分かってるスクリプトに
無理して英語でコメントを書くのは時間の無駄じゃないかな。
UTF-8で書いてあれば問題は起こらないわけだし。
05085012009/04/19(日) 21:01:45
本題に戻って、おまいらちょっくら教えてください。
↓のような感じのPOPのLOGINログを抜き出したのが山のようにあります。
---
Apr 19 01:23:45 popsvr1 pop3d: [ID 232323 mail.info] LOGIN, user=hogehoge, ip=[192.168.1.2]
(popsvr1はホスト名、232323は固定値(再起動しない限り不変)です)
---

このログから「2009/04/19 01:23:45,hogehoge,192.168.1.2」のように
日時とユーザ名とIPアドレスを抜き出してCSVに変換したいのですが、
シェルスクリプトで高速に動かすうまい方法はないでしょうか?
# 年は今年(date +'%Y'で得られる年)とします。

とりあえずcutコマンド等をひたすら使った稚拙なスクリプトは作っては
みたものの、30万行ほどログを処理させると、Core2Duoのそこそこの
CPU環境でも20分ぐらいかかってしまいまつ。(´・ω・`)

何かうまい方法があったら教えてください。おながいします。
0509名無しさん@お腹いっぱい。2009/04/19(日) 21:12:11
>>508
とりあえず、kshで実行してみたら?
それでも遅いのなら、シェルスクリプトで実行すること自体が
問題なのだと思う。
05105012009/04/19(日) 21:22:29
>>509
ありがとうございます。
/bin/shで実行させていたので、明日試してみます。
(手元に実行環境が無いもので…)
0511名無しさん@お腹いっぱい。2009/04/19(日) 21:26:41
>>508
あえてシェルの内部コマンドだけで書いてみたよ。


while IFS=' =,[]' read mon day time d1 d2 d3 d4 d5 d6 d7 user d8 ip
do
echo 2009/$mon/$day $time,$user,$ip
done

あと、Aprを 04に変換したりするのだけパイプで sed でやってね。
0512名無しさん@お腹いっぱい。2009/04/19(日) 21:29:32
>>508
そのスクリプトでトータル何行(未来の行数も含めて)のログを処理させたいの?
0513名無しさん@お腹いっぱい。2009/04/19(日) 21:34:50
>>511
そこまでできてるなら、echoの直前に

case $mon in Jan)mon=01;;Feb)mon=02;;Mar)mon=03;;Apr)mon=04;;..省略..;;esac

の行を入れれば sedも不要。全部シェルでできる。
05145012009/04/19(日) 21:43:29
>>511, >>513
ありがとうございますた。参考にさせていただきまつ。m(__)m

>>512
今のところ30万行ぐらいなんですが、もしかしたら最大で
500〜600万行ぐらい処理するかもしれません。
0515名無しさん@お腹いっぱい。2009/04/19(日) 23:05:25
プログラミングで飯喰ってるPGならシェルスクリプトや何の言語でもさっと読んで理解するのを期待したい所では有るな。
コメントに頼るレベルで、プログラムで飯喰おうってのが甘い気がする。
もちろん母国語的、得意な言語が有って、それで前任者のプログラム置き換えていけばいいと思うけどね。
前任者がシェルスクリプトで組んでても、修正出来ないじゃ、作り直すしか無いし。


汎用的なシェルスクリプトよりは、いろいろな環境の癖を知って臨機応変に組めたほうが重宝すると思う。
いろんな環境を体験する事かな。SunOS, Solaris, Linux(rhel系,フリー系), Windows(cygwin, interix)ぐらいかなあ。SunOSはもう流石に無いと思いたいwww
0516名無しさん@お腹いっぱい。2009/04/19(日) 23:15:44
>>515
http://pc12.2ch.net/test/read.cgi/unix/1012927963/
0517名無しさん@お腹いっぱい。2009/04/20(月) 01:23:45
>>515
うちのところにもこういう人います。
意外と仕事が雑なんですよね・・・
0518名無しさん@お腹いっぱい。2009/04/20(月) 01:57:50
>>508
Apr 19 01:23:45 popsvr1 pop3d: [ID 232323 mail.info] LOGIN, user=hogehoge, ip=[192.168.1.2]をただ300万行コピペしたファイルをうちの並のマシンで1分38秒出た
メモリも喰わないし、シェルスクリプトってかなりいいタイム出すんだね

$ time ( cat pop-300.txt | ksh 2ch-shell-20090419a-foo.sh >> pop-300.cvs ) &
[7] 27015
$
real 1m38.872s
user 0m26.174s
sys 1m12.485s

[7] Done time ( cat pop-300.txt | ksh 2ch-shell-20090419a-foo.sh >> pop-300.cvs )
$ wc pop-300.cvs
300000 600000 12900000 pop-300.cvs
$ tail pop-300.cvs
2009/04/19 01:23:45,hogehoge,[192.168.1.2]
2009/04/19 01:23:45,hogehoge,[192.168.1.2]
2009/04/19 01:23:45,hogehoge,[192.168.1.2]
2009/04/19 01:23:45,hogehoge,[192.168.1.2]
2009/04/19 01:23:45,hogehoge,[192.168.1.2]
2009/04/19 01:23:45,hogehoge,[192.168.1.2]
2009/04/19 01:23:45,hogehoge,[192.168.1.2]
2009/04/19 01:23:45,hogehoge,[192.168.1.2]
2009/04/19 01:23:45,hogehoge,[192.168.1.2]
2009/04/19 01:23:45,hogehoge,[192.168.1.2]
05195182009/04/20(月) 02:23:18
bashよりkshは3.5倍速った
こんなに違うのか

$ time ( cat pop-300.txt | sh 2ch-shell-20090419a-foo.sh >> pop-300.cv2 ) &
real 5m45.010s
user 4m31.791s
sys 1m11.200s
$ time ( cat pop-300.txt | bash 2ch-shell-20090419a-foo.sh >> pop-300.cv3 ) &
real 5m47.776s
user 4m34.900s
sys 1m12.200s
0520名無しさん@お腹いっぱい。2009/04/20(月) 02:31:55
空行を五行文だすときに
------------------------
echo aaa
echo ""
echo ""
echo ""
echo ""
echo ""
echo bbb
------------------------

以上のようにしているのですが、もっとエレガントな方法ってないですか?
イメージ的には
echo "" * 5
ってやると空行が五行文出力されるようなものです。
0521名無しさん@お腹いっぱい。2009/04/20(月) 02:54:54
echo "aaaa"
for i in `seq -w 5`; do echo ""; done
echo "bbbb"
for i in "" "" "" "" ""; do echo $i; done
echo "cccc"
printf "\n"; printf "\n"; printf "\n"; printf "\n"; printf "\n";
echo "dddd"
echo; echo; echo; echo; echo;
echo "eeee"
# どれか?
# というか、普通にecho ""を縦に並べたほうがみやすいんじゃないの?
0522名無しさん@お腹いっぱい。2009/04/20(月) 03:11:36
>>521
自己レスだけど;(セミコロン)は、C言語としての文の終わりとしての意味合いの記号じゃないから、;は入れないほうが望ましいって本に書いてあったな
なにかあるってわけじゃないんだろうけど
printf "\n"; printf "\n"; printf "\n"; printf "\n"; printf "\n"
echo "dddd"
echo; echo; echo; echo; echo
echo "eeee"
0523名無しさん@お腹いっぱい。2009/04/20(月) 07:06:13
>>520
1個のechoで、改行含めて見たままシングルクォートにするのがエレガント。

echo 'aaa





bbb'

以上
0524名無しさん@お腹いっぱい。2009/04/20(月) 07:17:56
そういやこういうのもあるね
echo -e "aaaaa\n\n\n\n\nbbbbb"
>>523
シングルクォートの意味はあるんですか?
あとでダブルクォートを入れやすくするため?
0525名無しさん@お腹いっぱい。2009/04/20(月) 07:25:46
>>524
不用意な展開を防ぐため。

基本はすべてシングルクォート。
$HOGE とか `com` とか、展開が必要な時のみダブルクォート、というのがルール。
0526名無しさん@お腹いっぱい。2009/04/20(月) 07:44:04
>>525
さんくす
もっといっぱい本を読んで、写経します
0527名無しさん@お腹いっぱい。2009/04/20(月) 09:31:41
>>519
kshの速さを実感して貰えて何より。
いまいちマイナーなのが不思議だったりする。
0528名無しさん@お腹いっぱい。2009/04/20(月) 12:48:18
kshは商用SystemV系ってイメージあるし
0529名無しさん@お腹いっぱい。2009/04/20(月) 12:58:57
>>527
昔はこぞってみんな使ってたんだぜ。
bashがなかった時代だけど。
0530名無しさん@お腹いっぱい。2009/04/20(月) 13:16:27
>>525
自分ルールを標準のごとく言ったりエレガントとか言うのはどうかと思う
520〜523までなら後から見たときや他人が書いたものを見たとき520が一番見やすい

echo の内容を | を通して渡す為に >>523 にしたというならともかく(この場合でも他に方法はいくらでもあるけど)
0531名無しさん@お腹いっぱい。2009/04/20(月) 14:16:51
仕事で使うのは最近はkshばかりだなー
マイナーという
0532名無しさん@お腹いっぱい。2009/04/20(月) 14:17:41
マイナーというのはどうかな
0533名無しさん@お腹いっぱい。2009/04/20(月) 14:35:10
>>527
なぜかOpenBSDで使われているShellって感じですね

2000年まで、Korn shell は AT&T の権利保有するソフトウェアであった。その後AT&T独自
のライセンスの下でオープンソースとなり、2005年から Common Public License での配布
となった。Korn shell は AT&T Software Technology (AST) Open Source Software
Collection の一部として入手可能である。
と書いてあるけど、2000年以前は無料で使えなかったんでしょうか?
10年前ぐらい訳本には商用うんぬんと書いていないから15年前ぐらいからは入手的には困らなかったんだろうか
OpenBSD誕生が1996年みたいだけど、標準Shellは、なんだったのだろうか
最初からksh?

あとなんちゃってUNIXユーザーとしては、知名度だと
bash >>> sh >= zsh >= tcsh >> csh > ksh ぐらい違う
それ以外のマイナーなShellは、自分の中に存在しません
>>529
bash誕生が1987年、Linux誕生が1991年なんですけど、簡単にbashは入手しづらかったんでしょうか?
>>531
Linuxだと標準では入っていないけど、kshは入れるものなんでしょうか?
ビジネスでの普及度はどんな感じなんですか?
対話シェルはbashとか、他のなにかでshスクリプトの実行はkshって感じなんでしょうか?
それともshに対応しないkshスクリプトを書くの?
>>532
今でもひそかなファンが多いし、重宝されていると言えばいいのかな
0534名無しさん@お腹いっぱい。2009/04/20(月) 14:40:33
>>533
>それともshに対応しないkshスクリプトを書くの?

普通書かない。
shに対応しないkshスクリプトの代表例と言えば [[ ]] の記述。

sh的には if [ "$hoge" = fuga ]; then と書くところを、
kshでは if [[ "$hoge" == fuga ]]; then と書く。

でも、こんなの滅多に見ないだろ。それほど kshはマイナー。
0535名無しさん@お腹いっぱい。2009/04/20(月) 15:02:26
>>533
Linuxには入れちゃうよーん
0536名無しさん@お腹いっぱい。2009/04/20(月) 15:27:09
客先とかだと勝手に入れられない。
0537名無しさん@お腹いっぱい。2009/04/20(月) 16:31:48
もちろん設計段階で盛り込むんだよーん
0538名無しさん@お腹いっぱい。2009/04/20(月) 16:35:48
自分が一生面倒見ますくらいじゃないとそんなの入れられない
特に自社システムじゃなく受託開発なら
トラブル時に責任問題にもなる
0539名無しさん@お腹いっぱい。2009/04/20(月) 16:39:40
なんか、どうでもいい話だな。
0540名無しさん@お腹いっぱい。2009/04/20(月) 16:41:47
サポートのあるものを入れれば大丈夫だよん
0541名無しさん@お腹いっぱい。2009/04/20(月) 16:43:27
>>540
具体的には?
0542名無しさん@お腹いっぱい。2009/04/20(月) 16:57:46
redhatとかsuseとか
それぞれのベンダが提供しているやつ
0543名無しさん@お腹いっぱい。2009/04/20(月) 17:08:15
OpenBSDのkshはpdkshじゃなかったっけ?
0544名無しさん@お腹いっぱい。2009/04/20(月) 17:21:19
たいていpbksh
0545名無しさん@お腹いっぱい。2009/04/20(月) 21:06:27
$ ksh
プログラム 'ksh' は以下のパッケージで見つかりました:
* ksh
* mksh
* zsh
* pdksh
次の操作を試してください: sudo apt-get install <選択したパッケージ>

やはりここはpdksh?
0546名無しさん@お腹いっぱい。2009/04/20(月) 21:46:52
OSが起動した日時を取得する、いい方法は無いでしょうか?
起動からの経過時間でなく、起動日時です。
出来ればシリアル値(1970からの経過秒)で取得できれば嬉しいです。

uptimeの結果から計算するのは起動からの経過時間によってフォーマットが
(daysやminが付いたり、付かなかったり)違うため出来れば避けたいです。
GNU、bash依存でもかまいません。
0547名無しさん@お腹いっぱい。2009/04/20(月) 21:52:23
cat /proc/uptime
0548名無しさん@お腹いっぱい。2009/04/20(月) 21:56:22
cat: /proc/uptime: No such file or directory
0549名無しさん@お腹いっぱい。2009/04/20(月) 21:58:37
だからBSD*は駄目なんだよ
0550名無しさん@お腹いっぱい。2009/04/20(月) 22:14:36
>>546
GNU 依存でいいなら、

date -r /

(ルートディレクトリのタイムスタンプは起動時に touchされて
その後書き込みは普通は発生しないことを利用)
0551名無しさん@お腹いっぱい。2009/04/20(月) 22:18:32
$ date -r /
2009年  2月  6日 金曜日 21:12:47 JST

ずれまくりワロタ
0552名無しさん@お腹いっぱい。2009/04/20(月) 22:24:36
>>545
好きにすればいいじゃない
0553名無しさん@お腹いっぱい。2009/04/20(月) 22:31:52
>>550
OpenBSD on VMware on WindowsXPでやったら、Thu Jan 1 09:00:00 JST 1970になった
まあ、OpenBSD on VMwareだからしゃないやな
05545532009/04/20(月) 22:46:48
ubuntu8.04 LTS on VMwareだとVM作成時の年数日時
Scientific on VMware,Fedora11 on VMwareだとちゃんと出るんだな

まあ、どうでもいい話でした
05555012009/04/21(火) 00:03:03
>>508の質問の件ですが、御陰様で無事に動きますた。

ただしおいらの環境だと、>>511さんのプログラムのままでは
 2009/04/19 01:23:45,user,ip=[192.168.1.2]
のような結果になってしまうので、whileのダミー引数を増やしました。

最終的にこんな感じにしますた。
(※全角スペースでインデントしています)

----
#!/usr/local/bin/ksh

YEAR=`date +'%Y'`
while IFS=' =,[]' read mon day time d1 d2 d3 d4 d5 d6 d7 d8 user d9 d10 ip d11
do
  case $mon in
    Jan)mon=01;; Feb)mon=02;; Mar)mon=03;; Apr)mon=04;;
    May)mon=05;; Jun)mon=06;; Jul)mon=07;; Aug)mon=08;;
    Sep)mon=09;; Oct)mon=10;; Nov)mon=11;; Dec)mon=12;;
  esac
  echo $YEAR/$mon/$day $time,$user,$ip
done
----
05565012009/04/21(火) 00:07:41
続きです。

スクリプトの実行速度なんですが、約10万行のログを処理したところ、
kshではなんと4秒で終わっちゃいました。

ちなみに/bin/shで動かしたら、27秒もかかっちゃいまして、
処理性能の違いに驚いた次第であります。
おまいら、ありがとうございますた。
0557名無しさん@お腹いっぱい。2009/04/21(火) 01:03:04
>>556
ちなみにOSは?
0558名無しさん@お腹いっぱい。2009/04/21(火) 01:13:39
>>555
報告おつ
比較をわかりやすく、30万行じゃないのねw

6.75倍はすごいね
05595012009/04/21(火) 01:26:31
>>557
処理時間を計ったのはVMware上で動いているFreeBSD7.1ですが、
Solaris9(SPARC)でも動くのは確認しますた。


>>558
手元にあったのが10万行のログだったので、
とりあえずこれで試しますた。
深い意味はありませんw
0560名無しさん@お腹いっぱい。2009/04/21(火) 01:31:08
>>546
こんなのどうかな。
GNU依存だし、動かないパターン多そうだけど。

$ last | grep '^reboot' | head -1 | awk '{print $5" "$6" "$7" "$8}' | date -f - '+%s'
0561名無しさん@お腹いっぱい。2009/04/21(火) 01:40:08
今月起動したっていう場合しか無理っぽいな
0562名無しさん@お腹いっぱい。2009/04/21(火) 01:50:16
>>561
wtmp って1月分しか残らないんだっけ?
そう言えば、/proc/uptime はサイズどれだけ有るんだっけ(溢れることはない?)?
0563名無しさん@お腹いっぱい。2009/04/21(火) 03:07:54
bashで、三項演算子を使いたいのですが、どのようにするのでしょうか?
0564名無しさん@お腹いっぱい。2009/04/21(火) 03:55:34
shellはダイナミックライブラリのとスタティックのが有るから、ベンチ遣るならダイナミックのほうが有利だろうな。
0565名無しさん@お腹いっぱい。2009/04/21(火) 07:16:33
>>563
たとえば、
echo $((x > 0 ? x: -x))
とか。
0566名無しさん@お腹いっぱい。2009/04/21(火) 07:38:41
俺の解釈では
A && (B; true) || C
かと。
0567名無しさん@お腹いっぱい。2009/04/21(火) 08:20:54
>>566
アフォか。
それは普通の「2項」の演算子の組み合わせ。
しかも、bash限定でもない。

>>565 が正解。
0568名無しさん@お腹いっぱい。2009/04/21(火) 09:59:52
正解は>>565
>>567は>566に輪をかけたアフォ。
「bashで」というお題は「bash以外では動作しない == bash限定」事を要求していない。
0569名無しさん@お腹いっぱい。2009/04/21(火) 10:53:47
頭のおかしい人はスルーで
はりきるだけだから
0570名無しさん@お腹いっぱい。2009/04/21(火) 11:12:24
するーされてるが >>564 もあふぉだな。
ここでのベンチ(kshとbash)は、ライブラリが動的か静的かよりもはるかに大きい
差を生じているので、そんな点を指摘しても無意味。
さらにアフォな点は、バイナリは「スタティックリンク」の方が速い(有利)ということ。
>>564 は全く逆に覚えてるようだね。
0571名無しさん@お腹いっぱい。2009/04/21(火) 12:34:23
なんでスタティックリンクの方が速いんだ?
0572名無しさん@お腹いっぱい。2009/04/21(火) 12:40:45
>>571
素で質問してるならぐぐれ。
釣りなら面白くない。
0573名無しさん@お腹いっぱい。2009/04/21(火) 13:33:19
ファイル名を通し番号に変えたいんですけど
以下のスクリプトでエラーが出ます。

num=1

for file in *.m4a; do

mv $file $num.m4r

num=`expr $num + 1`

done


エラーは
mv: target `1.m4r' is not a directory
というものです。

シェルというよりmvコマンドの使い方の問題なのかもしれませんが
自分には原因がわかりません
教えてください
0574名無しさん@お腹いっぱい。2009/04/21(火) 13:42:53
>>571
共有ライブラリは間接呼出しになる。
0575名無しさん@お腹いっぱい。2009/04/21(火) 13:44:59
>>573
スペース入りファイル名が分割されて、
mv hoge hage.m4a 123.m4r
みたいに実行されたのが原因。

シェル変数の展開時には原則すべてダブルクォートを付けること。

mv "$file" "$num.m4r"
0576名無しさん@お腹いっぱい。2009/04/21(火) 13:45:06
>>573
ファイル名に空白(やタブ等)が含まれているのだろう。

mv "$file" $num.m4r
0577名無しさん@お腹いっぱい。2009/04/21(火) 14:04:48
>>575
>>576
なるほど、そういうことだったんですか!
まさにその通りで、ファイル名にスペースが入っていました。
ありがとうございます!
0578名無しさん@お腹いっぱい。2009/04/21(火) 21:57:17
>>546
すごく適当ですが・・・・こんな感じで OS ごとに書くしかないかと。

case `uname -s` in
'Linux')
  grep btime /proc/stat | cut -d ' ' -f 2
  ;;
'FreeBSD')
  cut -d ' ' -f 8 /proc/1/status | cut -d ',' -f 1
  ;;
*)
  ;;
esac
0579名無しさん@お腹いっぱい。2009/04/22(水) 05:32:25
スタティクは全部読むから読み込みに時間がかかるし、ライブラリのキャッシュも効いてないぞ。
ダイナミックが遅いなら、みんなダイナミック使ってないwww
perlとかも普通はダイナミック。
0580名無しさん@お腹いっぱい。2009/04/22(水) 06:10:01
>>579
オマエ真性の勘違い野郎か。

スタティックリンクでも全部は読み込まない。
仮想記憶って知ってるか?
バイナリプログラムのうち、実際にCPUのプログラムカウンタが走った命令のアドレス
を含むメモリページのみが読み込まれる。実行されなかった部分は読み込まれない。

ダイナミックリンクのライブラリは、リロケーションの関係で、
PIC(ポジションインディペンデント)にコンパイルする必要があり、
PIC自体が通常のバイナリよりも数%遅い。

ライブラリのキャッシュについては確かにいうとおりだが、
これは他の要素に比べて影響は小さいので、
やはりダイナミックリンクの方が遅い。

ダイナミックリンクは遅いが、HDDの節約や、ライブラリのupdateの際に
リンクしてる個々のバイナリを再コンパイルしなくて良い便宜のために
使用されている。どうしても速度優先の場合は、
スタティックリンクを使うことがあるよ。
0581名無しさん@お腹いっぱい。2009/04/22(水) 06:36:28
>>580 に補足。
ライブラリは複数の関数の集まりでできているが、
スタティックリンクの場合、それらの関数のうち、使用している関数だけが
コンパイル(ld)時にリンクされる。使っていない関数はそもそもリンクされない。
(使っていても条件によって呼び出されなかった関数は
仮想記憶によってメモリにはロードされないままになる可能性があるのは
>>580 がいう通り)

ダイナミックリンクの場合は、使っていない関数まで
実行時に塊で付いてきてしまう。
0582名無しさん@お腹いっぱい。2009/04/22(水) 06:57:20
ダイナミックリンク/スタティックリンクの速度の違いなんて小さいからどうでもいい。
それよりもバイトコンパイルやらコマンド組み込みやらの方が効果でかいはず。
0583名無しさん@お腹いっぱい。2009/04/22(水) 07:57:48
>>579
間違った知識ばらまいてないで、実験してみればいいのに。

$ cat hoge.c
#include <stdio.h>
int main(){printf("Hello¥n");return 0;}

$ gcc -o dynamic hoge.c
$ gcc -o static hoge.c -static

$ time ./dynamic
Hello

real 0m0.004s
user 0m0.000s
sys 0m0.001s

$ time ./static
Hello

real 0m0.002s
user 0m0.000s
sys 0m0.000s


スタティックリンクの方が速いね。
0584名無しさん@お腹いっぱい。2009/04/22(水) 09:15:01
>>563
ミリ秒オーダでしか違わないんじゃほとんどの場合は
そんなこと気にするよりまともなプログラム書いたほうが
いいなw
0585名無しさん@お腹いっぱい。2009/04/22(水) 09:37:11
>>584
dynamicもstaticも「ほとんど違わない」ので、それ以外の要素による違いの方が大きい
ということは元々 >>570 が指摘してる。(こっちが要点)

それ以外に、>>564 は「ダイナミックの方が速い」と間違ってることを言ってるるので、
それをついでに指摘しただけ。

で、>>579 で未だに「ダイナミックの方が速い」の主張を続けるから、
>>580 がそれを否定しているだけ。

別に>>580 が、シェルスクリプトのシェルをスタティックにしろと主張している
わけではない。

元の質問に戻って、>>508 の場合、外部コマンドの cutの呼び出しが多数ループ
されるので、それが遅かったのが原因と思われる。
>>511 はシェルの内部コマンドだけを使っているので、それで激劇に速くなったと。

いすれにしても、その話の流れを読まずに
>>564 で見当違いかつ間違った指摘をしている >>564 はアフォ。
0586名無しさん@お腹いっぱい。2009/04/22(水) 10:22:55
>>580
> ライブラリのキャッシュについては確かにいうとおりだが、
> これは他の要素に比べて影響は小さいので、
> やはりダイナミックリンクの方が遅い。

嘘八百のおバカさん
0587名無しさん@お腹いっぱい。2009/04/22(水) 10:31:05
>>585
主張する内容自体に問題くても、必死すぎるとキモいものだな...
まあ落ち着け。
■ このスレッドは過去ログ倉庫に格納されています