シェルスクリプト総合 その5
■ このスレッドは過去ログ倉庫に格納されています
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 でトレースしましょう。
0092名無しさん@お腹いっぱい。
2006/01/27(金) 23:36:28(゚Д゚)ハァ?哲哉してて頭おかしかったようです。。
0093名無しさん@お腹いっぱい。
2006/01/27(金) 23:45:30>command1が失敗したらcommand2なんか実行しないんだよ。
x が偽ならば y に関係なく x && y が偽なのは事実だが、
y を評価せずに済ませるかどうかは論理演算とはまったく何の関係もない。
sh を含めほとんどの言語がそう実装されているだけ。
0094名無しさん@お腹いっぱい。
2006/01/27(金) 23:54:16違います。仕様です。
A && Bは、
if A; then B; fiと同じです。
0095名無しさん@お腹いっぱい。
2006/01/27(金) 23:58:120096名無しさん@お腹いっぱい。
2006/01/27(金) 23:59:320097名無しさん@お腹いっぱい。
2006/01/28(土) 00:00:55(だからshでは最適化してて)command1が失敗したらcommand2なんか実行しないんだよ。
だったらいいんじゃね?重箱の隅つまんね。
0098名無しさん@お腹いっぱい。
2006/01/28(土) 00:05:18>(だからshでは最適化してて)command1が失敗したらcommand2なんか実行しないんだよ。
このカッコの中を省略するのを指摘するのが重箱の隅だというのは
無理がありすぎるだろ。
0099名無しさん@お腹いっぱい。
2006/01/28(土) 00:07:000100名無しさん@お腹いっぱい。
2006/01/28(土) 00:09:080101名無しさん@お腹いっぱい。
2006/01/28(土) 00:12:280102名無しさん@お腹いっぱい。
2006/01/28(土) 00:31:51http://www.jp.freebsd.org/cgi/mroff.cgi?subdir=man&lc=1&cmd=&man=sh&dir=jpman-5.4.0%2Fman§=0 の
短絡リスト演算子 (Short-Circuit List Operators) を読んでくるように。
0103名無しさん@お腹いっぱい。
2006/01/28(土) 01:16:46そういうお前にはサイエンス社版クヌース4冊の演習問題を宿題として与える
0104名無しさん@お腹いっぱい。
2006/01/28(土) 01:38:110105名無しさん@お腹いっぱい。
2006/01/28(土) 02:12:250106名無しさん@お腹いっぱい。
2006/01/28(土) 12:30:10だと、余分なサブシェルが起動されるから無駄。
command1や2でシェル変数を操作してたら反映されないというバグを生じるし。
{ command1 && command2; } || command3
と、グルーピングにするべき。
もちろん、&&の方が優先順位が高いから、
command1 && command2 || command3
と書いても同じことだけど。
0107名無しさん@お腹いっぱい。
2006/01/28(土) 12:35:310108名無しさん@お腹いっぱい。
2006/01/28(土) 12:38:08> もちろん、&&の方が優先順位が高いから、
そういう問題なん?
0109名無しさん@お腹いっぱい。
2006/01/28(土) 12:48:330110名無しさん@お腹いっぱい。
2006/01/28(土) 13:23:52同じ優先順位だから左側の演算子(&&)の方が優先順位が高いという意味だろ。
あげ足ばっかだな。
0111名無しさん@お腹いっぱい。
2006/01/28(土) 13:32:29それは優先順位が高いと言わない。
「左に結合する」などが適切な表現。
優先順位は別の概念。
0112名無しさん@お腹いっぱい。
2006/01/28(土) 13:38:560113名無しさん@お腹いっぱい。
2006/01/28(土) 14:08:440114名無しさん@お腹いっぱい。
2006/01/28(土) 15:27:48ノシ
0115名無しさん@お腹いっぱい。
2006/01/28(土) 15:57:44shellでも、commandじゃなくて算術式の中なら、
&& の方が || より優先順位が高い。
例: (( 1 || 3 && 0 )) の結果は真になる。
0116名無しさん@お腹いっぱい。
2006/01/28(土) 17:27:50その例だと. 同一優先順/左結合でも,
1 が真で 3 && 0 を評価しないので
やはり真になるんだが...
0117名無しさん@お腹いっぱい。
2006/01/28(土) 17:31:48$ echo $(( (1 || 3) && 0 ))
0
でしょ。
$ echo $(( 1 || (3 && 0) ))
1
$ echo $(( 1 || 3 && 0 ))
1
0118名無しさん@お腹いっぱい。
2006/01/28(土) 17:32:51違います。
仮に同一優先順位左から結合だとすると、
((1 || 3)) が真で、そのあと((1 && 0))が評価されるから偽になる。
0119名無しさん@お腹いっぱい。
2006/01/28(土) 17:33:180120名無しさん@お腹いっぱい。
2006/01/28(土) 17:35:10>>116 は間違い。
>>117 >>118 が正解。
0121名無しさん@お腹いっぱい。
2006/01/28(土) 17:36:55算術式の場合は 0が偽になるというのも混乱の元だなぁ。
0122名無しさん@お腹いっぱい。
2006/01/28(土) 17:53:510といえば0だけど、シェルの if や while が見るのは終了コードなので
一緒にするのはよくないかと。
確かに紛らわしいんだけど
0123名無しさん@お腹いっぱい。
2006/01/28(土) 19:30:50「終了値が0かそれ以外か」とは考えなくて、
「コマンドが成功するか失敗するか」と考えるから混乱することはない。
status=$? して後で利用する時くらいか。
0124名無しさん@お腹いっぱい。
2006/01/28(土) 19:55:200125名無しさん@お腹いっぱい。
2006/01/28(土) 20:04:21言われて気づいたが、不思議なことに全然混乱していない。
0126名無しさん@お腹いっぱい。
2006/01/28(土) 20:50:03「シェル関数」とわざわざ断っているのはどうして?
exitじゃなくてreturnの間違い?
$ function f () { return 0; }
$ if f; then echo yes; fi
yes
だからね。
それともサブ・シェルでのexitのこと?
0127名無しさん@お腹いっぱい。
2006/01/28(土) 21:04:500128名無しさん@お腹いっぱい。
2006/01/29(日) 02:17:330129名無しさん@お腹いっぱい。
2006/01/30(月) 15:03:320130名無しさん@お腹いっぱい。
2006/01/30(月) 23:03:48for((i=0.1;i<1;i=i+0.1)){
echo $i
}
のような感じです。
0131名無しさん@お腹いっぱい。
2006/01/30(月) 23:07:490132名無しさん@お腹いっぱい。
2006/01/30(月) 23:07:59for文で小数使うな
0133名無しさん@お腹いっぱい。
2006/01/30(月) 23:13:14□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
0134名無しさん@お腹いっぱい。
2006/01/30(月) 23:16:050135名無しさん@お腹いっぱい。
2006/01/30(月) 23:18:050136名無しさん@お腹いっぱい。
2006/01/30(月) 23:18:40場合によっては bc 使う
$ for i in $(seq 10); do echo "$i/10.0" | bc -l; done
0137名無しさん@お腹いっぱい。
2006/01/31(火) 00:02:15seqは小数点使える奴が多いんじゃまいか
$ seq 0.1 0.1 1
0.1
(ry
0.8
0.9
それから、seq 9な。
0138名無しさん@お腹いっぱい。
2006/01/31(火) 00:02:59そう言うときは「漢」という字を使え
0139名無しさん@お腹いっぱい。
2006/02/01(水) 02:29:09シェルで良いんじゃないか?
0140名無しさん@お腹いっぱい。
2006/02/01(水) 02:50:13sedやawkも使わず、変数の展開だけでがんばれるようになったらな。
0141名無しさん@お腹いっぱい。
2006/02/01(水) 03:50:40>>130 はシェルスクリプトのつもりで言ってるかも試練が
この場合はむしろシェルの方が正しいだろ
0142名無しさん@お腹いっぱい。
2006/02/01(水) 06:08:560143名無しさん@お腹いっぱい。
2006/02/01(水) 08:05:31○ シェルスクリプトで〜〜する
× シェルを書く
○ シェルスクリプトを書く
0144名無しさん@お腹いっぱい。
2006/02/01(水) 08:24:37× 〜というシェルが動かない
0145名無しさん@お腹いっぱい。
2006/02/01(水) 11:37:12> × シェルを書く
だからぁ...
% vi lex.l
% vi parse.y
% vi main.c
...
% vi Makefile
% make
てな作業の事なので無問題
>>144
> × 〜というシェルが動かない
"〜" が sh とか bash とか csh とか tcsh とか zsh とか scsh とか...
だったら無問題
0146名無しさん@お腹いっぱい。
2006/02/01(水) 11:44:17そんなんできるやつには○とか×とか言わんよ。
0147名無しさん@お腹いっぱい。
2006/02/01(水) 12:07:190148名無しさん@お腹いっぱい。
2006/02/01(水) 12:43:26まあ、プロンプト % で書く香具師は、何言っても説得力が無いわな。
0149名無しさん@お腹いっぱい。
2006/02/01(水) 22:48:40プロンプトが常に # の奴もちょっと嫌だな。w
0150名無しさん@お腹いっぱい。
2006/02/01(水) 23:15:190151名無しさん@お腹いっぱい。
2006/02/01(水) 23:30:140152名無しさん@お腹いっぱい。
2006/02/01(水) 23:36:250153名無しさん@お腹いっぱい。
2006/02/02(木) 00:27:250154名無しさん@お腹いっぱい。
2006/02/02(木) 01:09:25# はコメントみたいだし、$ は変数と紛らわしい
0155名無しさん@お腹いっぱい。
2006/02/02(木) 04:09:380156名無しさん@お腹いっぱい。
2006/02/02(木) 04:43:510157名無しさん@お腹いっぱい。
2006/02/02(木) 06:00:560158名無しさん@お腹いっぱい。
2006/02/02(木) 09:01:45スーパーハッカーが集うスレッドはここですか?
0159名無しさん@お腹いっぱい。
2006/02/02(木) 09:59:110160名無しさん@お腹いっぱい。
2006/02/02(木) 10:05:140161名無しさん@お腹いっぱい。
2006/02/02(木) 11:29:17シェルを書くには結構な腕が必要なんじゃないか?
おれは、シェルスクリプトは書けてもシェルは書けん。
0162名無しさん@お腹いっぱい。
2006/02/02(木) 11:56:11システムプログラムの初歩なんで、
やればできるレベルだと思われ。
動かすだけなら結構簡単なので、
大学での演習レベル。
0163名無しさん@お腹いっぱい。
2006/02/02(木) 12:00:110164名無しさん@お腹いっぱい。
2006/02/02(木) 12:14:17パイプとか、サブシェルとか、ジョブコンとか、環境変数とか、
基本的とはいえかなりのシステムコールの利用経験と、パーザの知識がいるかと。
0165名無しさん@お腹いっぱい。
2006/02/02(木) 12:19:32これは簡単だろ。
> ジョブコンとか、
とCtrl-Cでシグナル喰った時のシェルの挙動辺りは
ちゃんとPOSIX規格その他を読んでないと難しいものがある。
少なくともマルチプラットーフォームは無理。
0166名無しさん@お腹いっぱい。
2006/02/02(木) 12:28:52Posix 互換でなきゃいけないのか?
scsh とか, ぜんぜん Posix 互換じゃないし interactive shell として使おうと
言う気すら起きないが, それでも shell だ.
0167名無しさん@お腹いっぱい。
2006/02/02(木) 18:26:02165はジョブコンを(ポータブルに)きちんと実装するのに知識が必要だって
ことなんでは。
0168名無しさん@お腹いっぱい。
2006/02/02(木) 18:32:17元祖B-shにはないし、今時のシェルであっても
非対話モード(シェルスクリプト)で起動されれば
ジョブコンはdisableされるのが普通。
0169名無しさん@お腹いっぱい。
2006/02/02(木) 18:46:35ジョブコンゆうなぁ...
いまだに ジョブコン -> JCL とリダクションされる.
0170名無しさん@お腹いっぱい。
2006/02/02(木) 19:03:41csh, tcshって今でも非対話モードでもジョブコンenblaeされたままなのかな?
大昔、子プロセスにSIGSTOP送ったら、(もちろんkill(1)→killpg(2))
プロセスグループが別で、シェルに制御が戻って、
子プロセス異常終了で、スクリプトが止まったのはビビッた。
>>167
setsid()周辺は古いUNIXも含めると大変だよね。
Emacsにはその辺のレガシーなコードがまだ残っているが。
0171名無しさん@お腹いっぱい。
2006/02/02(木) 19:52:26ん?null?
0172名無しさん@お腹いっぱい。
2006/02/02(木) 20:18:48「リダクション」reduction:半減。例:ノイズリダクション
??はて??
0173名無しさん@お腹いっぱい。
2006/02/02(木) 20:33:370174名無しさん@お腹いっぱい。
2006/02/02(木) 21:56:420175名無しさん@お腹いっぱい。
2006/02/02(木) 22:01:460176名無しさん@お腹いっぱい。
2006/02/02(木) 22:20:08というか、「リダクション」じゃなく、
「リフレクション」と言いたかったのでは、とマジレス。
0177名無しさん@お腹いっぱい。
2006/02/02(木) 22:36:05ラムダ計算あたりでは、リダクションってのは、おおざっぱに言って
1/3 + 2/3 -> 1
のように, 複雑な表現から簡約された表現に置き換えることをさします。
おそらく >>169 の頭の中では、ジョブコンよりも JCL の方が簡約された
表現だったんだと思うんですけど…
ちゃうんかい >>169
0178名無しさん@お腹いっぱい。
2006/02/02(木) 22:44:280179名無しさん@お腹いっぱい。
2006/02/02(木) 22:47:01それは >>169 に聞いてくれ。おいらの知ったこっちゃない。
ってか、文字数から見ると十分リダクションしてると思う。
0180名無しさん@お腹いっぱい。
2006/02/02(木) 22:52:210181名無しさん@お腹いっぱい。
2006/02/02(木) 23:06:50あは…
そう言われるとそうだ。
0182名無しさん@お腹いっぱい。
2006/02/04(土) 11:35:02#!/usr/bin/ruby
require 'kconv'
puts 'あいうえお'.toutf8
以下の出力が異なるのはそーゆーもん? echo 使ったほうが化けちゃうみたい。
#!/bin/sh
./utfout.rb
echo `./utfout.rb`
sh は dash ってやつ(Debian版 の ash みたい、Debian でごめん)。
こんなときは bash 使うべきなんかね(bash なら化けなかった)。
0183名無しさん@お腹いっぱい。
2006/02/04(土) 11:58:50と勘で回答してみる。
0184名無しさん@お腹いっぱい。
2006/02/04(土) 12:11:140185名無しさん@お腹いっぱい。
2006/02/04(土) 12:24:22あーごめんなさい。どっちも試してたんだけど相変わらず化けたまんまっす。
ちなみに dash は echo は内部に持ってないみたいなのでどっちにしろ
/bin/sh を使ってるみたい。
0186名無しさん@お腹いっぱい。
2006/02/04(土) 15:06:52> /bin/sh を使ってるみたい。
なにその角度
0187名無しさん@お腹いっぱい。
2006/02/04(土) 17:04:37/bin/shを使う(ビルトインじゃないのは丸投げかよ)
でぶの考えは理解できんな。
0188名無しさん@お腹いっぱい。
2006/02/04(土) 17:11:31どっちにしろ
Debian$ dash -c 'echo `echo どっちにしろ | iconv -f euc-jp -t utf-8`' | iconv -f utf-8 -t euc-jp
どっちにしろ
0189名無しさん@お腹いっぱい。
2006/02/04(土) 17:59:06/bin/sh は /bin/echo の書き間違いね。失敬。
>>188
むむ。
% dash -c 'echo `echo どっちにしろ | iconv -f euc-jp -t utf-8`' | iconv -f utf-8 -t euc-jp
iconv: 位置 0 で不正な入力シーケンスがありました
手元の stable 環境だとこうなった。環境か dash の version 固有の話っぽい
ので犬板行ってみる。
0190名無しさん@お腹いっぱい。
2006/02/04(土) 23:02:430191名無しさん@お腹いっぱい。
2006/02/05(日) 11:14:41■ このスレッドは過去ログ倉庫に格納されています