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

シェルスクリプト総合 その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 でトレースしましょう。
0066名無しさん@お腹いっぱい。2006/01/24(火) 19:37:27
つまり移植性的にも問題無いって事か
テンプレ?
0067名無しさん@お腹いっぱい。2006/01/24(火) 21:12:37
>>65
それいつから?
すくなくとも, 現場で稼働してる
% uname -a
SunOS ns11 5.9 Generic_112233-06 sun4u sparc SUNW,UltraAX-i2
な, マシンでは使えないんだが...
0068名無しさん@お腹いっぱい。2006/01/24(火) 21:41:24
>>65
なんてオプション?
0069名無しさん@お腹いっぱい。2006/01/24(火) 21:58:07
>>65
Solaris 10でも無いよ。嘘はイカンよ。
0070名無しさん@お腹いっぱい。2006/01/25(水) 02:40:57
Solarisなんかに移植しようなんて考えなけりゃいいじゃん。
0071名無しさん@お腹いっぱい。2006/01/25(水) 12:27:16
えっとtgzファイルのgrep検索なんですが、
tar Ozxf hoge.tgz | grep arekore
とかやってもどのファイルにあったか分からないんで困ってます。
そりゃファイルを展開すればいいけど、また削除するのが面倒です。
tarのオプション`O'はファイルを作らないでSTDINに出してくれるので
これとシェルスクリプトの何か使ってファイル名と行数を出してくれる
ようなことできないでしょうか。

0072名無しさん@お腹いっぱい。2006/01/25(水) 12:34:20
ディレクトリ作って展開してgrepしてディレクトリごと消すスクリプトじゃだめなん?
0073名無しさん@お腹いっぱい。2006/01/25(水) 12:42:53
>>71
tar Ozxvf hoge.tgz 2>&1 |
だと、ファイル名も出てくるから、何とか加工できるかもしれんが、
はげしくtarの実装に依存しそう
0074名無しさん@お腹いっぱい。2006/01/25(水) 12:44:37
hoge.tgzがhoge-1.0/*のアーカイブだとして、

tar Ovzxf hoge.tgz 2>&1 | egrep '^hoge-1.0/|arekore'

くらいで我慢して貰えないか?

perlならArchive::Tar使ってなんとでもなるけども。
0075名無しさん@お腹いっぱい。2006/01/25(水) 23:00:20
>>72, >>73-74
ご返答ありがとうございます。今、帰りますた。
で、実はcygwinでやってまして、まず、以下の環境で>>74さんの
でやってみたのですが、何にも出てこなかったっす。
~$ tar --version
tar (GNU tar) 1.15.1
~$ egrep --version
egrep (GNU grep) 2.5.1
でもって>>72さんのでやればいいことに気づきました。ってか、
それは気づいていたんですけどやりたくなかったんですが…
0076名無しさん@お腹いっぱい。2006/01/27(金) 00:49:24
情報小出し野郎登場。以後スルーでよろしく>みなさま
0077名無しさん@お腹いっぱい。2006/01/27(金) 19:29:46
command1 && command2 || command3
と書いた場合の挙動ってどのシェルも同じ?
0078名無しさん@お腹いっぱい。2006/01/27(金) 19:53:02
command1,command2,command3がすべて実行されることを期待しても良いか、ということ?
0079名無しさん@お腹いっぱい。2006/01/27(金) 20:11:06
>>77
どのシェルも同じ。

>>78
すべて実行されるわけないだろ。
0080名無しさん@お腹いっぱい。2006/01/27(金) 21:24:44
>>79
command2 が偽を返したらすべて実行されるんじゃないか?

>>77
どのシェルも同じかどうかはシェルを特定しないと答えようがないな
変な仕様の独自シェルだってありえるし
0081名無しさん@お腹いっぱい。2006/01/27(金) 21:34:04
>>80
□お約束
・特記なき場合はbourne shがデフォルトです。

「無条件ですべて実行される」わけないだろ。
0082名無しさん@お腹いっぱい。2006/01/27(金) 21:50:02
> どのシェルも同じ?
という質問にそれはないだろ。
0083名無しさん@お腹いっぱい。2006/01/27(金) 22:16:00
command1 && command2 || command3 と書いたときに、|| がcommand1の結果
を見るのか、command2 の結果を見るのか、っていうのがシェルごとに違うか?

っていう質問ならば「違わない」。
0084名無しさん@お腹いっぱい。2006/01/27(金) 22:42:33
>>83
|| がcommand1の結果を見るのは実験してわかったのですが、manual を読んで
もきちんと書かれていないように見えます。私の読みかたが甘いのでしょう
か?
0085名無しさん@お腹いっぱい。2006/01/27(金) 22:44:29
はひ?
0086名無しさん@お腹いっぱい。2006/01/27(金) 22:48:25
&&や||はshort cut operatorってやつ。
右項を評価するかどうかは、左項の値による。
Cとおんなじ。
0087名無しさん@お腹いっぱい。2006/01/27(金) 22:51:33
N88 BASICでもおんなじだぉ

0088名無しさん@お腹いっぱい。2006/01/27(金) 23:07:32
いつもおもろいヤツが多いよな、このスレは

$ ./success.sh && ./success.sh || echo failure
$ ./success.sh && ./failure.sh || echo failure
failure
$ ./failure.sh && ./success.sh || echo failure
failure

>84
論理演算って知ってる?0 && 1も1 && 0も0だろ。
command1が失敗したらcommand2なんか実行しないんだよ。
0089名無しさん@お腹いっぱい。2006/01/27(金) 23:09:55
>>88
いや、command2 が実行されないのは不思議ではないです。
command3 が command1 の $? を見るのがどこに書かれているのかなぁと。。
0090名無しさん@お腹いっぱい。2006/01/27(金) 23:23:07
>>89
> command1 && command2 || command3

は、

(command1 && command2) || command3

と同じ。man shの"優先順位"も見れ!

0091名無しさん@お腹いっぱい。2006/01/27(金) 23:24:13
command2を実行してないんだろ。
そしたらcommand1の結果を見るしかないじゃんw

88の例でも、success && success || echo failureなら何もでてないわけで、
command1とcommand2の両方の結果をちゃんと見てるジャン。

実行されないのは不思議ではないとか口ではいっときながら理解してないYo!
0092名無しさん@お腹いっぱい。2006/01/27(金) 23:36:28
>>91
(゚Д゚)ハァ?哲哉してて頭おかしかったようです。。
0093名無しさん@お腹いっぱい。2006/01/27(金) 23:45:30
>論理演算って知ってる?0 && 1も1 && 0も0だろ。
>command1が失敗したらcommand2なんか実行しないんだよ。

x が偽ならば y に関係なく x && y が偽なのは事実だが、
y を評価せずに済ませるかどうかは論理演算とはまったく何の関係もない。
sh を含めほとんどの言語がそう実装されているだけ。
0094名無しさん@お腹いっぱい。2006/01/27(金) 23:54:16
>>93
違います。仕様です。

A && Bは、
if A; then B; fiと同じです。
0095名無しさん@お腹いっぱい。2006/01/27(金) 23:58:12
ますます論理演算と関係ないじゃん。
0096名無しさん@お腹いっぱい。2006/01/27(金) 23:59:32
>>88>>93も間違いを含んでいる。←は真
0097名無しさん@お腹いっぱい。2006/01/28(土) 00:00:55
論理演算って知ってる?0 && 1も1 && 0も0だろ。
(だからshでは最適化してて)command1が失敗したらcommand2なんか実行しないんだよ。

だったらいいんじゃね?重箱の隅つまんね。
0098名無しさん@お腹いっぱい。2006/01/28(土) 00:05:18
sh で command2 が実行されるかどうかの話としてるときに、

>(だからshでは最適化してて)command1が失敗したらcommand2なんか実行しないんだよ。

このカッコの中を省略するのを指摘するのが重箱の隅だというのは
無理がありすぎるだろ。
0099名無しさん@お腹いっぱい。2006/01/28(土) 00:07:00
じゃ、言い方を変えよう。質問してたヤツが納得したのに延々とつまんね(俺含む)
0100名無しさん@お腹いっぱい。2006/01/28(土) 00:09:08
うむ、そのとおりだ。消える。
0101名無しさん@お腹いっぱい。2006/01/28(土) 00:12:28
数学A 「論理と集合」で盛り上がっているスレはここですか?
0102名無しさん@お腹いっぱい。2006/01/28(土) 00:31:51
とりあえず、よいこのみんなは、明日までに
http://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
>>102
そういうお前にはサイエンス社版クヌース4冊の演習問題を宿題として与える
0104名無しさん@お腹いっぱい。2006/01/28(土) 01:38:11
そんなもん死ぬまで終わらんわ
0105名無しさん@お腹いっぱい。2006/01/28(土) 02:12:25
本当に賢いしとはあーだこーだ考える前にカッコでくくっちゃうんだろうけどネ
0106名無しさん@お腹いっぱい。2006/01/28(土) 12:30:10
(command1 && command2) || command3
だと、余分なサブシェルが起動されるから無駄。
command1や2でシェル変数を操作してたら反映されないというバグを生じるし。

{ command1 && command2; } || command3
と、グルーピングにするべき。

もちろん、&&の方が優先順位が高いから、
command1 && command2 || command3
と書いても同じことだけど。
0107名無しさん@お腹いっぱい。2006/01/28(土) 12:35:31
きみたちがプロでないことをはげしくねがうよ。
0108名無しさん@お腹いっぱい。2006/01/28(土) 12:38:08
>>106
> もちろん、&&の方が優先順位が高いから、
そういう問題なん?
0109名無しさん@お腹いっぱい。2006/01/28(土) 12:48:33
そういう問題でない以前に、&& と || の優先度は同じ。
0110名無しさん@お腹いっぱい。2006/01/28(土) 13:23:52
>>109
同じ優先順位だから左側の演算子(&&)の方が優先順位が高いという意味だろ。
あげ足ばっかだな。
0111名無しさん@お腹いっぱい。2006/01/28(土) 13:32:29
>>110
それは優先順位が高いと言わない。
「左に結合する」などが適切な表現。
優先順位は別の概念。
0112名無しさん@お腹いっぱい。2006/01/28(土) 13:38:56
なんだかなぁ・・・
0113名無しさん@お腹いっぱい。2006/01/28(土) 14:08:44
きみたちがプロでないことをはげしくねがうよ。
0114名無しさん@お腹いっぱい。2006/01/28(土) 15:27:48
&&の方が||より優先順位が高いと思っていたヤシ

ノシ
0115名無しさん@お腹いっぱい。2006/01/28(土) 15:57:44
C言語だと本当に && の方が || より優先順位が高い。

shellでも、commandじゃなくて算術式の中なら、
&& の方が || より優先順位が高い。
例: (( 1 || 3 && 0 )) の結果は真になる。
0116名無しさん@お腹いっぱい。2006/01/28(土) 17:27:50
>>115
その例だと. 同一優先順/左結合でも,
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
>>116
違います。

仮に同一優先順位左から結合だとすると、
((1 || 3)) が真で、そのあと((1 && 0))が評価されるから偽になる。
0119名無しさん@お腹いっぱい。2006/01/28(土) 17:33:18
ゆとり教育の弊害がここにも!
0120名無しさん@お腹いっぱい。2006/01/28(土) 17:35:10
かぶった。
>>116 は間違い。
>>117 >>118 が正解。
0121名無しさん@お腹いっぱい。2006/01/28(土) 17:36:55
シェルでは普通、0が真なんだが、
算術式の場合は 0が偽になるというのも混乱の元だなぁ。
0122名無しさん@お腹いっぱい。2006/01/28(土) 17:53:51
>>121
0といえば0だけど、シェルの if や while が見るのは終了コードなので
一緒にするのはよくないかと。
確かに紛らわしいんだけど

0123名無しさん@お腹いっぱい。2006/01/28(土) 19:30:50
control operatorの場合、
「終了値が0かそれ以外か」とは考えなくて、
「コマンドが成功するか失敗するか」と考えるから混乱することはない。

status=$? して後で利用する時くらいか。
0124名無しさん@お腹いっぱい。2006/01/28(土) 19:55:20
シェル関数の中で exit 1とか exit 0とか書く時に混乱するだろ。
0125名無しさん@お腹いっぱい。2006/01/28(土) 20:04:21
>>124
言われて気づいたが、不思議なことに全然混乱していない。
0126名無しさん@お腹いっぱい。2006/01/28(土) 20:50:03
>>124
「シェル関数」とわざわざ断っているのはどうして?
exitじゃなくてreturnの間違い?

$ function f () { return 0; }
$ if f; then echo yes; fi
yes

だからね。

それともサブ・シェルでのexitのこと?
0127名無しさん@お腹いっぱい。2006/01/28(土) 21:04:50
わかった上でビミョーに誤りを混入してカキコして釣るのが高度な釣り師。
0128名無しさん@お腹いっぱい。2006/01/29(日) 02:17:33
こりゃおじさん一本取られちゃったな。
0129名無しさん@お腹いっぱい。2006/01/30(月) 15:03:32
じいさんめんご
0130名無しさん@お腹いっぱい。2006/01/30(月) 23:03:48
シェルで 少数を使った計算はできますか? 例えば
for((i=0.1;i<1;i=i+0.1)){
echo $i
}
のような感じです。
0131名無しさん@お腹いっぱい。2006/01/30(月) 23:07:49
シェルってゆうな。クズ。
0132名無しさん@お腹いっぱい。2006/01/30(月) 23:07:59
>>130
for文で小数使うな
0133名無しさん@お腹いっぱい。2006/01/30(月) 23:13:14
まあそんなことをしたくなったらperlやrubyってのが普通だな。

□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
0134名無しさん@お腹いっぱい。2006/01/30(月) 23:16:05
意地でも sh と sed と awk だけで問題を片付ける、それが男道
0135名無しさん@お腹いっぱい。2006/01/30(月) 23:18:05
cutはダメ?
0136名無しさん@お腹いっぱい。2006/01/30(月) 23:18:40
>>130
場合によっては bc 使う
$ for i in $(seq 10); do echo "$i/10.0" | bc -l; done
0137名無しさん@お腹いっぱい。2006/01/31(火) 00:02:15
>>136
seqは小数点使える奴が多いんじゃまいか

$ seq 0.1 0.1 1
0.1
(ry
0.8
0.9

それから、seq 9な。
0138名無しさん@お腹いっぱい。2006/01/31(火) 00:02:59
>>134
そう言うときは「漢」という字を使え
0139名無しさん@お腹いっぱい。2006/02/01(水) 02:29:09
>>131
シェルで良いんじゃないか?
0140名無しさん@お腹いっぱい。2006/02/01(水) 02:50:13
>>138
sedやawkも使わず、変数の展開だけでがんばれるようになったらな。
0141名無しさん@お腹いっぱい。2006/02/01(水) 03:50:40
>>131
>>130 はシェルスクリプトのつもりで言ってるかも試練が
この場合はむしろシェルの方が正しいだろ
0142名無しさん@お腹いっぱい。2006/02/01(水) 06:08:56
少数っていうな、が正しい
0143名無しさん@お腹いっぱい。2006/02/01(水) 08:05:31
○ シェルで〜〜する
○ シェルスクリプトで〜〜する
× シェルを書く
○ シェルスクリプトを書く
0144名無しさん@お腹いっぱい。2006/02/01(水) 08:24:37
中等レベル
× 〜というシェルが動かない
0145名無しさん@お腹いっぱい。2006/02/01(水) 11:37:12
>>143
> × シェルを書く
だからぁ...
% 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
>>145
そんなんできるやつには○とか×とか言わんよ。
0147名無しさん@お腹いっぱい。2006/02/01(水) 12:07:19
どーでもいーな
0148名無しさん@お腹いっぱい。2006/02/01(水) 12:43:26
>>145
まあ、プロンプト % で書く香具師は、何言っても説得力が無いわな。
0149名無しさん@お腹いっぱい。2006/02/01(水) 22:48:40
>>148
プロンプトが常に # の奴もちょっと嫌だな。w
0150名無しさん@お腹いっぱい。2006/02/01(水) 23:15:19
プロンプトが$な漏れは勝ち組。
0151名無しさん@お腹いっぱい。2006/02/01(水) 23:30:14
# な俺は神
0152名無しさん@お腹いっぱい。2006/02/01(水) 23:36:25
zshはプロンプトが%
0153名無しさん@お腹いっぱい。2006/02/02(木) 00:27:25
> な人
0154名無しさん@お腹いっぱい。2006/02/02(木) 01:09:25
書くとき、プロンプトは、% が分かりやすいと思う
# はコメントみたいだし、$ は変数と紛らわしい
0155名無しさん@お腹いっぱい。2006/02/02(木) 04:09:38
ok ■
0156名無しさん@お腹いっぱい。2006/02/02(木) 04:43:51
how many files ?
0157名無しさん@お腹いっぱい。2006/02/02(木) 06:00:56
plan9のは%だよ。
0158名無しさん@お腹いっぱい。2006/02/02(木) 09:01:45
シェルを書いている
スーパーハッカーが集うスレッドはここですか?
0159名無しさん@お腹いっぱい。2006/02/02(木) 09:59:11
いやシェルって普通のCUIのプログラムだし、ハッカーとかそんな凄いもんじゃないし
0160名無しさん@お腹いっぱい。2006/02/02(木) 10:05:14
ポカーン、というAAが辞書に有ったら、今それを使っていたと思う
0161名無しさん@お腹いっぱい。2006/02/02(木) 11:29:17
>>159
シェルを書くには結構な腕が必要なんじゃないか?
おれは、シェルスクリプトは書けてもシェルは書けん。
0162名無しさん@お腹いっぱい。2006/02/02(木) 11:56:11
>>161
システムプログラムの初歩なんで、
やればできるレベルだと思われ。

動かすだけなら結構簡単なので、
大学での演習レベル。
0163名無しさん@お腹いっぱい。2006/02/02(木) 12:00:11
車輪の大発明
0164名無しさん@お腹いっぱい。2006/02/02(木) 12:14:17
リダイレクトとかバックグラウンド程度だけなら簡単だろうけど、
パイプとか、サブシェルとか、ジョブコンとか、環境変数とか、
基本的とはいえかなりのシステムコールの利用経験と、パーザの知識がいるかと。
0165名無しさん@お腹いっぱい。2006/02/02(木) 12:19:32
> パイプとか、サブシェルとか、環境変数とか、

これは簡単だろ。

> ジョブコンとか、

とCtrl-Cでシグナル喰った時のシェルの挙動辺りは
ちゃんとPOSIX規格その他を読んでないと難しいものがある。
少なくともマルチプラットーフォームは無理。

■ このスレッドは過去ログ倉庫に格納されています