シェルスクリプト総合 その6
■ このスレッドは過去ログ倉庫に格納されています
0001うはwwwww
2006/03/26(日) 00:56:22スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>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 でトレースしましょう。
0306名無しさん@お腹いっぱい。
2006/04/13(木) 19:25:56といったところ?
0307名無しさん@お腹いっぱい。
2006/04/13(木) 21:11:24comm - /dev/null
0308名無しさん@お腹いっぱい。
2006/04/13(木) 22:07:280309名無しさん@お腹いっぱい。
2006/04/14(金) 00:26:170310名無しさん@お腹いっぱい。
2006/04/14(金) 05:05:22>ダウト! nkf -Jj は変換されてしまう。
nkf -t だよ。作者が言うんだから間違いない。
perl -ple 0
0311名無しさん@お腹いっぱい。
2006/04/14(金) 07:27:38おなじ殺伐でも馴れ合いで緩和されるところがあると思う。
0312名無しさん@お腹いっぱい。
2006/04/14(金) 07:57:48馴れ合いはハンドルネームなどで個人が特定可能な場合に生じるものだと
思うが。
2ch以前の掲示板文化は大体それで、常連同士の馴れ合いの場と化していた。
2chであっても、コテが集まるスレッドは概ね馴れ合いの場になるよな。
fjがあまり馴れ合い的でなかったとすれば、個人が特定可能かどうかという
問題ではなく、あの独特のスノビズムにあったのでは?と思う。
馴れ合いより議論の緊張感と個人主義を好み、知的であることを尊ぶ。
fjの有名人達にそういうキャラの人が多く集まっていて、それがfjの
空気を生んでいたと言うべきではないかと。
0313名無しさん@お腹いっぱい。
2006/04/14(金) 08:31:44裏でははらわたが煮えくり返っていそうで冷静を装う文章とか
どうでもいいところにいちいち丁寧に突っ込むのとかは
確かにスノッブといえばそうだな。
0314名無しさん@お腹いっぱい。
2006/04/14(金) 09:11:07そう言ってもいい気もするがな
0315名無しさん@お腹いっぱい。
2006/04/14(金) 11:38:200316名無しさん@お腹いっぱい。
2006/04/14(金) 11:44:200317名無しさん@お腹いっぱい。
2006/04/14(金) 12:23:16オレなんか未だに「レス」に抵抗あるもん
0318名無しさん@お腹いっぱい。
2006/04/14(金) 12:25:030319名無しさん@お腹いっぱい。
2006/04/14(金) 13:55:27やるとなるとマルチになっちゃう。
0320名無しさん@お腹いっぱい。
2006/04/14(金) 14:16:410321名無しさん@お腹いっぱい。
2006/04/14(金) 17:27:08「マジフォロ希盆」とか
「横フォロスマソ」とかいう言葉を普及させてくれ。
0322名無しさん@お腹いっぱい。
2006/04/15(土) 07:50:220323名無しさん@お腹いっぱい。
2006/04/16(日) 19:52:12フォローに相当するのならレス(ポンス)で許せるが
単発の投稿をレスというのは違和感がぬぐいきれない :-(
0324名無しさん@お腹いっぱい。
2006/04/16(日) 22:06:100325277
2006/04/17(月) 10:02:03先日お聞きしたメールアカウント登録の件、無事終了できました。
パスがどうのとか権限がどうのとかいう部分からわかんない状態でしたので
そもそも私みたいなもんがやることじゃなかったかもしれませんが、
勉強できてよかったです。
返答してくださった皆さん本当にありがとうございました。
0326名無しさん@お腹いっぱい。
2006/04/21(金) 10:31:55goto文以外で。
0327名無しさん@お腹いっぱい。
2006/04/21(金) 11:22:51使えないよ。tcshとか最近の拡張されたのは知らんけど
0328名無しさん@お腹いっぱい。
2006/04/21(金) 12:00:04(t)cshは関数だけじゃなくていろんな意味で糞だから、
決して(t)cshスクリプトを書こうなんて思っちゃいけない。
0329名無しさん@お腹いっぱい。
2006/04/21(金) 12:10:150330名無しさん@お腹いっぱい。
2006/04/21(金) 12:17:00と老害が申しております。
0331名無しさん@お腹いっぱい。
2006/04/21(金) 13:50:37し。UTF-8対応でないところは無視すれば良い。
0332名無しさん@お腹いっぱい。
2006/04/21(金) 15:48:48対応しているが。
0333名無しさん@お腹いっぱい。
2006/04/22(土) 01:18:13ただ、shのスクリプトをまともに書けなくするbashは消されるべき。
0334名無しさん@お腹いっぱい。
2006/04/22(土) 10:45:01同じことがzshにも言えるわけで・・
というか、shの範囲内だけで記述するなら、
zshよりもbashの方が互換性高いよ。
zshはsignalまわりがどうやってもsh互換にできない。
0335名無しさん@お腹いっぱい。
2006/04/22(土) 14:22:20bash 使ってる奴は、その辺、無自覚な奴が多い。
ってことでは?
bash の場合、昔からそうだったってわけじゃなくて、
Linux の標準シェルになったのが不幸の始まりって気がする。
zsh もユーザが増えてきたから、最近は bash とそう事情は変わらんかも。
0336名無しさん@お腹いっぱい。
2006/04/22(土) 15:30:30シングルユーザーモードで使いにくい、というのないか?
bashだと、現実にシングルユーザーモードでも使われてる。
まあ、そういう場合はsh(ash)を使えばいいんだけど。
0337名無しさん@お腹いっぱい。
2006/04/22(土) 17:56:30今シングルユーザモードで使えないシェルってあるの?
0338名無しさん@お腹いっぱい。
2006/04/22(土) 18:34:27使えない。(実体が/usr以下にあるから)
使えるのは/sbin/shのみ。
0339名無しさん@お腹いっぱい。
2006/04/22(土) 19:55:38% svcs -d svc:/milestone/single-user | grep filesystem
online 15:53:25 svc:/system/filesystem/minimal:default
% svcs -d svc:/system/filesystem/minimal
STATE STIME FMRI
online 15:53:25 svc:/system/filesystem/usr:default
online 15:53:25 svc:/system/device/local:default
0340名無しさん@お腹いっぱい。
2006/04/22(土) 22:55:04Linux板のシェルスクリプトスレに行ってくれよ。
0341名無しさん@お腹いっぱい。
2006/04/22(土) 23:01:13誰もそんな話はしていないが。
0342名無しさん@お腹いっぱい。
2006/04/23(日) 01:45:54sh で、スクリプトを組もうとしています。
目的は、apache で、決まったユーザごとにBASIC認証をさせようとしていて、
新規のユーザが入るたびに、設定するのが面倒になったので、スクリプトを組み始めました。
取り合えずユーザ名とパスワードだけのテキストファイル(list_name)は、手動で作り
user1 passwd1
user2 passwd2
for文かwhile文で書けば終わると思っていたのですが
二次元配列?のところでうまくいきません。
ユーザ名もパスワードもバラバラに引数として利用したい。
for文だと、eval を使って、出来るんでしょうか?
while文で、shift 2 とかすればいいかなと思ったのですが、for文でのin に変わるものだわかりません。
なにかヒントだけでもよろしくお願いします。
0343名無しさん@お腹いっぱい。
2006/04/23(日) 02:02:21read の使い方を調べると幸せになれる。
while read user pass ; do
...
done < list_name
bash の read なら配列に代入する事もできるけど、
これで充分だよね?
0344名無しさん@お腹いっぱい。
2006/04/23(日) 02:09:510346名無しさん@お腹いっぱい。
2006/04/23(日) 09:01:38zshでも、readで配列に入れることができるが、(read -A)
するとzshも、もうたくさんですか?
0347名無しさん@お腹いっぱい。
2006/04/23(日) 15:29:150348名無しさん@お腹いっぱい。
2006/04/23(日) 15:41:27で、配列が使えるkshでは、bashとkshは同じ。
kshがPOSIX準拠だとすると、bash方式の配列が正しくて、
zsh方式の配列は独自文法ということになる。
配列に関してはzshの方が糞。bashは正しい。
0349名無しさん@お腹いっぱい。
2006/04/23(日) 15:49:45/bin/sh がzshのシステムなんて、無いだろ?
てことは、zshスクリプトは「わざと」書いてるんだろう。
「わざと」書く分には、/bin/shと互換性が無かろうが、そいつの責任であり
勝手じゃないのか?
0350名無しさん@お腹いっぱい。
2006/04/23(日) 16:29:58python -c 'print __import__("sys").stdin.read()' |
ruby -e 'while gets(); print $_ end' |
sh -c 'while read x;do echo $x;done' |
awk '{print}' |
perl -pe '' |
sed '' |
cat |
tr a a |
grep '' |
dd 2> /dev/null |
gzip -c | gzip -dc |
uuencode hoge | uudecode -p |
tail +1 |
vim -es -c "wq! /dev/stdout" /dev/stdin |
bash -c 'echo "`</dev/stdin`"' |
tee |
comm - /dev/null |
paste - |
cut -f 1- |
nkf -t |
perl -ple 0 |
危険!全部繋げて試したらカーネルパニクッた
0351名無しさん@お腹いっぱい。
2006/04/23(日) 16:30:10MacOSX 10.0
0352名無しさん@お腹いっぱい。
2006/04/23(日) 18:09:51乙。w
0353名無しさん@お腹いっぱい。
2006/04/23(日) 18:15:55(というかそもそも可能でしょうか?)
0354353
2006/04/23(日) 18:28:59多数見つけたのですが、
これではセキュリティ的にもろみえの状態なので避けたい、ということです。
ttp://ns1.php.gr.jp/pipermail/php-users/2003-December/019954.html
0355名無しさん@お腹いっぱい。
2006/04/23(日) 18:42:42expect `cat`
でいいんじゃない?
0357名無しさん@お腹いっぱい。
2006/04/23(日) 23:47:19>>355は何もわかっていないという意味です。
0358名無しさん@お腹いっぱい。
2006/04/24(月) 12:25:35できました。ありがとう。
シェルの基本文法で良かったのですね。
0359353
2006/04/24(月) 16:18:450360353
2006/04/24(月) 23:53:15若干すれ違い気味なせいでしょうか
0361名無しさん@お腹いっぱい。
2006/04/25(火) 02:20:38expectもtclも門外漢だが、
gets stdin line
or
set line [ gets stdin ]
とかじゃいかんのか?
0362名無しさん@お腹いっぱい。
2006/04/25(火) 09:13:53355 で解決しないの?
command substitution って知ってる?
0363353
2006/04/25(火) 10:21:30神サンクス!
gets stdin line でアメ語をぐぐったら例が結構見つかりました。
ただ
gets stdin old_pass
gets stdin new_pass
としている例があったんですが、2つ標準出力で渡すのはどうすればいいんでしょうか?
echo "old_pass" | echo "new_pass" | ./password.exp
とかやってみたけどもちろん無理ですた
gets stdin new_pass のみなら上手くいきました。
>>362
357氏のレスから意味のないレスだと思ってマスタ、
神レスだったのですね。
コマンド置換ってやつですね、調べてみましたが、基本的な使い方は
なんとなく理解したのですが、
この場合はいまいち使い方がわからんとです orz
0364名無しさん@お腹いっぱい。
2006/04/26(水) 00:33:20だったら expect 使う意味があまり無いと思うんだが。
0365名無しさん@お腹いっぱい。
2006/04/26(水) 01:25:570366名無しさん@お腹いっぱい。
2006/04/26(水) 01:31:170367名無しさん@お腹いっぱい。
2006/04/26(水) 04:18:44セキュリティ的にモロ見えイクナイってのが発端なのに、
>>355で解決するって本気で思ってんの?
0368名無しさん@お腹いっぱい。
2006/04/27(木) 21:08:48スクリプトを書いているんですが、
引数を渡さないかぎり入力待機状態にして次の行にいかない様に
するようなコマンドはありますでしょうか?
教えてくださいm(。_。;)m
0369名無しさん@お腹いっぱい。
2006/04/27(木) 21:53:37引数という用語がおかしいようだが、
キー入力待ちにしながらシェルスクリプトを1行ずつ実行させたいということか?
だったら、途中に、
read hoge
というコマンドをはさんどけ。
[Enter]を入力しないと次に進まなくなる。
0370名無しさん@お腹いっぱい。
2006/04/27(木) 23:09:09Cシェルは1706が引数の制限なようですがBシェルに関しては
ARG_MAXを限界値に引数に渡されるバイト数+環境との記述
をみたのだが同じ環境なら引数に渡されるバイト数は固定でないのか?
例えばls * | wc -l とかでやると(ファイル名+空白分)*ファイル数のバイト数は
ファイル数が多いほど少なくなるのですが・・・。
詳しい方教えてください。
0371名無しさん@お腹いっぱい。
2006/04/27(木) 23:15:140372名無しさん@お腹いっぱい。
2006/04/27(木) 23:20:43引数の個数じゃなくて、
全引数の文字列のバイト数+環境変数のバイト数(変数名も含む)
で決まってるはず。
手元の環境で試してみると、
合計128KBみたいだった。
0373名無しさん@お腹いっぱい。
2006/04/27(木) 23:35:01レスサンクス。
書き方がわるかったのかな。
全引数の文字列のバイト数+環境変数のバイト数(変数名も含む)
はオレも分かってはいるんだが
同じマシン、同じコマンドでやれば環境変数のバイト数は同じだよね?
つまり全引数のバイト数は固定だと思ってるのだが・・・。
ls * | wc -lを例えば%10dの10文字のファイル名が入ったフォルダで
実行した場合の限界ファイル数と200文字のファイル名が入った
フォルダでの限界ファイル数を取得したとき、文字数*ファイル数で出した数
がかなり違ってくるのでどうしてでしょうか?と聞きたい。
一応空白を考慮しても計算しているがそれでも違ってくる・・・。
0374名無しさん@お腹いっぱい。
2006/04/28(金) 01:56:550375名無しさん@お腹いっぱい。
2006/04/28(金) 09:37:540376名無しさん@お腹いっぱい。
2006/04/28(金) 19:03:33でls * | wc -lが引数が長すぎますとのエラーを返して
で%200dで作成した200文字のファイル名の場合5000ファイルで
ls * | wc -lが引数が長すぎますとのエラーを返した。
ここで空白を考慮してファイル名を31バイトと201バイトだと
考えると31*29800と201*5000では100Kぐらい差が出てくる。
全引数の文字列のバイト数だと考えるとなんでこんなに差が出るのと謎に思えたので教えてほしい
0377名無しさん@お腹いっぱい。
2006/05/01(月) 22:16:01「引数が長すぎます」は E2BIG (システムコールからのエラー)で出るらしい。Solarisでは
http://cvs.opensolaris.org/source/xref/on/usr/src/cmd/sh/service.c#315
その計算では argvの分が入ってないのでざっと計算すると、
31 byte x 29800 + sizeof(char *) x 29800 = 1043000
201 byte x 5000 + sizeof(char *) x 5000 = 1025000
これぐらいの差なら誤差程度では?
0378名無しさん@お腹いっぱい。
2006/05/04(木) 11:42:41対象ファイルの中で hoge という文字列が含まれている
ファイルを表示させたいのですが、簡単な方法はないでしょうか?
grep とリダイレクトあたりを使用することになると思うのですが。
0379名無しさん@お腹いっぱい。
2006/05/04(木) 12:47:59xargs grep -l hoge < ファイル
0380名無しさん@お腹いっぱい。
2006/05/04(木) 17:39:58応答待ち状態にタイムアウトを設定する、というのがあります
10秒たっても入力がないときには自動で抜けるようにする、というスクリプトです
trap ":" 2
(sleep 10; kill -2 $$) &
echo "Would you like to ... [y/n]? \c"
read ANSWER
if kill -0 $! 2>/dev/null; then
kill $!
fi
case "$ANSWER" in
y | yes ) FLAG=TRUE ;;
* ) FLAG=FALSE ;;
esac
trap 2
CentOSというLinuxのディストリで標準のbash使ってるんですが
サブシェルからの割り込みをうまく受け付けてくれないようで、自動で抜けてくれません
Solaris環境では意図したとおりに動きました
Linuxが悪いのか、bashが悪いのか、スクリプトが悪いだけなのかよくわかりませんが
うまく動かすにはどうすればいいでしょうか?
0381名無しさん@お腹いっぱい。
2006/05/04(木) 19:27:480382名無しさん@お腹いっぱい。
2006/05/04(木) 20:22:29こんな感じ? やっつけだけど。
#!/bin/sh
for f in `cat ファイル`
do
if [ `basename $f | grep hoge` ] ; then
echo $f
fi
done
0383名無しさん@お腹いっぱい。
2006/05/04(木) 21:07:41たしかに、ash使ってみたらうまくいきました
UNIX間で互換性をもたせるにはどうすればいいのかな、と考えてたのですが
とりあえずLinuxの標準がbashになってることを恨め、って感じでしょうか・・・
0384名無しさん@お腹いっぱい。
2006/05/04(木) 23:11:37それならkshに統一するとか?
Bourne shellよりわかりやすくスマートにかける場面も多いし。
いっちゃうとPerlでもいいとおもう。
0385名無しさん@お腹いっぱい。
2006/05/05(金) 02:48:10ここはシェルスクリプトのスレッド。あくまで。
0386名無しさん@お腹いっぱい。
2006/05/05(金) 12:53:54ここのpflogsumm_reportってシェルスクリプト参考にさせて
もらったんだけど、
直接たたくと上手く動作するものの
cronで動作させるとメール本文が空っぽ。
だれか想像できる原因教えてぷりーず
0387名無しさん@お腹いっぱい。
2006/05/05(金) 13:26:420388名無しさん@お腹いっぱい。
2006/05/05(金) 16:03:41そういう場合はshellの引数に-xをつければいいよー。
そこだと1行目を
#!/bin/bash -x
にするとか。
0389名無しさん@お腹いっぱい。
2006/05/05(金) 17:19:17crontab に必要なパスを記述していない可能性が高い。
たとえば >>387 とか。
0390名無しさん@お腹いっぱい。
2006/05/10(水) 22:03:55Unixの方がexpr substrに対応してなかった。
原因わかるまで1時間以上かかったぜ。
0391名無しさん@お腹いっぱい。
2006/05/10(水) 22:40:44エラーが出るだけましと思えば、、
0392名無しさん@お腹いっぱい。
2006/05/11(木) 01:45:33参考までに両方の expr のバージョンを教えてくれ。
0393名無しさん@お腹いっぱい。
2006/05/11(木) 06:38:10管理者の人に頼まれてLinuxで書いたからもうUnixの方は調べらんね。
実行できないって言われてmanでexpr調べたらsubstrはx86系のみ対応って書いてあった。んで、聞いたらたぶんx86系だといってたので原因わからず格闘。随分時間たっあとunameでシステムみたらSunの文字。ネットで調べたら他のCPUってオチ・・・。
0394名無しさん@お腹いっぱい。
2006/05/11(木) 15:11:04察するにお前の知識が足らんかっただけだろう
0395名無しさん@お腹いっぱい。
2006/05/11(木) 22:23:08Vine3.2(Pen4)で書いてSunOS(SPARC)で実行した。
3日前に初シェルスクリプト書いた位なので・・・知識はね
0396名無しさん@お腹いっぱい。
2006/05/12(金) 02:54:32GNU 拡張みたいだな。
0397名無しさん@お腹いっぱい。
2006/05/12(金) 10:02:570398名無しさん@お腹いっぱい。
2006/05/12(金) 10:42:01できない。
0399名無しさん@お腹いっぱい。
2006/05/12(金) 11:00:06必要なものだけ環境変数に export することにします。
同じ種類のシェルなら内部でなんかうまいことパイプとか
つくって引き継いでくれるのかな?
とか都合いいこと考えてました。
0400名無しさん@お腹いっぱい。
2006/05/13(土) 00:13:13http://shunit.sourceforge.net/
ドキュメントがまったく無いんだけど
0401名無しさん@お腹いっぱい。
2006/05/13(土) 06:48:50シェルスクリプトのテストツール?なのかこれ?
今ソースを眺めてるけど、なんか関数が
たくさん定義されてるな。
今は眠いから処理を追いかけられねーや。
0402名無しさん@お腹いっぱい。
2006/05/14(日) 04:13:005 だったら 0005
55 だったら 0055
555 だったら 0555
5555 だったらそのままの 5555
というように数字1〜4桁までのファイル名を0を使って4桁に揃えたいのですが
for 名前 in * ; do
桁数=${#名前}
[ $桁数 = 1 ] && mv $名前 000$名前
[ $桁数 = 2 ] && mv $名前 00$名前
[ $桁数 = 3 ] && mv $名前 0$名前
done
こんなのしか思い浮かびません。もっとスマートで汎用的な感じにできませんでしょうか?
0403ヽ(´ー`)ノ ◆.ogCuANUcE
2006/05/14(日) 05:05:53# -> 0005
printf %04d 55
# -> 0055
printf %04d 555
# -> 0555
printf %04d 5555
# -> 5555
printf %04d 55555
# -> 55555
0404名無しさん@お腹いっぱい。
2006/05/14(日) 09:15:040055
0405名無しさん@お腹いっぱい。
2006/05/14(日) 12:13:29case "$x" in
?) y=000$x ;;
??) y=00$x ;;
???) y=0$x ;;
????) y=$x ;;
*) y=$x ;;
esac
なんて方法もある。
普通なら>>403を使うけど、数値しか使えないのでこういう小細工も使うことがある。
0406名無しさん@お腹いっぱい。
2006/05/14(日) 13:36:09それ自体は悪くはないんだけど、
仕事でそういうのの塊のコードがあって泣きそうになったことある。
シェルスクリプトで日付計算とかね。アホかっちゅーの。
■ このスレッドは過去ログ倉庫に格納されています