シェルスクリプト総合 その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 でトレースしましょう。
前スレ落ちたみたいなのでリンク省略。
0588名無しさん@お腹いっぱい。
2009/04/22(水) 10:35:53>>579 は perlの「ダイナミックロード」のライブラリ(モジュール)の話と
混同してるフシがあるな。(わざわざ的外れなperlを例に持ち出してきてるあたり)
>>579 にとって、「ダイナミック」とは、perlでしかイメージできてなくて、
普通にCをコンパイルする時のstatic linkとdynamic linkを違いを
全く理解できてない(存在自体知らない?)んだろう(笑)
0589名無しさん@お腹いっぱい。
2009/04/22(水) 10:49:32問題です。
Ubuntuでは、dashをビルドする際に、libcを使わずdietlibcに変更した上で、
スタティックリンクしています。これはなぜでしょうか。
ヒント:Ubuntuでは/bin/shとしてdashを使っています。
0590名無しさん@お腹いっぱい。
2009/04/22(水) 11:07:22スタティックリンクの方が速いからではない。
そもそも速くないし。
0591名無しさん@お腹いっぱい。
2009/04/22(水) 11:11:36>そもそも速くないし。
↑
は間違い。実際速い。
それ以外にstatic linkにする利点と、さらにdietlibcに変更する理由を質問してる。
>>590 では答えになっていない。
ハイ、答え直し >>590 >>584
↓
0592名無しさん@お腹いっぱい。
2009/04/22(水) 11:12:45ちゃんと自分の頭を使って自分の体を動かして自分の目で確認しろよ。
0593名無しさん@お腹いっぱい。
2009/04/22(水) 11:31:22NSS まわりとかで必要があれば勝手にダイナミックでリンクしちゃうから
わりとどーでもいい。
0594名無しさん@お腹いっぱい。
2009/04/22(水) 11:47:34争点をぼかすことになるから、ここでは dlopen()系の話は持ち込まない方が
話が簡単になるかと。どうせあほは >>579 1人だろうし。
0595名無しさん@お腹いっぱい。
2009/04/22(水) 12:33:36しかもdietlibcはLGPLでなくGPLなのでダイナミックリンクでも汚染する。
0596名無しさん@お腹いっぱい。
2009/04/22(水) 12:35:04すさまじい勘違いだなw
0597名無しさん@お腹いっぱい。
2009/04/22(水) 12:38:47このオーダーも特に速度が必要な場合は馬鹿に出来ないよ。
まぁ、dynamicかstaticかの違いより、根本的な設計の方がよっぽど大きいけど。
0598名無しさん@お腹いっぱい。
2009/04/22(水) 12:49:51ミリ秒オーダーの起動オーバヘッドが問題になるほど実行時間の
短いプログラムを何度も起動するのはそもそも設計が悪いよね
0599名無しさん@お腹いっぱい。
2009/04/22(水) 12:59:45オーバヘッドは「プログラム起動時」だけじゃないよ。
dynamicなライブラリ上の関数を呼び出すたびにオーバーヘッドがかかる。
さらに、関数自体がPICによって速度上不利なコードで書かれているから遅くなる。
staticライブラリなら、プログラム中に絶対アドレスを決めうちで持つから、
その分のオーバーヘッドがなく高速動作する。
0600名無しさん@お腹いっぱい。
2009/04/22(水) 13:10:18結論ありきというか
そうでないと世界が崩壊しちゃうんだろうね
0601名無しさん@お腹いっぱい。
2009/04/22(水) 13:18:31今まで「ダイナミックリンクの方が速い」と間違って覚えていて
散々恥を晒した気分はどうだい? >>600 = >>579
0602名無しさん@お腹いっぱい。
2009/04/22(水) 13:22:13自己紹介乙。
そうか、今までdynamicの方が速いと信じこんでいて、それが間違いだと知って
キミの世界が崩壊しちゃったのか、、よしよし
0603名無しさん@お腹いっぱい。
2009/04/22(水) 13:50:410604名無しさん@お腹いっぱい。
2009/04/22(水) 17:24:320605名無しさん@お腹いっぱい。
2009/04/22(水) 23:37:030606名無しさん@お腹いっぱい。
2009/04/22(水) 23:52:09ま、次から間違えないようにすれば良いじゃないか。
0607名無しさん@お腹いっぱい。
2009/04/23(木) 22:37:10という場合のsedをひとつにできますか?
0608名無しさん@お腹いっぱい。
2009/04/23(木) 22:43:22echo aaabbbccceee | sed 's/aaa//;s/ccc//'
0609名無しさん@お腹いっぱい。
2009/04/23(木) 22:55:44$ alias ひとつ=sed
$ echo aaabbbccceee | ひとつ 's/aaa//' | ひとつ 's/ccc//'
0610名無しさん@お腹いっぱい。
2009/04/23(木) 23:29:400611名無しさん@お腹いっぱい。
2009/04/24(金) 00:10:17個人的には、見やすさも考えてこんな風に書くこと多いかな。
sed -e 's/afo/moe/g' \
-e 's/unko/umai/g' \
-e 's/ahya/uhyo/g'
あと、文字列に / がいっぱい入るときは \/ じゃなくって、そもそも / を使わない。
s|/afo/desu/yo|/unko/tabe/tai/ne|
0612名無しさん@お腹いっぱい。
2009/04/24(金) 00:41:350613名無しさん@お腹いっぱい。
2009/04/24(金) 06:46:280614名無しさん@お腹いっぱい。
2009/04/24(金) 09:27:04カーソル戻さなくていい分楽なのでついやっちゃうんだよな...
0615名無しさん@お腹いっぱい。
2009/04/24(金) 11:10:54実行速度が大きく違う時がある
-e よりは sed | sed | sedの方が速いときもある
ケースバイケースでしょ
0616名無しさん@お腹いっぱい。
2009/04/24(金) 11:47:58インターネットで俺の悪口を言うのは止めてくれないか ><
0617名無しさん@お腹いっぱい。
2009/04/24(金) 12:46:500618名無しさん@お腹いっぱい。
2009/04/24(金) 19:58:34ただひとつの場合-eはなくてもいいのに複数の場合は必須なんですね?
0619名無しさん@お腹いっぱい。
2009/04/24(金) 20:08:32>>608 の形式なら -e は不要。
0620名無しさん@お腹いっぱい。
2009/04/24(金) 23:03:440621名無しさん@お腹いっぱい。
2009/04/25(土) 04:52:340622名無しさん@お腹いっぱい。
2009/04/25(土) 09:27:360623名無しさん@お腹いっぱい。
2009/04/25(土) 09:49:23sed 's/afo/moe/g;s/unko/umai/g;s/ahya/uhyo/g'
よりも、
sed | sed | sed の方が速いことはあり得ない。
×ケースバイケース
○ >>615 の負け惜しみ
0624名無しさん@お腹いっぱい。
2009/04/25(土) 10:29:360625名無しさん@お腹いっぱい。
2009/04/25(土) 12:07:39>>615 は一言で言い表すために -e って言っただけだろ。
-e でも>>623 でも同じこと。
まとめると、
>>611 (-e) または >>623 の方が速い。
間違っても、>>615 が言う sed | sed | sed の方が速くなるケースは無い。
0626名無しさん@お腹いっぱい。
2009/04/25(土) 16:57:49まあsed実行中もshellが居座ってるのもなんだかなあだけど。
0627名無しさん@お腹いっぱい。
2009/04/25(土) 17:41:53そのshell分、ちょっぴりメモリを食うだけでしょ
他になんかデメリットってあるんでしょうか?
0628名無しさん@お腹いっぱい。
2009/04/25(土) 18:30:210629名無しさん@お腹いっぱい。
2009/04/25(土) 18:32:170630名無しさん@お腹いっぱい。
2009/04/25(土) 18:46:52exec command
とやって、forkせずにシェルをコマンドに化けさせられる。
2つ以上のコマンドをパイプする場合は、execが使えない。
敢えて exec を付けても無意味。実験してみればわかる。
0631名無しさん@お腹いっぱい。
2009/04/25(土) 22:25:150632名無しさん@お腹いっぱい。
2009/04/26(日) 01:12:310633名無しさん@お腹いっぱい。
2009/04/26(日) 01:20:050634名無しさん@お腹いっぱい。
2009/04/26(日) 02:03:58そりゃFortran・COBOL・Lispが未だに現役なわけだし。
0635名無しさん@お腹いっぱい。
2009/04/26(日) 05:23:42今時オンデマンドでリアルタイムで処理しろよって感じだが。
0636名無しさん@お腹いっぱい。
2009/04/26(日) 06:47:10まぁ世の中、夜間のバッチ処理に向いてる(リアルタイムに向かない)
処理もある訳で、ホストもバッチ処理もそう簡単には無くならんでしょうな。
0637名無しさん@お腹いっぱい。
2009/04/26(日) 22:31:52bash 3.5, ksh 3.5, zsh 2, csh(tcsh) 1って感じだった
他のマイナーなShellは出てこず
kshの良い点としてvi-likeの編集機能を何名かがあげていたんですけど、そんなに便利なんでしょうか?
0638名無しさん@お腹いっぱい。
2009/04/26(日) 22:47:320639名無しさん@お腹いっぱい。
2009/04/27(月) 02:51:03vi `locate filename.sh`
クドイほどtips and 例文満載の文書ってないのかな
0640名無しさん@お腹いっぱい。
2009/04/27(月) 04:44:20弱い犬ほど良く吠えるから
発言が活発=利用者が多い
じゃないよ
cshやbash以外は普及してるかと言われればそうでもない
0641名無しさん@お腹いっぱい。
2009/04/27(月) 06:35:18/bin/shの実体が何かによって利用者の数は決まる気がする。
0642名無しさん@お腹いっぱい。
2009/04/27(月) 09:32:46vi +/PATTERN `egrep -l PATTERN *`
ってのは良くやるからシェルスクリプトにしてる。
0643名無しさん@お腹いっぱい。
2009/04/27(月) 23:29:030644名無しさん@お腹いっぱい。
2009/04/28(火) 00:07:22結局公開されたkshにはその機能がなくて一度も見ることなく終わったのだが、
どんなもんだったか証言できる人はいますか?
これが使えていたらTcl/Tkとかたぶんやってなかった。
0645名無しさん@お腹いっぱい。
2009/04/28(火) 01:11:38DeskTop Korn SHellな。
http://www.brendangregg.com/DtkshDemos/xpong
0646名無しさん@お腹いっぱい。
2009/04/28(火) 10:24:050647名無しさん@お腹いっぱい。
2009/04/28(火) 15:36:56トン。dtkshだったのか。いままで検索しても画面を拝めなかったので
もう見ることはないかと思ってたよ。おかげで
http://docs.sun.com/app/docs/doc/805-3917/6j3niaoaf?l=Ja&a=view
のプログラミングマニュアルでコードとか動作を初めて拝めた。
Solarisは使ってるけど/usr/dtとかまず使わないからまったく知らなかった。
もしかしてOpenSolarisにも入っているのだろうか・・・
Xツールキットの関数とオプションのまんまラッパーだったんだな。
今見るとベタで微笑ましい位。さすがにスクリプトででもXtは使いたいとは
もう思えないが、当時使えていたらハマッただろうなぁ。
0648名無しさん@お腹いっぱい。
2009/04/28(火) 18:39:57/tmp/old まであるディレクトリ構造で
単純に/tmpディレクトリにあるファイルリストをテキストで出したいのだけど
ディレクトリや隠しファイルの表示は入れたくない
どんなコマンドつかえばできる?
lsやfindでいろんなオプションつけてやってみたけど無理だった
たぶんすごく単純なところで引っ掛かってる気がするので、わかる方いたら教えてください
0649名無しさん@お腹いっぱい。
2009/04/28(火) 19:27:000650名無しさん@お腹いっぱい。
2009/04/28(火) 19:29:16隠しファイルの表示は入れたくない
0651名無しさん@お腹いっぱい。
2009/04/28(火) 19:30:52cd /tmp; for file in *; do [ -f "$file" ] && echo "$file"; done
0652名無しさん@お腹いっぱい。
2009/04/28(火) 19:38:57くだ質スレでほぼ解決してるからここ見に来るとは思わんけど。
0653名無しさん@お腹いっぱい。
2009/04/28(火) 19:42:22find内で.*を排除するのは無駄だろ。
せっかく内部コマンドだけでできるのに。
0654名無しさん@お腹いっぱい。
2009/04/28(火) 19:44:13あっちでやってるのは、find「内」じゃないだろ。
findの「外」のパイプに出してからあとからカットしてる。ノンエレガント。
0655名無しさん@お腹いっぱい。
2009/04/28(火) 19:47:52よりも、
シェル内部コマンドのみ
の方が速いわな。
0656名無しさん@お腹いっぱい。
2009/04/28(火) 19:49:47find方式だと、「hoge<改行>.hoge」みたいなファイル名があった場合、誤動作する。
>>651 方式なら無問題。
0657名無しさん@お腹いっぱい。
2009/04/28(火) 20:17:44外部コマンドなシェルだとパフォーマンス最悪
0658名無しさん@お腹いっぱい。
2009/04/28(火) 20:39:130659名無しさん@お腹いっぱい。
2009/04/28(火) 21:12:44$ touch foo\\bar
$ for file in *; do [ -f "$file" ] && echo "$file"; done
foar
0660名無しさん@お腹いっぱい。
2009/04/28(火) 21:12:510661名無しさん@お腹いっぱい。
2009/04/28(火) 21:14:33for f in *; do [ -f "$f" ] && printf '%s¥n' "$f"; done
0662名無しさん@お腹いっぱい。
2009/04/28(火) 21:30:00v7sh
echoも外出し。
0663名無しさん@お腹いっぱい。
2009/04/28(火) 21:33:48FreeBSD tcsh
% which [
/bin/[
0664名無しさん@お腹いっぱい。
2009/04/28(火) 21:48:08>>661 で for文使ってるのが見えねぇのかよw
>>662
v7は「現存」しない。
0665名無しさん@お腹いっぱい。
2009/04/28(火) 21:51:340666名無しさん@お腹いっぱい。
2009/04/28(火) 21:55:13やっぱり「現存」しないじゃん。
わざわざ作らなきゃいけないんだから。
0667名無しさん@お腹いっぱい。
2009/04/28(火) 21:57:57「testやechoが外部コマンドの場合もある」って主張してる人、
実際そんな古いシェルを「ログインシェル」または「スクリプトシェル」として
現役で使ってるの?
使ってないのに机上の空論してもしょうがないよ。
0668名無しさん@お腹いっぱい。
2009/04/28(火) 22:02:390669名無しさん@お腹いっぱい。
2009/04/28(火) 22:08:53for f in *; do (cd "$f") 2> /dev/null || echo "$f"; done
Permission deniedなディレクトリがあったら誤判定されるのは仕方ない。
0670名無しさん@お腹いっぱい。
2009/04/28(火) 22:14:47> 誤判定されるのは仕方ない。
> 誤判定されるのは仕方ない。
> 誤判定されるのは仕方ない。
0671名無しさん@お腹いっぱい。
2009/04/28(火) 22:16:41v7sh
cdも外出し。
0672名無しさん@お腹いっぱい。
2009/04/28(火) 22:29:15誤判定されない方法を考えてみた。
for f in *;do case `(cd "$f") 2>&1` in *'Not a directory')echo "$f";;esac; done
0673名無しさん@お腹いっぱい。
2009/04/28(火) 22:56:37> もしかしてOpenSolarisにも入っているのだろうか・・・
入ってない。TODOリストに入っているが、
ライセンス関係で新たに作らないといけない。
CDE/Motifべったりだから誰もやらないだろう。
>>666
わざわざエミュレータで動かしてます。
「現存」してないです。とあなたは言うでしょうけど。
0674名無しさん@お腹いっぱい。
2009/04/29(水) 01:06:420675名無しさん@お腹いっぱい。
2009/04/29(水) 02:37:45美しくないな。
なんてこと言う奴はrcを使えってことか
0676名無しさん@お腹いっぱい。
2009/04/29(水) 05:58:40> v7は「現存」しない。
うちでは fpga で作った pdp-11 互換 CPU 上で元気に動いてますけど
0677名無しさん@お腹いっぱい。
2009/04/29(水) 05:59:43寝言は寝てから言ってね
0678名無しさん@お腹いっぱい。
2009/04/29(水) 06:49:51それを「現存しない」と言う。よく覚えとけ。
0679名無しさん@お腹いっぱい。
2009/04/29(水) 06:55:31/usr/bin/cd コマンドが存在するし。
多分、親プロセスを chdir()するようなシステムコール? を呼んでる??
0680名無しさん@お腹いっぱい。
2009/04/29(水) 08:08:58それたしか、自分がcdするだけ、ってnopコマンドじゃなかった?
0681名無しさん@お腹いっぱい。
2009/04/29(水) 08:30:530682名無しさん@お腹いっぱい。
2009/04/29(水) 08:59:20/usr/bin/cd fooとやると変わらないだろ。
/usr/bin/cd foo && cd fooでフェイルセイフなcdだ。
0683名無しさん@お腹いっぱい。
2009/04/29(水) 09:09:49> /usr/bin/cd foo && cd fooでフェイルセイフなcdだ。
それ、フェイルな場合 /usr/bin/cd の段階でフェイルして、
エラーメッセージも出てしまうから、ちっともフェイルセーフじゃない。
単に cd foo とやったのと何ら変わりない。
0684名無しさん@お腹いっぱい。
2009/04/29(水) 09:28:49> 多分、親プロセスを chdir()するようなシステムコール? を呼んでる??
そんなシステムコールあるわけねーだろw
0685名無しさん@お腹いっぱい。
2009/04/29(水) 09:39:00子プロセスとカレントディレクトリを共有する仕様にしようと思ってる。
cdを外付けコマンドにしたシェルを実装するんだ。
0686名無しさん@お腹いっぱい。
2009/04/29(水) 09:40:040687名無しさん@お腹いっぱい。
2009/04/29(水) 09:43:41■ このスレッドは過去ログ倉庫に格納されています