[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 2chのread.cgiへ]
Update time : 05/09 11:27 / Filesize : 228 KB / Number-of Response : 986
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

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



1 名前:名無しさん@お腹いっぱい。 [2007/02/15(木) 14:28:44 ]
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>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 でトレースしましょう。

前スレ
シェルスクリプト総合 その7
pc10.2ch.net/test/read.cgi/unix/1157601611/


81 名前:名無し募集中。。。 mailto:sage [2007/02/19(月) 06:55:03 ]
>>80
環境によっては使えないかもね
manでもネットでも調べれば?



82 名前:64 mailto:sage [2007/02/19(月) 07:03:11 ]
>>52
あ、find -print0 と IFS を弄って while を組合わせたいって意味なら駄目だよ
>>68さんの言ってる方法で

それより -print0 オプションが使えない環境もあるから
まずはそっちを調べた方がいいよ

83 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/19(月) 07:57:15 ]
>>79
findコマンド自体では IFSは当然関係ないが、
findの結果を ` ` で取り込んで forの引数にする際に
IFSが参照される。(IFSの影響を受ける)
なので、スペース入りファイル名の問題なら、
IFSの内容を改行コードのみにして for f in `find ...` を実行すればOK
なことは既に上に書かれている。

84 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/19(月) 17:57:07 ]
>>68
ちなみに NULL じゃなくて NUL ですね。

85 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/19(月) 22:58:23 ]
>>84
頭ではわかっているが、指が憶えてしまっているのでしょうがない。

86 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/20(火) 02:12:08 ]
>>79
man awk の文字列関数の項を参照してみな。
もしかしたら gawk だけかもしれないけど。

87 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/20(火) 10:40:49 ]
gawk 3.0 以上の拡張機能でございます。

88 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/20(火) 11:31:38 ]
大嘘つき

89 名前:64 mailto:sage [2007/02/20(火) 17:58:58 ]
いつから正規表現板に?あと自分の環境が全ての人しか居ないの?
素のAIXじゃ、grep '\(a\)\1' はできたが egrep, grep -E は無理みたい
拡張正規表現だと \1 は使えなさそうあとawkも

gawk は知らんけどgawkは無い環境も多いからawkとgawkを一緒にするな
awkと言えば昔ながらの素のawkのことだよ
linuxでshを語るアホウ(そりゃashだ)と同じやね




90 名前:64 mailto:sage [2007/02/20(火) 19:15:33 ]
最後だけ削除
shについては、Cygwinもash、今時の素のAIX、HP-UXなら実はkshだったりするから
Solaris、FreeBSDは知らんけど例としてはかなり不適切やね、無視してくれ

91 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/20(火) 21:12:01 ]
kshはねーよ。デフォルトでは使いにくい。

set -o emacs
set -o vi

どっち?

92 名前:osuga [2007/02/20(火) 22:49:15 ]
>>90
HP-UXのデフォルトがkshかよ

93 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/20(火) 22:58:23 ]
>>64は面白いな

94 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/20(火) 23:48:35 ]
>>89
> 素のAIXじゃ、grep '\(a\)\1' はできた
参考までに grep のバージョン教えてくれ。

>>90
> Cygwinもash
それいつの話?
手元の環境だと ash は入れてあるけど、sh の実体は bash になってるよ?

$ uname -r
1.5.24(0.156/4/2)

$ /bin/sh --version
GNU bash, version 3.2.9(11)-release (i686-pc-cygwin)
Copyright (C) 2005 Free Software Foundation, Inc.

95 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 02:37:28 ]
>>89
POSIX的には拡張正規表現(ERE))でbackrefernceが使えるということは
一言も書いていないので、grep -E でbackrefernceが使えるGNU grep
なんかが拡張しているということなんだろう。多分。



96 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 04:14:13 ]
それにしてもネタないね
叩きはすぐ集まってくるけど

grep '\(a\)\1' は実際できるし(AIX5.3、SFU)、基本正規表現(BRE)にあるんで
linuxやHP-UXのgrepでも出来た記憶がある、まぁ昔の事なんで自信はない

