シェルスクリプト総合 その9
■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。
2007/08/15(水) 07:25:02スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>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 でトレースしましょう。
前スレ
シェルスクリプト総合 その8
http://pc11.2ch.net/test/read.cgi/unix/1171517324/
004140
2007/09/08(土) 02:14:11googleのI'm feeling luckyにかけたい対象キーワードは複数あります。
それらの対象キーワードのgoogleランキングの変遷を知りたいという
わけです。
質問は多分二つに切り分け可能で、I'm feeling luckyによるリダイレクトジャンプを
wgetはフォローできるかというのが一つ、もう一つが英数字以外の文字列によって
構成されている
http://www.google.com/search?q=2ch
といったページをwgetでどうやって取得するか、という問題です。後者が出来れば
一応ソースを取得して検索順位第一位のサイトアドレスを取得することは
何とか出来ます。
0042名無しさん@お腹いっぱい。
2007/09/08(土) 06:20:400043名無しさん@お腹いっぱい。
2007/09/08(土) 10:12:00なんで犬板で聞かないのだ?
0044名無しさん@お腹いっぱい。
2007/09/08(土) 11:15:400045名無しさん@お腹いっぱい。
2007/09/08(土) 18:08:000046名無しさん@お腹いっぱい。
2007/09/08(土) 18:10:33cshやzshより圧倒的に利用者が多いしbashが標準みたいなもんなのに。
0047名無しさん@お腹いっぱい。
2007/09/08(土) 18:35:31Linux的には単にシェルと言ったらbashを指す。
0048名無しさん@お腹いっぱい。
2007/09/08(土) 20:32:05シェルスクリプト総合@LINUX Part3
http://pc11.2ch.net/test/read.cgi/linux/1184077033/
0049名無しさん@お腹いっぱい。
2007/09/09(日) 12:25:29自分の環境に wget が無くて curl ならあるんで直接的な回答じゃなくてスマンが。
curl だと -L オプションでリダイレクトをたどってくれる。
wget は知らない。調べてちょ。ダメだったら wget はあきらめて curl で代替するのがお勧め。
後、curl の User Agent だと Google から嫌われるので、
-A ' -A 'Mozilla/5.0 (hogehoge)'
のオプションを付けてブラウザのフリをさせる。知ってるかも知れないけど。
0050名無しさん@お腹いっぱい。
2007/09/09(日) 12:40:04ちとやってみたがユーザーエージェントではじかれてるだけっぽい
-U 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
とかでUA指定すればよいが、とりあえず'a'とか適当な名前でも通るようだ
>>41の質問だが
-O foo.htmlとか適当な名前を出力先に指定するなり
-O -などとして標準出力に吐かせてシェル側で受け取るなり好きに汁
0051名無しさん@お腹いっぱい。
2007/09/09(日) 13:07:11そういう問題みたいだね。
>英数字以外の文字列
たとえば「ソニー」の場合のURLは
http://www.google.co.jp/search?hl=ja&q=%E3%82%BD%E3%83%8B%E3%83%BC&btnI=I%27m+Feeling+Lucky&lr=
になる。「ソニー」をUTF-8でURLエンコードして「%E3%82%BD%E3%83%8B%E3%83%BC」
にするんだが、そこから先の細かい話はWebProg板とかで聞いた方が良い。
005240
2007/09/09(日) 21:03:32いただいたヒントを元にネットで検索した結果、手元の環境で
curl -L -A 'a' -w %{url_effective} "http://www.google.co.jp/search?hl=ja&q=2ch&btnI=I%27m+Feeling+Lucky&lr="
にて出力される最後の1行だけをテキスト処理していくことで、思っていることが
出来ることがわかりました。
板違いの分も含めてお騒がせしました。
0053名無しさん@お腹いっぱい。
2007/09/12(水) 00:12:12while read line; do echo $line; done < file
であってますか?
0054名無しさん@お腹いっぱい。
2007/09/12(水) 00:21:400055名無しさん@お腹いっぱい。
2007/09/12(水) 01:14:370056名無しさん@お腹いっぱい。
2007/09/12(水) 02:55:39for でファイル数分処理したいと考えています。
例: find で見つかったファイルが /home/abc/1.txt /home/abc/2.txt
であれば、
for i in /home/abc/1.txt /home/abc/2.txt
do ......
といった感じです。
この場合に、find で見つけたファイルを変数に、
「arg1 arg2 arg3 ...」と代入する方法がわかりません。
お助けください、おながいします。m(_ _)m
0057名無しさん@お腹いっぱい。
2007/09/12(水) 04:28:01> for で
ここが間違い
0058名無しさん@お腹いっぱい。
2007/09/12(水) 06:40:33あってるお
>>56
find . | while read line; do echo $line; done
0059名無しさん@お腹いっぱい。
2007/09/12(水) 08:45:19あってないよw
せっかく >>55 がくれてるヒント守れよ
でないと誤動作するよ
0060名無しさん@お腹いっぱい。
2007/09/12(水) 10:38:11完全な方法はないってことで。
# \ は read -r で動作を変えられるけど。
0061名無しさん@お腹いっぱい。
2007/09/12(水) 10:56:32/home/fuga/2.txt
/home/ahan/3.txt
このパスから
Unixユーザ名部分(上記の場合、hogeとfugaとahan)を
抜き出して変数に代入するにはどうすればよいでしょうか。
正規表現を使うということはなんとなくわかります。
0062名無しさん@お腹いっぱい。
2007/09/12(水) 10:59:39雑でいいなら
awk -F/ '{ print $3 }'
で出るけど、他に条件あるなら言ってくれ。
006361
2007/09/12(水) 11:10:04ありがとうございます、
お言葉に甘えて
Unixユーザ名が
[a-z0-9-]+
の場合、という条件も加えてもらえるでしょうか。
それで awk の使い方などを調べてみます。
0064名無しさん@お腹いっぱい。
2007/09/12(水) 11:19:210065名無しさん@お腹いっぱい。
2007/09/12(水) 12:58:10スクリプトfoo.shは、trapを用いて、SIGINTのハンドラを記述しています。
スクリプトbar.shは、スクリプトfoo.shをバックグラウンドで起動します。
foo.shをコマンドラインからフォアグラウンドで実行した場合。
foo.shをコマンドラインからバックグラウンドで実行した場合。
foo.shをdaemonで実行した場合。
いずれのケースでも、foo.shにSIGINTを送ると、foo.shのハンドラは
実行されます。
しかし、bar.shからバックグラウンドで起動されたfoo.shに対して
SIGINTを送っても、foo.shのハンドラは実行されません。
また、foo.shから起動しているコマンドにSIGINTを送っても、
無視されている様子です。
なぜでしょう?
また、bar.shからバックグラウンドでfoo.shを起動した場合でも、
foo.shのハンドラが実行され、foo.shから起動しているコマンドも
同様にSIGINTを受け付けてくれるようにする為にはどうすれば
良いのでしょうか?
006665
2007/09/12(水) 12:59:09スクリプト foo.sh
#!/bin/sh
trap 'HANDLE' INT
HANDLE()
{
touch /tmp/foo.log
exit
}
echo "START"
/bin/rm -f /tmp/foo.log
/bin/sleep 30
echo "END"
スクリプトbar.sh
#!/bin/sh
/tmp/foo.sh &
0067名無しさん@お腹いっぱい。
2007/09/12(水) 13:15:52バックグラウンドで起動されたプロセスは、
最初から SIGINT無視の状態で起動される。
これは、シェル上で trapを実行しても再設定されない。
シェルスクリプトでは不可能。
006865
2007/09/12(水) 13:19:32perlのスクリプトにしても同じでした。
0069名無しさん@お腹いっぱい。
2007/09/12(水) 13:21:31>>67
0070名無しさん@お腹いっぱい。
2007/09/12(水) 13:32:35直接起動する場合に限り、バックグラウンドで起動してもSIGINTは無視されない。
しかしこれは例外と考えるべき。
ジョブコントロールは、プロセスグループを変更することによって管理していて、
fgでフォアグラウンドになる時のために、
SIGINTを無視しないようになっているだけの話。
007165
2007/09/12(水) 13:42:08shのソースを見てましたが、確かにバックグラウンドで起動されたときは
SIGINT,SIGQUITをSIG_IGNしているみたいです。
ひとつ賢くなりました。
daemonで起動することにします。
0072名無しさん@お腹いっぱい。
2007/09/12(水) 16:01:50のfileだけ返すようなコマンドってないでしょうか。
0073名無しさん@お腹いっぱい。
2007/09/12(水) 16:21:270074名無しさん@お腹いっぱい。
2007/09/12(水) 16:47:520075名無しさん@お腹いっぱい。
2007/09/12(水) 16:53:28アフォか。/hoge/hage/boke/file だったらどうすんだよw
0076名無しさん@お腹いっぱい。
2007/09/12(水) 16:55:41サンクスです!!
0077名無しさん@お腹いっぱい。
2007/09/12(水) 16:55:49後からそんな条件追加されてもな。
0078名無しさん@お腹いっぱい。
2007/09/12(水) 17:06:15正解が出る前にわざとボケるならまだしも、
>>73 に正解が出た後でボケてもウケないよ。
0079名無しさん@お腹いっぱい。
2007/09/12(水) 17:38:55と
find /home -regex "/home/.*\.c"
ってCPUやHDDへの負荷って変わりますか?
後者の方が良い気がしますが、現在全て前者で作っちゃってます。
0080名無しさん@お腹いっぱい。
2007/09/12(水) 18:27:30やってみればすぐわかるのに
あと、cのソース探すのに、-regexは過剰だろ。-nameで十分
0081名無しさん@お腹いっぱい。
2007/09/12(水) 18:30:50どっちでもいいんじゃないかな。たまには痛い目を見るのもいい経験だよ。
008261
2007/09/12(水) 18:33:59ありがとうございます。
今回のケースはこれでいけそうです。
何度もすいません、今後のために聞いておきたいのですが、
/home/hoge/abc.txt
の.txtを除いたファイル名、つまりabcを取得したい場合、
などには
どんな方法があるでしょうか。
0083名無しさん@お腹いっぱい。
2007/09/12(水) 18:37:19008461
2007/09/12(水) 18:42:02abc.txt ではなく、 abc を取得したいと思います。
0085名無しさん@お腹いっぱい。
2007/09/12(水) 18:50:290086名無しさん@お腹いっぱい。
2007/09/12(水) 18:57:34それだとなんか英語のようなものが表示さ(ry
0087名無しさん@お腹いっぱい。
2007/09/12(水) 18:59:40黙らせるためにずばり答え書いてやれよ。
basename /home/hoge/abc.txt .txt
008861
2007/09/12(水) 19:06:57サンクスです
0089名無しさん@お腹いっぱい。
2007/09/12(水) 19:11:12>>61 は awkなんか使わなくてもできる。
basename `dirname /home/hoge/1.txt`
0090名無しさん@お腹いっぱい。
2007/09/12(水) 22:20:18監視(ここでは適当なcommand)したいです。
syslogやmessegesはローテートしているので
前回の監視(1時間前)後にログが切り替わった場合と
そのまま使われている場合で実行commandを変えたいのですが
どのようなシェルスクリプトにしたらできるでしょうか?
たとえばどのログも切り替わっていない場合はcommandA、
syslogが切り替わった場合はcommandB、
messegesが切り替わった場合にはcommandCを
実行するというようなシェルスクリプトが書きたいのですが^^;
0091名無しさん@お腹いっぱい。
2007/09/12(水) 22:36:41name=/home/hoge/1.txt; name=${name#/*/}; echo ${name%%/*}
0092名無しさん@お腹いっぱい。
2007/09/12(水) 22:39:40どっちも切り替わった場合は?
というのは置いといて、
前回と今回見ているファイルの実体同じかどうかのチェックということなら、
切り替え時に必ずi-node番号が変わるという前提で、
ls -iでi-node番号を取得して、保存しとくしかないだろうな。
oldinode=`cat /var/log/oldinodestore`
ls -i /var/log/syslog | awk '{print $1}' >/var/log/oldinodestore
newinode=`cat /var/log/oldinodestore`
if [ $newinode -eq $oldinode ]; then
kawattenai
else
kawatta
fi
0093名無しさん@お腹いっぱい。
2007/09/12(水) 22:44:43あってるだろがwwwwwwwwwww
ばかかwwwwwwwww
0094名無しさん@お腹いっぱい。
2007/09/12(水) 22:50:16あってねーよ。池沼。WWWW
(echo " aaa"; echo " bbb")|while read line; do echo $line; done
0095名無しさん@お腹いっぱい。
2007/09/12(水) 22:55:10切り替わってなくて commandA を実行しはじめたとたんに、
あるいはその直前に、切り替わっても問題ないという前提か?
009690
2007/09/13(木) 10:35:28>>92
ありがとうございます。
いただいたShellで試してみますね。
いつか自分でもShellがすらすら書けるようになるのかなぁ。。
>>95
そこまでシビアなタイミングは前提にしていないようです。
最悪1時間後の監視でひっかかればよいという前提です。
>90を訂正します。
syslog、messegesどちらが切り替わってもcommandBを
実行すればよいみたいです。
syslog、messegesが切り替わっていたらcommandBを実行。
切り替わっていなかったらcommandAを実行できればよいようです。
0097名無しさん@お腹いっぱい。
2007/09/13(木) 10:40:56009890
2007/09/13(木) 10:49:31先日区別しなくてはいけないと読んだばかりでした><
0099名無しさん@お腹いっぱい。
2007/09/13(木) 13:00:29>1時間ごとにのsyslog、messegesを
>監視(ここでは適当なcommand)したいです。
新人君かな?それじゃなきゃ、おわってるけどw
君には、このギョーカイ向いて無いぞ
でも、そんなの関係ねぇー♪なら、いいけどさ。
分からないことは、聞くんじゃ無くて検索するようにすれば、生き残っていけるから頑張れ!!
0100名無しさん@お腹いっぱい。
2007/09/13(木) 13:23:47新入社員です^^;
シェルスクリプトを勉強し始めましたが
自分で作れるほどにはなっていなくて><
0101名無しさん@お腹いっぱい。
2007/09/13(木) 18:09:32CPU使用率を跳ね上げた状態で試験がしたいのです。
それで、CPU使用率がバカ上がる(目標90%)シェルかスクリプトを簡単に作りたいんです。
Whileでfindやgrepやsortをまわしたんですが、70%越えが精一杯。
もっと凶悪なものないでしょうか?
0102名無しさん@お腹いっぱい。
2007/09/13(木) 18:19:13while :; do :; done
とかは?
0103名無しさん@お腹いっぱい。
2007/09/13(木) 18:21:52whileで無限ループはかけてますよ。
0104名無しさん@お腹いっぱい。
2007/09/13(木) 18:33:29単にシェルのなかでビジーループするだけのほうがCPU占有するだろうと
思えるから書いたんだが。
0105名無しさん@お腹いっぱい。
2007/09/13(木) 18:44:01>>103 みたいな、恩を仇で返すような質問者にはなりたくないなぁ
0106名無しさん@お腹いっぱい。
2007/09/13(木) 19:03:590107名無しさん@お腹いっぱい。
2007/09/13(木) 19:06:19実験注意
0108名無しさん@お腹いっぱい。
2007/09/13(木) 19:13:45ようこそ、バーボンハウスへ。
このしょっぱいロールケーキはサービスだから、まず食べて落ち着いて欲しい。
実は、君に一生セクロス出来ない呪いをかけたんだ。
うん、「また」なんだ。済まない。
仏の顔もって言うしね、謝って許してもらおうとも思っていない。
↓このスレに「こんばんは、プッシーキャットです」とレスすれば呪いは解ける。
http://ex21.2ch.net/test/read.cgi/voiceactor/1189073996/
じゃあ、注文を聞こうか。
0110名無しさん@お腹いっぱい。
2007/09/13(木) 20:02:20どうでもいいが、君は>>101かな?
レス番ずれとるぞ
0111名無しさん@お腹いっぱい。
2007/09/13(木) 23:40:34それのどこがファイル表示してんだ?wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
ばかばっかりwwwwwww
0112名無しさん@お腹いっぱい。
2007/09/14(金) 00:12:41( ・ω・)んも〜
○={=}〇,
|:::::::::\, ', ´
、、、、し 、、、(((.@)wwwwwwwwwww
0113名無しさん@お腹いっぱい。
2007/09/14(金) 00:36:44>>94は「行頭行末の空白が出ない」って言いたいんだろ。 >>60 参照。
0114名無しさん@お腹いっぱい。
2007/09/14(金) 19:39:12ファイルからコマンドラインを読み込んでるだけですよね?
だったら、なぜシェルスクリプトのモード(?)の時は、
プロンプトが出ないんですか?
プロンプトを出す方法はありますか?
0115名無しさん@お腹いっぱい。
2007/09/14(金) 20:25:19させたいのですが、bashで乱数を発生させるのにはどうすれば
良いでしょうか?
何に使うかというと、
OSはCentOS5.0です。NFSサーバが一台、NFSクライアントが100台です。
NFSクライアントの個々のlocal HDDのファイルを土曜深夜に
自動バックアップさせようと思っていますのでcrontabに一行
書こうと思っています。1台あたりのバックアップは10秒もか
かりません。
うんで、100台が一斉にバックアップはじめるとサーバが死ぬので
ランダムにsleepを居れたいのですが、、、
100台のcrontabの時間を1分刻に変更してくなんて、めんどくさい
にょろ。
0116名無しさん@お腹いっぱい。
2007/09/14(金) 20:27:50sleep $((RANDOM*1800/32768))
0118名無しさん@お腹いっぱい。
2007/09/14(金) 20:32:040119名無しさん@お腹いっぱい。
2007/09/14(金) 21:03:49次はこっちで聞こうな。
シェルスクリプト総合@LINUX Part3
http://pc11.2ch.net/test/read.cgi/linux/1184077033/
0120名無しさん@お腹いっぱい。
2007/09/14(金) 21:25:44>ファイルからコマンドラインを読み込んでるだけ
違う。
プロンプトではコマンドラインしか実行できないが、
シェルスクリプトではコマンドラインの他、
if文とかfor文とか、変数の代入とかもできるようになる。
そもそも別物なので、プロンプトは出ない。
0121名無しさん@お腹いっぱい。
2007/09/14(金) 21:49:470122名無しさん@お腹いっぱい。
2007/09/14(金) 22:08:09$ for i in hoge
for: Command not found.
って出るし。
変数も使えない。
$ HOGE=hage
HOGE=hage: Command not found.
0123名無しさん@お腹いっぱい。
2007/09/14(金) 22:33:150124名無しさん@お腹いっぱい。
2007/09/14(金) 22:46:57シェルがプロンプトを出力するのは、ユーザに入力を受け付ける事ができるようになった事を表すため。
なので、基本的にその必要のない、非対話的(>シェルスクリプトのモード)な動作をするときはプロンプトを出力しない。
この対話的、非対話的であるということは起動時に決定され移行する手段もないためスクリプト実行中にプロンプトを出力する事は出来ない。
0125名無しさん@お腹いっぱい。
2007/09/14(金) 23:37:55set -i すればプロンプト出るよw
0127名無しさん@お腹いっぱい。
2007/09/15(土) 08:45:14これで満足か? イケヌマ君。www
echo " aaa" >file
while read line; do echo $line; done <file
0128名無しさん@お腹いっぱい。
2007/09/16(日) 21:05:08こんなどうしようもないショボい釣り針は初めて
うっかり釣られたけど、どうやったらこんなショボいこと浮かぶの?
0129名無しさん@お腹いっぱい。
2007/09/16(日) 21:08:42本当に使えないんですが,,,
使えるようになる設定とかあるんですか???
0130名無しさん@お腹いっぱい。
2007/09/16(日) 21:21:06もし使えたらおかしなことになるだろ。
例えば forだったら、doneコマンドを実行したら
doコマンドのところまで後ろにジャンプしないといけない。
コマンドラインでは、打ったコマンドを順番に実行するだけだから、
後ろに戻るような動作はできない。
forを使いたきゃ、シェルスクリプトに一旦書くしかない。
0131名無しさん@お腹いっぱい。
2007/09/16(日) 21:51:01コマンドラインでfor文を使いたければ、Cシェル系(foreach)でも使ったら?
0132名無しさん@お腹いっぱい。
2007/09/16(日) 22:02:42もしかしてマジ?そんな環境があるのか知らないけど
取り合えず以下でも受け付けない?
for x in a b; do echo $x ; done
0133名無しさん@お腹いっぱい。
2007/09/16(日) 22:09:27for: Command not found.
x: Undefined variable.
0134名無しさん@お腹いっぱい。
2007/09/16(日) 22:18:59$ csh
%set prompt='$ '
$ for x in a b; do echo $x;done
for: Command not found.
x: Undefined variable.
0135名無しさん@お腹いっぱい。
2007/09/16(日) 22:20:51まじですまないがググらんと原因が分からないんでパス
0136名無しさん@お腹いっぱい。
2007/09/16(日) 22:26:14いやプロンプトをどうするかは自由だけどね
0137名無しさん@お腹いっぱい。
2007/09/17(月) 10:19:560138名無しさん@お腹いっぱい。
2007/09/17(月) 18:50:07でも >>129-131 の時点で自演に気付けなかった自分にorz
参りました一生romってます
0139名無しさん@お腹いっぱい。
2007/09/18(火) 19:37:25非常に簡単なスクリプト、たとえば以下のような場合ですが
このままでいいのですかね?
もうちょっとスクリプトらしく書けとかありません?^^;
役割果たすならシンプルが一番なのかもしれませんが
シェルスクリプトというよりコマンドの羅列なので・・
#!/bin/sh
ls -i /var/log/syslog > var/log/check.log
date >> var/log/check.log
0140名無しさん@お腹いっぱい。
2007/09/18(火) 20:15:57var/log/check.logを、わざわざ相対PATHで書いてるのはなぜ?
これだと、このシェルスクリプトを / で実行しないと
期待通り動かないよ。
もうちょっとシェルスクリプトらしくするには、
例えば↓
#!/bin/sh
CHECK_LOG=/var/log/check.log
{ ls -i /var/log/syslog; date; } > $CHECK_LOG
■ このスレッドは過去ログ倉庫に格納されています