1 名前:1様 [2009/04/03(金) 22:17:43 ID:0qFlvOW9] UNIX板のスレを見ている方も多数おられるかと思いますが、 まあそれはそれとして、BASHウゼーとか言われる心配なく 平和にLINUX的スクリプト談義しましょうよ。 初めての自作スクリプト、自信ないから見てください。な初心者から トリッキーな技を駆使した作品を披露したい、蘊蓄を語りたい上級者まで いろいろな人に参加して頂けると嬉しいです。 perlやらPythonやらの話が混ざっても良いんでない? Part4 : pc11.2ch.net/test/read.cgi/linux/1210999497/ Part3 : pc11.2ch.net/test/read.cgi/linux/1184077033/ Part2 : pc11.2ch.net/test/read.cgi/linux/1154578200/ Part1 : pc8.2ch.net/test/read.cgi/linux/1121994321/ >>2-5 あたりに色々と。
34 名前:login:Penguin mailto:sage [2009/04/18(土) 16:08:22 ID:Fbv8BZKW] for i in `seq 100`; do echo $i; done 俺この方法好き
35 名前:login:Penguin [2009/04/18(土) 16:40:49 ID:h9pcedkY] for i in `seq -w 100`; do echo $i; done の方が好き
36 名前:login:Penguin mailto:sage [2009/04/20(月) 18:07:25 ID:nHdRbS/v] もまいら、なかなかうまいな
37 名前:login:Penguin [2009/04/24(金) 12:57:30 ID:b7e2t/yg] trapについて教えてください ------hoge.sh---- #!/bin/bash trap '' INT sleep 1 echo hoge sleep 1 echo hoge ----------------- 上記のスクリプトを実行し、Ctrl+c を押しっぱなし にしても正常に最後までechoし終了するのですが、最後にscpをいれると固まります ------hoge.sh---- #!/bin/bash trap '' INT sleep 1 echo hoge sleep 1 echo hoge scp hostname:file1 ./file2 ----------------- これの回避方法を教えてください。
38 名前:login:Penguin [2009/04/25(土) 18:13:43 ID:xpy/PYPF BE:1185862267-S★(614436)] ファイル名の一括変換なんかができたらなぁと思っています。 まいにちフランス語_4月13日放送分.mp3 → FR20090413.mp3 まいにちフランス語_4月14日放送分.mp3 → FR20090414.mp3 まいにちフランス語_4月15日放送分.mp3 → FR20090415.mp3 まいにちフランス語_4月16日放送分.mp3 → FR20090416.mp3 まいにちフランス語_4月17日放送分.mp3 → FR20090417.mp3 というルールでファイル名を一括変換したいのですが、 シェル・スクリプトでどう書けばいいのかさっぱり分かりません。 どなたかお助け願えませんでしょうか?よろしくお願いいたします。
39 名前:login:Penguin mailto:sage [2009/04/25(土) 19:52:53 ID:kvdAirHU] >>38 見習い中の者だけど、直接、mvするのは書けた でも cp rm -iとしたいけど、適当な記述が思いつかない 雨がやんだっぽいので買い出しに行ってきます
40 名前:login:Penguin mailto:sage [2009/04/25(土) 19:58:44 ID:0GMAGDVv] >>38 自己レスです。 まいにちフランス語_4月13日放送分.mp3 → FR20090413.mp3 のうち、ttp://tinyurl.com/czxw5g を参考に、 まいにちフランス語_4月13日放送分.mp3 → FR2009413.mp3 までは自力でなんとか出来ました。4月を04と2桁にするのだけが分かりません。 現在のスクリプトは以下です。 for base_name in `find ./ -name "まいにちフランス語_*"` do rename=`(echo ${base_name} | sed 's/まいにちフランス語_/FR2009/g' | sed 's/月//g' | sed 's/日放送分//g')` mv ${base_name} ${rename} done あとどう直せば希望通りの動作を実現できるのでしょうか。どなたかお助け下さい。お願いいたします。
41 名前:login:Penguin mailto:sage [2009/04/25(土) 20:39:12 ID:KQhyDGwp] sed -e 's/^[^0-9]*/FR2009 /' -e 's/月/ /' -e 's/日放送分/ /' | awk '{printf"%s%02d%02d%s",$1,$2,$3,$4}'
42 名前:login:Penguin mailto:sage [2009/04/25(土) 22:21:23 ID:gHQ99EuD] >>40 回答じゃないけど、なんか元ファイルに想定外なのがあって上書き、とかを避けるため、 mvじゃなくって同一driveの別ディレクトリにハードリンクのがオレは好み。 個数とか確認後に元を消すだけだし、容量的にも×2必要ってわけじゃねぇし。
43 名前:login:Penguin mailto:sage [2009/04/25(土) 22:37:34 ID:kvdAirHU] >>42 プログラムエラーがあるかもしれないぐらいの気合いの入っていないプログラムだと ファイル操作に慣れていないと結構大変だね mvじゃなくcpして、元ファイルは/tmpに移しておけばいいんかな /tmpについてそこまで詳しく知らないけど、ある日数とtmpの容量がオーバーしたら 勝手に消えるんでしょ? dfでマイナス表記をみた記憶があった気もするけど HDDも安くなったから、事前にmkdir ~/tmpと作っておいて、ゴミ箱的に使うのがいい感じなのかな
44 名前:login:Penguin mailto:sage [2009/04/25(土) 22:46:19 ID:U0RjRCaW] >/tmpについてそこまで詳しく知らないけど、ある日数とtmpの容量がオーバーしたら >勝手に消えるんでしょ? (´・ω・`)・・・
45 名前:login:Penguin mailto:sage [2009/04/25(土) 23:29:31 ID:z0Vi8pSt] >>38 ,40 #!/bin/sh find ./ -name 'まいにちフランス語_*' | while read line do mv -i "$line" `echo "$line" | sed \ -e 's/\([^0-9]\)\([0-9]月\)/\10\2/' \ -e 's/\([^0-9]\)\([0-9]日\)/\10\2/' \ -e 's/まいにちフランス語_/FR2009/' \ -e 's/月//;s/日放送分//'` done
46 名前:login:Penguin mailto:sage [2009/04/26(日) 16:11:48 ID:NYZwuLsV] $ ls "*" ls: cannot access *: そのようなファイルやディレクトリはありません これって展開されないんだ?
47 名前:login:Penguin mailto:sage [2009/04/26(日) 16:46:19 ID:/3VhflV8] >>46 > $ ls "*" それだと$ ls \*と同じじゃないの? $ ls *なら展開される 試しに$ echo "foobar" > "*"とすると*というファイル名できるんだね また$ echo "foobar" > "2*2=4"でもちゃんとできる $ echo "hoge" > "2+2=4"としておいて $ ls 2*2=4だと、2*2=4 2+2=4の二つが出てきますが まあ、そういうことなんでしょ ファイル名はShellにとって特殊文字の*?は使わないほうがいいんだっけ? $ rm *とやったら、どうなるんだろ こわくてできない
48 名前:login:Penguin mailto:sage [2009/04/26(日) 17:51:05 ID:NYZwuLsV] ダブルクォートだと展開されるような気がしてたけど 勘違いか、そっか。 > ファイル名はShellにとって特殊文字の*?は使わないほうがいいんだっけ? 頭に '-' とかもコマンドによってはオプションとして識別するからね。 $ date > --help $ cat '--help' 使用法: cat [オプション]... [ファイル]... … $ cat -- '--help' 2009年 4月 26日 日曜日 17:49:26 JST
49 名前:login:Penguin mailto:sage [2009/04/26(日) 18:15:04 ID:6AxKKceD] >>46 ttp://www.linux.or.jp/JM/html/GNU_bash/man1/bash.1.html#lbBE > パターンマッチング > 特殊パターン文字をその文字そのものにマッチさせるためには、クォートしなければなりません。
50 名前:login:Penguin mailto:sage [2009/04/26(日) 18:18:28 ID:cQuTU2RN] ダブルクォート中で有効なメタ文字は「$\`」
51 名前:login:Penguin mailto:sage [2009/04/26(日) 18:33:49 ID:/3VhflV8] >>48 対話インタプリタ(コマンドライン)のときとシェルスクリプトを実行するときに挙動に違いがあるってことかな echo `*`だと二回出るのは、なんなんだろ うーん $ cat foo.sh echo '[command] *' echo `*` echo '[command] ls *' echo `ls *` echo '[command] ls "*"' echo `ls "*"` echo '[command single-qoate] ls *' echo `ls '*'` echo '[command] ls \*' echo `ls \*` > > ファイル名はShellにとって特殊文字の*?は使わないほうがいいんだっけ? > 頭に '-' とかもコマンドによってはオプションとして識別するからね。 そうだね 他人が作ったプログラムを動かすときに'-'は予期しにくい挙動しそうだから、控えたほうが良さそうだけど でも、'*?'をファイル名に使っても良さそうに思えるなあ 実際、どうなんだろ
52 名前:login:Penguin mailto:sage [2009/04/26(日) 19:20:08 ID:4i92v2TV] echoと一口に言っても coreutilsのechoやbashのビルトインecho dashやzshのビルトインechoは挙動が違う
53 名前:login:Penguin mailto:sage [2009/04/26(日) 19:46:21 ID:/3VhflV8] >>52 >・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。 > bash/zsh/ksh/ashなどに依存する場合は明示しましょう。 > Linuxユーザは/bin/shの正体がbashなので特に注意。 とあるわけだし zsh, dashは関係ないんじゃないの? Linux板のスレというのもあってLinux依存に関することは、多少寛容なんでしょうけど まあ、そういう自分はLinuxなんであれですが あと「特に注意」とあるけど、環境明示なしの質問でsh関連の質問に答えるためにどういう環境があればいいの? ここのスレと@UNIXスレの質問の答えになる程度の妥協した現実的な環境として 仮想OSなしでLinux上で整えることができるんでしょうか? 純正shと聞くOpenSolarisのshでちゃんと動けばいいの? FreeBSD, OpenBSDでは満たせないんでしょうか?
54 名前:login:Penguin mailto:sage [2009/04/26(日) 20:05:49 ID:z35DirHv] (意図通りに)動けば正義
55 名前:login:Penguin mailto:sage [2009/04/26(日) 20:13:36 ID:IdxLO+dc] >>53 > >・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。 > > bash/zsh/ksh/ashなどに依存する場合は明示しましょう。 > > Linuxユーザは/bin/shの正体がbashなので特に注意。 > とあるわけだし ID:zPRKkUO8 が UNIX 板と間違えて貼ったテンプレを持ち出して なにがしたいの?
56 名前:login:Penguin [2009/04/27(月) 22:45:23 ID:zIUJH1+o] >>41 どうもありがとうございます。レスが遅くなって申し訳ありません。 大変長期に渡るアク禁を喰らっている者で、元の >>40 の質問もこの投稿も、 どちらも代行スレ経由で投稿してもらっております。 >>41 で教えていただいたスクリプトで確かに希望通りの動きをするのですが、 sed の部分も awk の部分も、どちらもどういう操作を命令しているのか、 イマイチ理解が出来ておりません。スクリプトの内容を、 簡単に解説していただけませんでしょうか? >>45 さんもありがとうございます。
57 名前:login:Penguin mailto:sage [2009/04/27(月) 22:52:48 ID:doFZwSgR] >スクリプトの内容を、 >簡単に解説していただけませんでしょうか? そりは、あーたの仕事ですがな。 調べて解らん部分を訊かんと。
58 名前:login:Penguin mailto:sage [2009/04/28(火) 01:07:02 ID:2xnVN10b] >>41 はどこも難しいとこないよ。 基本的なことしかしてない。
59 名前:login:Penguin mailto:sage [2009/04/28(火) 01:12:22 ID:7KxLupvN] awkは必要? awk '{printf"%s%02d%02d%s",$1,$2,$3,$4}'のようにprintf文だけ理解していればいい?
60 名前:login:Penguin mailto:sage [2009/04/28(火) 03:06:53 ID:zC1qen3j] そんなことを他人に聞くようなら 初めからrubyやpythonなんかで書きなさい
61 名前:login:Penguin mailto:sage [2009/04/28(火) 12:10:33 ID:2xnVN10b] >>59 意味わかんないけど 目的が達成できれば何でもいいんじゃね。
62 名前:login:Penguin [2009/05/04(月) 01:16:30 ID:Z02vxYwi] ∩゜∀゜∩
63 名前:login:Penguin mailto:sage [2009/05/08(金) 16:39:20 ID:/GOSAdyI] foo | bar と foo | \ bar って違いあるの?
64 名前:login:Penguin mailto:sage [2009/05/08(金) 20:18:40 ID:3ejrnY18] バックスラッシュ可愛いよ | \ァ | \ァ・・・
65 名前:login:Penguin mailto:sage [2009/05/09(土) 01:08:35 ID:unYbYLqh] >>63 の上のように書けるなんて、俺ぁ始めて知ったよ。
66 名前:login:Penguin mailto:sage [2009/05/09(土) 02:44:39 ID:R823USQU] >>56 オライリーの詳説正規表現(ふくろう本)とsed&awk(めがねざる本)を おまえの金で買って嫁。 まずはそこからだ。 >>57 が言うように、まずは勉強してから聞いた方が良い。
67 名前:login:Penguin mailto:sage [2009/05/10(日) 23:02:29 ID:QXYPExpJ] 命題=USB接続のストレージを全てumountする(サスペンド/ハイバネのハンドラで使う) ls -l /dev/disk/by-path/ | while read DEV; do DEV=${DEV#*usb*/*/} case $DEV in sd?[0-9]) echo "umount /dev/$DEV" ;; esac done どんなもんでしょ? もっと賢い方法ありますか? 諸兄に採点願いたい
68 名前:login:Penguin mailto:sage [2009/05/10(日) 23:09:18 ID:6t5VOjiz] >>67 目線が高い
69 名前:login:Penguin mailto:sage [2009/05/11(月) 07:09:17 ID:0Zy7nDFj] >>67 SATAのHDDもアンマウントされるよね?どうすんの??
70 名前:login:Penguin mailto:sage [2009/05/11(月) 17:10:02 ID:fWM1Begt] >>69 DEV=${DEV#*usb*/*/} *usb*
71 名前:login:Penguin [2009/05/12(火) 23:16:06 ID:6EJpjlI0] シェルで出来るかなと考えず、 最初からrubyやperlでやっちゃう人も多いですよね。 現実問題として、ファイル処理やテキスト処理以外の大多数は 他の言語でやったほうが楽ですよね。 結局、シェルスクリプトってどんな時に便利なんですか?
72 名前:login:Penguin mailto:sage [2009/05/12(火) 23:20:01 ID:D0y0zjLK] >>71 パイプでガスガスコマンド繋ぎたいとき。 関数型言語のような気持ちよさ。
73 名前:login:Penguin mailto:sage [2009/05/13(水) 19:34:16 ID:V3jwSh7A] >>71 ファイル処理やテキスト処理のときに便利だと、自分で言うとるやないか。
74 名前:login:Penguin mailto:sage [2009/05/13(水) 22:24:14 ID:u0Eoo5tc] たとえばサスペンド/ハイバネのハンドラは一応クリティカルなので最小限で済ましたい bashオンリー、sedやawkも控える サスペンド/ハイバネ自体もbashをフロントエンドにして実装されてる
75 名前:login:Penguin mailto:sage [2009/05/14(木) 19:14:39 ID:VFAnBpU/] 旧いノートにCentOSを入れて酷使してるんだが もっと愛が必要だと思ったので作った。 もっと良い書き方あるかな #!/bin/sh THROTTLING=/proc/acpi/processor/CPU0/throttling TEMPERATURE=/proc/acpi/thermal_zone/THM0/temperature STATE_COUNT=8 THRESHOLD_TEMPS='75 70 65 63 62 61 60 0' get_temperature() { sed -e 's/[^0-9]*//g' < $TEMPERATURE} set_state() { echo -n $1 > $THROTTLING } start() { while(:); do sleep 2 current_temperature=`get_temperature` i=$STATE_COUNT for threshold_temp in $THRESHOLD_TEMPS; do let i-- if (( $threshold_temp < $current_temperature )); then set_state $i break fi done done } #daemonにするにはデタッチが必要らしい start &
76 名前:login:Penguin [2009/05/21(木) 14:21:38 ID:8Ph6oUED] 時刻を利用したものを書きたいんですがどうもよくわかりません。 dateとgrepを利用するのはなんとなくわかるんですがさっぱりです。 <例>引数として与えた時刻になったときに‘wake up!’と表示する どなたかお助けいただけませんでしょうか。お願いします。
77 名前:76 mailto:sage [2009/05/21(木) 17:13:53 ID:ZE+yaPSj] 大学から書き込んでます。 うちの教授がこのスレを見ているらしいです。 このスレの回答を課題として提出したら単位をくれないと思うので 質問を取り消します。
78 名前:login:Penguin mailto:sage [2009/05/21(木) 17:14:26 ID:8WrmPGB1] そうかそうか
79 名前:login:Penguin mailto:sage [2009/05/21(木) 17:23:51 ID:Ed3fgcAs] >>77 wikipediaでshのチュートリアルがあるんで、それ読めばだいたいのことは解決すると思う あとmanを読む
80 名前:76 mailto:sage [2009/05/21(木) 17:28:06 ID:ZE+yaPSj] >>79 ありがとう。でも読むのめんどくさいです。退散します
81 名前:login:Penguin [2009/05/21(木) 18:06:18 ID:YOkJVZm9] >>76 =77=80 氏ね
82 名前:login:Penguin mailto:sage [2009/05/21(木) 18:19:28 ID:Ed3fgcAs] >>81 おれも思った
83 名前:login:Penguin [2009/05/21(木) 18:33:46 ID:X//3znla] >>76 です。 今度はネットカフェから書き込んでいます。 >>77 , >>80 は僕ではありません。 信じてください ><
84 名前:login:Penguin mailto:sage [2009/05/21(木) 18:41:39 ID:W9MVWV0e] イエーイ、教授見てる〜?
85 名前:login:Penguin mailto:sage [2009/05/21(木) 18:45:00 ID:50DHcUbO] じつを言うと>>76 は俺 信じてくれなくても良い
86 名前:login:Penguin [2009/05/28(木) 23:08:08 ID:MG6SQpHS] ディレクトリ構造を保持して特定のファイルをコピーするにはどうすれば良いでしょうか? cp -a a/b/c/d.txt e/ とやると e/d.txt となってしまいます。 e/a/b/c/d.txt となって欲しいのですが。
87 名前:login:Penguin mailto:sage [2009/05/28(木) 23:14:48 ID:OYPHtyPP] >>86 tar cvz a/b/c/d.txt | tar xvzf -C e/ -
88 名前:86 mailto:sage [2009/05/28(木) 23:50:32 ID:MG6SQpHS] >>87 Thx!
89 名前:login:Penguin mailto:sage [2009/05/29(金) 00:01:04 ID:rPFmiLnc] 一方ロシアは--parentsを使った
90 名前:login:Penguin mailto:sage [2009/05/29(金) 01:25:22 ID:H2hlYKbU] 出遅れた echo a/b/c/d.txt|cpio -p e
91 名前:login:Penguin mailto:sage [2009/05/29(金) 20:09:43 ID:ZTU2Uga5] rsync -aR a/b/c/d.txt e/
92 名前:login:Penguin mailto:sage [2009/06/15(月) 15:03:52 ID:An1qKLCY] くだスレから移動してきました。 bashで (for i in a b c d; do X done) | A | xargs B ; C; のような処理を行ったとき、B の処理をまだやっているうちに Cの処理に移ってしまうのですが、Bの処理が終わるのを 待つようにするにはどのようにすればよいのでしょうか? これまではそんな動作はありえない思っていたのですが、Cで ps で確認すると、B がまだ動いています。 もしバグだとすると、bash,libc,kernelのどのあたりになるでしょうか。 その確認方法はなにかありますか?
93 名前:login:Penguin mailto:sage [2009/06/15(月) 15:51:41 ID:FRq6RhHc] >>92 bashが待つのはBじゃなくてxargsの終了だからその辺でなんかあるのかもしれんが、 とりあえずその状態のときの各プロセスの親プロセス番号を確認したいところだな。
94 名前:login:Penguin mailto:sage [2009/06/15(月) 17:00:15 ID:An1qKLCY] >>93 ありがとうございます。Bの親はinitになってました。 xargsが勝手に終了してしまうのが問題みたいですね。 その辺調べてみます。
95 名前:login:Penguin [2009/06/15(月) 20:49:11 ID:oAD3AKfh] 初歩的な質問ですみません。readコマンドについてです。 #!/bin/bash ls * | while read result do echo $result done と書くとカレントディレクトリの内容がechoで表示されます。 これを ls * | read result ; echo $result と書いても同じように出力されそうな気がするのですが、 空行がでて終わってしまいます。 何が違うのでしょうか?
96 名前:login:Penguin mailto:sage [2009/06/15(月) 22:25:53 ID:FILO8IMv] 後者は1行しか読んでないんじゃない?
97 名前:login:Penguin mailto:sage [2009/06/16(火) 01:01:11 ID:nzUvvcuW] >>95 www.faqs.org/faqs/unix-faq/faq/part3/section-8.html
98 名前:login:Penguin mailto:sage [2009/06/18(木) 15:45:23 ID:dQ4OojSv] #!/bin/sh for FILE in "$@" do if [ -f $FILE ]; then echo "$FILE is a file" fi done だと、$FILE変数には、引数の記述により、相対パスも絶対パスもありえます。 $FILE変数を絶対パスに変換する方法はあるでしょうか?
99 名前:login:Penguin mailto:sage [2009/06/18(木) 15:53:07 ID:s3sHtQVu] >>98 あれば realpath
100 名前:login:Penguin mailto:sage [2009/06/18(木) 15:59:02 ID:dQ4OojSv] >>99 ないっす。
101 名前:login:Penguin [2009/06/18(木) 16:21:59 ID:0zcffroC] >>98 readlink -f
102 名前:login:Penguin mailto:sage [2009/06/18(木) 16:44:51 ID:dQ4OojSv] >>101 古いLinuxでreadlinkはシンボリックリンクのときのみ動作でした。 #!/bin/sh W_PWD=`pwd` for FILE in "$@" do if [ -f $FILE ]; then cd $W_PWD abpath=$(cd $(dirname $FILE) && pwd)/$(basename $FILE) echo "$abpath is a file" fi done しょうがないので、プログラムしてみた。 これで、$abpath に絶対パスが入るようになった。 シェルスクリプト暦浅いのだが、ベテランから見て問題なさそう?
103 名前:login:Penguin mailto:sage [2009/06/18(木) 17:05:37 ID:aPpB1FUW] kshだとrealpathはビルトインなのね
104 名前:login:Penguin mailto:sage [2009/06/18(木) 17:09:36 ID:aPpB1FUW] 無かったスマソ
105 名前:login:Penguin mailto:sage [2009/06/18(木) 17:23:14 ID:dQ4OojSv] #!/bin/sh for FILE in "$@" do if [ -f $FILE ]; then abpath=$(cd $(dirname $FILE) && pwd)/$(basename $FILE) echo "$abpath is a file" fi done これでいいんだ。
106 名前:login:Penguin mailto:sage [2009/06/18(木) 17:49:22 ID:S07Tjv1V] いや、ファイル名に空白あったらアウト 変数は基本""で囲む お兄さんとの約束だ
107 名前:login:Penguin mailto:sage [2009/06/18(木) 18:59:36 ID:dQ4OojSv] なるほど。 ありがとうございました。
108 名前:login:Penguin mailto:sage [2009/06/18(木) 19:18:06 ID:dQ4OojSv] おっと、ひとつ質問良いですか? abpath=$(cd $(dirname $FILE) && pwd)/$(basename $FILE) この後、カレントディレクトリ変わらないのはなぜですか?
109 名前:login:Penguin mailto:sage [2009/06/18(木) 20:19:19 ID:S07Tjv1V] cdしているのはサブシェルだから
110 名前:login:Penguin mailto:sage [2009/06/18(木) 20:26:28 ID:dQ4OojSv] 調べてました。 ()の中はサブシェルによって実行されるんですね。
111 名前:login:Penguin mailto:sage [2009/06/18(木) 22:56:25 ID:dQ4OojSv] >>98 です。 諸兄のおかげで、無事目的通りのスクリプトが組めました。 今後かなり作業効率が向上します。 感謝
112 名前:login:Penguin mailto:sage [2009/06/23(火) 22:19:47 ID:c8G3nrDU] bashの勉強のために、JMの該当するmanページをw3mで見るスクリプトを書いています。 ダブルクォーテーションの使い方など、細かいところも添削お願いできますでしょうか。 #!/bin/bash # @(#) man on linux.or.jp # COMMAND=`which w3m` PAGE= SECTION= SECT=("on" "on" "on" "on" "on" "on" "on" "on") SECTURL= BASEURL="search.linux.or.jp/cgi-bin/JM/man.cgi? " URL= if [ \( ! -e "$COMMAND" \) -o \( ! -x "$COMMAND" \) ]; then echo "not installed w3m" exit 1 fi while getopts S:h OPT do case $OPT in S) SECT=("off" "off" "off" "off" "off" "off" "off" "off") SECTION=$(expr $OPTARG - 1 2>/dev/null) if [ $? = 2 ]; then echo "secion number is invalid. exit." exit 2 fi SECT[$SECTION]="on";; h | ?) printf "Usage: %s: [-S secion] page\n" $0 exit 2;; esac done
113 名前:112 mailto:sage [2009/06/23(火) 22:21:09 ID:c8G3nrDU] shift $(($OPTIND - 1)) PAGE="$1" if [ x$PAGE == x ]; then echo "What manual page do you want?" exit 1 fi i=1 for onoff in ${SECT[@]}; do if [ x"$onoff" = x"on" ]; then SECTURL="$SECTURL"'&Sec'"$i"'='"$onoff" fi i=$(expr $i + 1) done URL="${BASEURL}"'Pagename='"${PAGE}"'&submit=Search%21'$SECTURL $COMMAND "$URL" よろしくお願いします。
114 名前:login:Penguin mailto:sage [2009/06/23(火) 23:37:11 ID:iNYrdW4A] 120点
115 名前:login:Penguin mailto:sage [2009/06/23(火) 23:41:00 ID:9feAjnJ4] bash限定(shで使わない)なら、外部コマンドよりbashの内部コマンドを使った方が速くなりますよ。 i=$(expr $i + 1) → ((i++)) とか。
116 名前:login:Penguin mailto:sage [2009/06/24(水) 00:57:03 ID:23DWLrsu] for (( expr1 ; expr2 ; expr3 )) ; do list ; done
117 名前:112 mailto:sage [2009/06/24(水) 01:41:57 ID:B7cQg4Om] >>114-116 ありがとうございます。 早速、(( ))を使って書き直しました。 10万までインクリメントしていくだけのスクリプトで 速度を計測してみたのですが、全然違うのですね! ./tmp.sh 4.64s user 0.10s system 99% cpu 4.788 total ./tmp.sh 92.07s user 111.03s system 96% cpu 3:31.31 total exprの方(下の方)が遅いです。 それと一貫性が無いように感じたので、1行目のwhichの文を$(which w3m)としました。 また、bashを見てみると[[ ]]という組み込みの評価式があったので、 if [ \( ! -e "$COMMAND" \) -o \( ! -x "$COMMAND" \) ]; then という部分を変更しました。 if [[ ( ! -e "$COMMAND" ) || ( ! -x "$COMMAND" ) ]]; then これも計測してみたら、若干ですが[[ ]]の方が速かったです。 >>116 で挙げられた記法を使用したことで変数が1つ減りました。 こんな感じになりました。 #!/bin/bash # @(#) man on linux.or.jp # COMMAND=$(which w3m) PAGE= SECTION= SECT=("on" "on" "on" "on" "on" "on" "on" "on") SECTURL= BASEURL="search.linux.or.jp/cgi-bin/JM/man.cgi? " URL= if [[ ( ! -e "$COMMAND" ) || ( ! -x "$COMMAND" ) ]]; then echo "not installed w3m" exit 1 fi
118 名前:112 mailto:sage [2009/06/24(水) 01:45:08 ID:B7cQg4Om] while getopts S:h OPT do case $OPT in S) SECT=("off" "off" "off" "off" "off" "off" "off" "off") SECTION=$(expr $OPTARG - 1 2>/dev/null) if [[ $? == 2 ]]; then echo "secion number is invalid. exit." exit 2 fi SECT[$SECTION]="on";; h | ?) printf "Usage: %s: [-S secion] page\n" $0 exit 2;; esac done shift $(($OPTIND - 1)) PAGE="$1" if [[ x$PAGE == x ]]; then echo "What manual page do you want?" exit 1 fi for ((i=1; i<${#SECT[@]}; i++)) do if [[ x"${SECT[i-1]}" = x"on" ]]; then SECTURL="$SECTURL"'&Sec'"$i"'='"${SECT[$((i-1))]}" fi done URL="${BASEURL}"'Pagename='"${PAGE}"'&submit=Search%21'"$SECTURL" $COMMAND "$URL" 変数が空の場合だったらとかスペースが含まれていたらとか、その辺りをよく理解しておらず、 とりあえずダブルクォートしてたりするのですが、無駄な部分があったりしますでしょうか。 細かい部分でも構いませんので、訂正していただけると嬉しいです。長文失礼しました。
119 名前:login:Penguin mailto:sage [2009/06/24(水) 02:04:47 ID:aKYWDWvt] そのままでも全然いいと思うよ(^_^)
120 名前:login:Penguin mailto:sage [2009/06/24(水) 08:42:54 ID:CrOO7ztU] COMMAND=$(which w3m) は COMMAND=$(command -v w3m) で外部コマンドはサヨウナラ SECTION=$(expr $OPTARG - 1 2>/dev/null) if [[ $? == 2 ]]; then echo "secion number is invalid. exit." exit 2 fi も let SECTION="OPTARG - 1" 2>/dev/null case $SECTION in [0-7]) :;; *) echo "secion number is invalid. exit." exit 1;; esac で外部コマンドはサヨウナラ if [[ ( ! -e "$COMMAND" ) || ( ! -x "$COMMAND" ) ]]; then は if [[ ! -x "$COMMAND" ]]; then で十分だと思うが
121 名前:login:Penguin mailto:sage [2009/06/24(水) 09:19:46 ID:aKYWDWvt] >>120 > COMMAND=$(command -v w3m) w3mがaliasされてたらwhichと結果がかわるよ
122 名前:login:Penguin mailto:sage [2009/06/24(水) 09:37:52 ID:BWmtmrUC] bashってtypeないの?
123 名前:112 mailto:sage [2009/06/24(水) 13:57:32 ID:qAybS9Ki] >119-122 レスありがとうございます。 今回作ったスクリプトでJMのbashを見ながら、こんな風にしてみました。 INTERRUPT=0 COMMAND=$( if [[ $(builtin type -t w3m) != "file" ]]; then echo "may not installed w3m" >&2 INTERRUPT=1 exit 1 fi IFS=' ' set $(builtin type w3m) echo $3 ) if [[ $INTERRUPT == 1 ]]; then exit 1 fi unset INTERRUPT こんなトリッキーなものを書いたのは初めてですが、これでエイリアスの場合も大丈夫でしょうか? # .bashrcにalias w3m='ls -l'と書いてみたのですが、 # type -tの結果がaliasになりませんでした。何故なのでしょうか... letは目から鱗でした。 「数字じゃない文字列が入力された時」(例えば"aaa"とか) をキャッチするために$?==2を使いたかったので、敢えて$(( ))を使えず、$( )を使っていました。 ですが、「セクション番号以外が入力された時」とまとめてしまえば、もっと安全ですね。 一貫性持たせるためにletを使わずにSECTION=$((OPTARG - 1));case云々...esac; とできるか、と思いましたが、letも数字から始まっている文字列("3aa"とか) だったりすると標準エラーに吐くのですね。便利です。let。 ファイルテストの部分は仰る通りです。わたしの勘違いです。 ご意見ありがとうございます。
124 名前:login:Penguin mailto:sage [2009/06/24(水) 14:40:30 ID:BWmtmrUC] >>123 そんな面倒なことはせんでもええ if ! type -P w3m >/dev/null; then echo '(# ゚Д゚)' fi
125 名前:112 mailto:sage [2009/06/24(水) 17:05:52 ID:qAybS9Ki] 何度もすみません。 Pオプションが、原文のman bashにしか書いようで、 書いてある英語がよく分からないのですけれど (-_-A; こういうことが書いてあるんでしょうか? pオプションは、エイリアスとか関数があったら何も返さないけれど、 そういう時でもPオプションは、ファイルだけを対象にしてそのパスを表示する。 間違ってたら恥ずかしいです。 if ! COMMAND=$(builtin type -P w3m 2> /dev/null); then if [[ ! -x $COMMAND ]]; then echo "not installed w3m" >&2 exit 1 fi fi ファイルテストと合わせて、COMMANDを取得するところはこんな感じになりました。 他は、>>117 ,118と同じです。
126 名前:login:Penguin mailto:sage [2009/06/24(水) 19:01:09 ID:h5ARTQfu] aliasにするには同シェルスクリプトファイル内に書くか.を使うか 例えばこう shopt -s expand_aliases . ~/.bashrc type -t w3m SECTURL="$SECTURL"'&Sec'"$i"'='"${SECT[$((i-1))]}" みたいなのは SECTURL="$SECTURL"\&Sec"$i"\="${SECT[$((i - 1))]}" とエスケープ使ったほうが読みやすいかもな
127 名前:login:Penguin mailto:sage [2009/06/24(水) 19:29:28 ID:w4EkT5LC] >>126 俺は関数化して環境登録することが多いです。 function w3m() { ls -l } export -f w3m
128 名前:login:Penguin mailto:sage [2009/06/26(金) 01:44:08 ID:+M5S3VDp] 質問です。前処理をして、 www.youtube.com/get_video?video_id=-AKQ6CUJa90&t=vjVQa1PpcFP1kWNkoPQ7xks6cfYQ2Ttsd-nzkuvfQsw=&el=detailpage&ps= のようなURLを列挙したファイル(you.txt)を用意してあり、 yt=$(cat you.txt | sed -e "s/&t.*//g; s/^.*video_id=//g") && \ wget -O $yt.flv -c -i you.txt で動作させた場合、 思惑通り一個目は、-AKQ6CUJa90.flv というファイル名で取ってこれるのですが、 二個目以降はファイル名の抽出が働かず、 ローカルに保存されるのは同名のファイル名となってしまいます。 どのようにすれば思惑通りファイルを取ってこれるのでしょうか?
129 名前:login:Penguin mailto:sage [2009/06/26(金) 02:55:31 ID:5uTursO/] for
130 名前:login:Penguin mailto:sage [2009/06/26(金) 03:43:24 ID:5uTursO/] for youtube_url in `cat you.txt`; do wget -c -O "`echo "$youtube_url" | sed 's/video_id=\(.*\)&t\1/g'`.flv" "$youtube_url" sleep 5 done でどうでしょうか
131 名前:login:Penguin mailto:sage [2009/06/26(金) 06:18:01 ID:3RE4KePV] for youtube_url in `cat you.txt`; do wget -c -O "`echo "$youtube_url" | sed 's/^.*video_id=\(.*\)&t.*$/\1/'`.flv" "$youtube_url" sleep 5 done …でどうでしょうか(^_^;)
132 名前:login:Penguin mailto:sage [2009/06/26(金) 06:31:57 ID:3RE4KePV] id変わってる…(^_^;;)
133 名前:128 mailto:sage [2009/06/26(金) 11:30:36 ID:WtRHx5He] >>130 , 131 お知恵を元にして、目的を果たせました。ありがとうございます。 感謝しています。 なお、自分の書き込んだ内容でも、いちおうファイル名の抽出には成功する模様? 試行錯誤してみるのも、面白いですね。ではでは。
134 名前:login:Penguin [2009/06/30(火) 11:41:15 ID:Iil9pev3] 質問です。 現在、kshを使用してテストをしているのですが、 ステップが多すぎて(1k↑)カバレッジを求められてます。 カバレッジツールが無いかグーグル先生に聞いてみましたが 全く引っかからなく・・・ シェルのカバレッジを求めている人はどんな方法で求めていますか?