拡張正規表現(ERE)にはBREの\( \)にあたるものが無いようで
>>95はフォローしてくれたんだろうけど
実際にやってみたが egrep, grep -E じゃできなさそう(AIX5.3)と既に書いている

HP-UXのshについては昔、といっても11iなんだが
純粋なshでは使えないはずの [[ ]] や alias なんかが使えたんで調べたら
sh-posix とか書かれていて、sh->kshで拡張されたものがほぼ?まんま拡張されてた

なんでHP-UXのshはksh、って位の認識だったんだが
POSIX の sh いうんやから [[ ]] や alias が使えるのが今時の純粋な sh ということかもしれんね


97 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 09:12:36 ]
おまえら >>1 読め
正規表現については以降はこちらへ

正規表現
pc10.2ch.net/test/read.cgi/unix/1039165754/

98 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 10:35:28 ]
sh-posix ってのがあるんですよ奥さん

99 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 10:37:51 ]
>>98
だから、sh-posixの部分だけ書けばいい。
正規表現の部分はスレ違い。



100 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 10:57:54 ]
本当にそういうものはあるのかな?

solaris においては /bin/sh は sh-posixではなく
/usr/xpg4/bin/sh が ごにょごにょ
FreeBSD では /bin/sh は IEEE Std 1003.2 (``POSIX.2'') に対応する途上
NetBSD では /bin/sh は  POSIX 1003.2 and 1003.2a に対応する途上
OpenBSDでは (ry
HP-UX では

101 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 10:59:10 ]
あ、きみ宛というよりは>>96宛てかな?

102 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 12:16:07 ]
docs.hp.com/ja/B2355-60104-02/sh-posix.1.html
でも嫁
現在のHP-UXの/bin/shはsh-posixであって、古いbourne shellは存在しない
sh-posixはkshによく似ているが別物

>>90は間違いだらけ

103 名前:95 mailto:sage [2007/02/21(水) 12:40:01 ]
>>96
すまん。寝る直前に書いたせいか
フォローのつもりがわけのわからんものになってた。

GNU のツールでそうだからといって、
それがUNIX全般でいえるかというと違うよね。
というのを補足したかった(awkとgawkとか)



104 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 13:49:30 ]
>>102
以前は /usr/old/bin/sh に Bourne shell があったんだけど今はもうないの?
手元に実機がないので確認できない。

105 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 14:03:34 ]
>>104
実機がなくても参照できちゃうんだなこれが
docs.hp.com/ja/B2355-60104-02/sh.1.html
-
注記 : B シェル (/usr/old/bin/sh) は、HP-UX 11i Version 1.5 以降、削除されました。
代りに、POSIX シェル (/usr/bin/sh) を使ってください。

-

本当に実機がこうであるかは確認していないけどね〜

106 名前:ksh [2007/02/21(水) 19:49:50 ]
こんばんわ ペソです。
シェル初心者ですが教えてください。
「ディレクトリの中にあるファイルで、実行権限のないファイルを読み込み
そのファイルに実行権限を付与するシェルが必要なのですがどうすればいいのかわかりません。
OS: AIX shell: ksh

#!/bin/ksh
for filename in ${1:+$1/}* ; do
newfilname=$(print $filename |tr [A-Z] [a-z])
newfilename=$newfilename%.}
print "$filename -> $newfilename"
mv $filename $newfilename
done

とりあえず自宅のfedora core5 のkshで実行したら、

' unexpectedtax error: `
と表示されて困ってます。

どうか教えてください。お願いします。

107 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 19:56:52 ]
>>106
質問が支離滅裂。実行権限を付けたいといっているのに、
スクリプトではファイル名の大文字を小文字にリネームしようとしている。
あと、クォートが正しくないので、スペース入りファイル名とかでコケるだろう。
釣りじゃないならもう一度よくまとめてから質問し直せ。

108 名前:ksh [2007/02/21(水) 20:43:07 ]
すいませんでした。
リネームするスクリプトを少し変更して作ろうとしているのですが、
このファイルもこけて動かないんです。




109 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 21:12:05 ]
>>106
そんなの、

#!/bin/sh

chmod +x "$1"/*

だけでいいじゃん。kshである必要もなし。



110 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 21:13:56 ]
とりあえず

1. シェルスクリプトのことをシェルというな。
2. forの次の行からdoneの前の行までは全部リネーム用でいらないから削れ。
3. man test
4. man chmod


111 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 21:15:07 ]
>>109
「実行権限のないもののみを選び出す」というのが宿題の一部であると
思われるので、問答無用で+xしちゃいけないかもしれない。


112 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 21:19:54 ]
「実行権限のないもののみを選び出す」意味がない。
もともと +x なファイルを chmod +x しても影響はない。

AIXで実行しようとしてるし、だとすると
宿題じゃなく、実務で必要なんだろ。

chmod +x で十分。

(ctimeは更新されるけど、そんなの普通関係ない)

113 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 21:23:34 ]
>>110
えっと、こういうことでしょうか?

#!/bin/ksh
for filename in ${1:+$1/}* ; do
man test
man chmod
done


やってみましたが、なんか、ファイルの数だけマニュアルのようなものが表示され、
実行権限は付きませんでしたが、、

114 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 21:25:51 ]
なんだ釣りか。


115 名前:ksh [2007/02/21(水) 22:08:50 ]
kshです。

#!/bin/ksh
for filename in ${1:+$1/}* ; do
if [[ -f $filename ]] ; then
chmod +x $filename
fi
done

なんとかディレクトリの中のファイルすべてに実行権限を付与できました。
これはシェルスクリプトと言うのでしょうか?
お恥ずかしながらシェルスクリプトとはなにか?イメージが完全でなく・・・

116 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/21(水) 22:38:30 ]
>>115
> kshです。
ペソじゃなかったのかw

117 名前:ksh [2007/02/21(水) 22:53:27 ]
あっペソです!!
ルールよくわかってなくてすみませんっw

118 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/25(日) 06:28:13 ]
>>102
単に興味本位で聞くけどsh-posixとkshを比較して
実際に機能として違う部分てどんなところがあるの?


119 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/26(月) 18:34:31 ]
すごく久しぶりに man tcsh してみたのだが。

あれ、"THE T IN TCSH" なんて項目、昔あったっけ?

turbo csh じゃないじゃん > 昔俺にそう教えた奴



120 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/26(月) 18:41:12 ]
Tenex CSHの略だと思っていたが、Tenex & Tops-20だったんだな。


121 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/27(火) 00:44:41 ]
TOPS-20 ねぇ。command line editing が欲しくてcshからtcshに移ったが、
それまでは、fep 使ってました。bash は、なじめんな。

今は、zsh 派です。

122 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/27(火) 04:53:35 ]
>>118
102とは別人だけど、kshはksh88とksh93で非常に違う。
とくに後者はperlに遜色ないほどの汎用言語になっている。
kshはbashと同じくshベースということで、
bashがkshから採り入れた機能もけっこうある。ローカル変数とか

123 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/27(火) 17:22:33 ]
>>119
え?違うんだ、知らなかった

124 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/27(火) 22:13:24 ]
kshといえばwkshで一度でいいから遊んでみたかった。
もうwのないkshしかないからなぁ・・・


125 名前:名無しさん@お腹いっぱい。 [2007/02/27(火) 22:45:55 ]
viで編集中は日本語のメッセージが正しく表示されていたのですが、シェルスクリプトを実行するとメッセージが文字化けします。どうすればよいですか。

126 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/27(火) 22:49:25 ]
viが自動認識して処理してる?

nkf -e < script
nkf -j < script
nkf -s < script
nkf -w < script

で化けないパターンを探してそれに置き換える。

127 名前:名無しさん@お腹いっぱい。 [2007/02/27(火) 22:51:13 ]
>>125

その vi の実体は、賢い vi で、
シェルの ENV がついていけてないとか。

128 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/28(水) 00:25:54 ]
Cシェル、Oracle10gで
exp 〜 query\"where column_name in\( select col from tableB \) \"
みたくqueryパラメータで副照会できないようなんで
exp 〜 query\"where column_name in\( $COLUMN_NAMES \) \"
なんて具合に変数を埋め込みたい。
シェル変数が展開されてからexportに渡されるようにする方法ないかな?



129 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/28(水) 00:54:58 ]
>>126
nkf -g が無いバージョンかな?



130 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/02/28(水) 01:00:16 ]
おお、そんなものが。
nkf -wができることに最近気づいたくらいアップデートしてなかったんで。

131 名前:名無しさん@お腹いっぱい。 [2007/02/28(水) 09:20:31 ]
浜田マキ子って人のジャーナル見てみなよ。
中国の恐さにぞっとすること請け合い。
あいつら本気で日本を侵略する気だ。
そして、手下はやはり立命館?

132 名前:118 mailto:sage [2007/03/01(木) 04:39:27 ]
>>122
すんません書き漏れです
知りたいのはsh-posixとksh88の機能差です

kshにksh88とksh93があってかなり違うってのは知ってるというか
kshの情報には大抵2つのバージョンの比較が併記されてるもんだし
ただsh-posixとksh88の比較は見たことがないし違いも見つけられなかったもんで

133 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/01(木) 06:28:17 ]
>>132
・ パターンマッチングがegrep相当に拡張
・ [[ ほげ ]] (中身をメタキャラ解釈しないtestのようなもの)
・ 配列が使えた
・ emacs風コマンドライン編集
ってとこか。なおksh93はksh88と挙動が違ったりバグが直されたりしてるし、
ksh88とpdkshでも機能に違いがあるので、
ksh88で動けば他のkshで動作するとは限らない

134 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/01(木) 22:50:40 ]
ksh に限らないが、バージョン依存の対応は本当に面倒だな。

135 名前:名無しさん@お腹いっぱい。 [2007/03/02(金) 00:10:52 ]
こういうデータを、
----
yes
・・・・
・・・
・・・・・
IPアドレス xxx.xxx.xx.54
----
no
・・・・
・・・・・
IPアドレス xxx.xxx.xx.123
----
yes
・・・・・・・・・
・・・・・
IPアドレス xxx.xxx.xx.23

こういうふうに加工したいのですが、
yes,xxx.xxx.xx.54
no,xxx.xxx.xx.123
yes,xxx.xxx.xx.23

・・・・・・・・・
・・・・・
の部分は2行のときもあるし10行のときもあります。

136 名前:135 [2007/03/02(金) 00:14:33 ]
最初の
----

IPアドレス
という文字をうまく関連付ければ
加工可能とは思うのですが、
具体的にどうしたらいいのかよくわかりません。

最初の
----
を見つけたら
その次の「IPアドレス」という文字列を捕まえて
xxx.xxx.xx.123を確保する、
という形でしょうか。

うまい方法があればヒントをいただけますか?
cat、more、grep、cut、sedなど一般的なコマンドは習得しています。

137 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 00:19:45 ]
1行1レコードじゃないときは
めんどくさいから perl 使っちゃうな。

138 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 00:34:22 ]
csplit input '/^----$/' '{*}'
for file in xx*; do echo `sed -n '2p;${s/.* //;p}' $file`; done

csplitってPOSIX標準だっけ?


139 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 00:34:30 ]
俺もperlかawkに1票。適材適所ってやつ。



140 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 01:17:00 ]
awkで RSに---を入れてやればいいじゃない

141 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 01:52:51 ]
ここはあえてCで

142 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 02:52:27 ]
>>141
書いてみて

143 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 08:40:46 ]
>>135
俺も awk に一票だが、
最初と最後をどうにかすれば grep と sed だけでもできそう。

grep -C 1 -x -e ---- | sed ....

こんな感じで。

144 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 08:56:59 ]
143 | sed -n '
N;
N;
N;
s/¥(yes¥|no¥)¥n/¥1 /;
s/----¥n//;
s/--¥n//;
s/IPアドレス //;
p'

改行ってどこのsedでも¥nと書けるのだっけ?


145 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 09:03:20 ]
あー、最後の部分がきちんと処理できないな。


146 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 09:10:43 ]
sed -n '
/¥(yes¥|no¥)/h;
/IPアドレス /{
H;
x;
s/¥(yes¥|no¥)¥n/¥1/;
s/IPアドレス /,/;
p
}' input

どだっ!?


147 名前:135 [2007/03/02(金) 13:43:23 ]
みなさんありがとうございます。
僕はまだレベルが低いですし
awkは(難しくて)使えないので
>>143さんの
grep -C
オプションでやってみよと思います。

148 名前:名無しさん@お腹いっぱい。 [2007/03/02(金) 15:27:32 ]
変数1で指定したディレクトリに変数2のファイル名でlsの結果をリダイレクトするにはどうすればいいですか。

149 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 15:32:33 ]
>>148
ちょっと、質問が複数の意味に取れるけど、

ls > "$1"/"$2"

ってことか?



150 名前:148 [2007/03/02(金) 16:42:33 ]
>>149 できたっす。バックスラッシュいれてたっす。

151 名前:名無しさん@お腹いっぱい。 [2007/03/02(金) 17:25:16 ]
変数1で指定したディレクトリに変数2のファイル名でlsの結果をリダイレクトするときに、すでにファイルが存在する場合、上書き確認のメッセージを出して処理を分岐させるにはどうすればいいですか。

152 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 17:27:36 ]
test -f ファイル
[ -f ファイル ]


153 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 18:47:44 ]
その調子で、1から10まで全部ここで聞くのか?

154 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 19:02:57 ]
シェルスクリプトの犬小屋でも作るか?

155 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 19:07:44 ]
いらね。

156 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 21:48:30 ]
>>152
便乗質問ですが、よく、ファイルがあるかどうかを判断するのに、
test -fを使えと言われるのですが、実行しても何も起こりません。
何か設定が必要なのでしょうか?

157 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 21:58:24 ]
test -f hoge && echo found

158 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 22:18:29 ]
「ファイルがあるかどうか」なら、test -fじゃなく、test -e使え。
test -fだとレギュラーファイル以外はないものと判定されるぞ。
(デバイスファイルとか、broken symlinkとか、socketとか)

159 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 22:36:23 ]
>>158
だめーっ。Bourneではtest -eは使えなーい。test -fが定石。



160 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 22:40:52 ]
if exist %1

161 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 23:04:59 ]
>>156

何かが起こるように書けばいい。
test を実行しただけで何も起こらないのは当たり前。

162 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/02(金) 23:15:29 ]
Bourne Shellのif文で、ifの次に来るのはコマンド(列)
test...も [ ... ] もコマンドを実行してる。
実行した結果のステータスコードで分岐するだけ。


163 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 00:09:47 ]
>>159
>>162の通り、testはシェルの内部コマンドではない。Bourneかどうかは関係ない。

まあそれはそれとして、autoconf infoの"Limitations of Builtins"から抜粋。
POSIXも信用せずにportableにしたいならどおぞ。

... use `test -f' or `test -r'. Do not use `test -x', because 4.3BSD
does not have it. Do not use `test -e' either, because Solaris 2.5
does not have it. To test for symbolic links on systems that have
them, use `test -h' rather than `test -L'; either form conforms to
POSIX 1003.1-2001, but older shells like Solaris 8 `/bin/sh' support
only `-h'.


164 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 00:37:34 ]
うちのシェルでは内部コマンドなのだが。

165 名前:162 mailto:sage [2007/03/03(土) 01:05:35 ]
>>164
そういえばそうか。シェルの実装はtestを内部コマンドとして定義しても
いいんだっけか。すまん間違えた。


166 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 01:21:37 ]
testは外部コマンドだから条件分岐は出来るだけcaseを使おうって話を
どっかで聞いたことがあるけど、
UNIX黎明期を除けばどのシステムでもシェル組み込みコマンドとして実装されている。
ループで最頻出のコマンドが外部呼び出しじゃ実用的な速度が出ないだろうしね。

167 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 01:30:36 ]
>>166
KernighanとPikeのUnix Programming Environmentにそういう記述があった希ガス。
UNIX第7版とかの時代の話だが。

168 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 07:57:52 ]
162は俺なのだが……、俺は「外部コマンド」とは書いてないぞ。


169 名前:163=165 mailto:sage [2007/03/03(土) 11:51:37 ]
>>168
すまん番号間違えた。
漏れは163と165だた




170 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 12:08:23 ]
>>166
適当なループ回して試してみろ。
testが内部コマンドである現在のシェルでも、
case使った方が、if [ ... ] よりも若干速いよ。

おそらく、内部コマンドとはいえ、独立したコマンドとして
内部的に実行するオーバーヘッドがtestにはかかるんだろう。
caseの場合はシェル本体が直接解釈するから
オーバーヘッドはtestよりも少ないと。

171 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 14:06:00 ]
>>170
釣りか天然か... 判断に苦しむ。

172 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 14:20:05 ]
>>171
釣りじゃないだろ。実験してみろ。time sh -c '...' とかで計れる。
確かに caseの方がちょっと早い。

173 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 14:34:36 ]
>>171
おかしなところがあるなら具体的に指摘してみればいいじゃない

174 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 14:37:35 ]
だね。あと、zshだと何故か違いが顕著になる。


$ time zsh -c 'for i in `seq 1 10000`; do [ a = a ] && :; done'
real 0m3.051s
user 0m2.705s
sys 0m0.207s

$ time zsh -c 'for i in `seq 1 10000`; do case a in a);;esac; done'
real 0m0.915s
user 0m0.703s
sys 0m0.204s


↓おまけ。[ ]の代わりに [[ ]] にすると、内部コマンドじゃなく、
直接のシェル文法になるので、早くなる。

$ time zsh -c 'for i in `seq 1 10000`; do [[ a = a ]] && :; done'
real 0m1.708s
user 0m1.201s
sys 0m0.402s

175 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 15:41:12 ]
>>173
おかしなところは推測の部分。単に実装の違いだけでしょ。

ksh(93)
case 0.65 real 0.46 user 0.17 sys
test 0.58 real 0.46 user 0.10 sys

pdksh
case 23.23 real 22.45 user 0.20 sys
test 4.96 real 4.74 user 0.14 sys

bash2
case 3.52 real 3.21 user 0.24 sys
test 4.26 real 3.93 user 0.25 sys

ash
case 0.38 real 0.28 user 0.09 sys
test 0.52 real 0.45 user 0.05 sys

176 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 17:55:22 ]
>>175
その実装の違いを推測してるのではないか? なので、おかしくない。

ちなみに俺の環境では、kshでもtestよりcaseの方が速かったよ。

177 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 18:59:53 ]
つまり、testよりcase使え、って言うテクは今でも生きてるってわけか。

178 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 20:43:22 ]
bash3 [[
real 0m1.758s
user 0m1.562s
sys 0m0.160s

bash3 case
real 0m1.515s
user 0m1.341s
sys 0m0.150s

確かに少しだけど、case の方が速いね

179 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 20:53:55 ]
>>178
いや、[[じゃなくて [ と caseを比較するという話だが。

速い順に、
case > [[ > [
となると思う。



180 名前:名無しさん@お腹いっぱい。 mailto:sage [2007/03/03(土) 21:13:01 ]
>>179
あ、そうだったっけか。

bash3 [
real 0m2.388s
user 0m2.042s
sys 0m0.370s


181 名前:名無しさん@お腹いっぱい。 [2007/03/04(日) 21:32:58 ]
Bashにおいて以下の条件で動くシェルスクリプトを書く場合、どのように書けばよいのでしょうか?

ディレクトリ名とその中にあるファイルサイズが0のファイル名を出力する。
補足1:ディレクトリが特定されていない場合は、現在シェルが働いているディレクトリ名を出力する。
補足2:もし引数がディレクトリ名でない場合は、すべてのコマンドラインの引数にエラーメッセージを出力する。
補足3:ファイル名の一番最初の文字が、「.」の場合は無視するようにする。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<228KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef