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

シェルスクリプト総合 その6

■ このスレッドは過去ログ倉庫に格納されています
0001うはwwwww2006/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 でトレースしましょう。
0793名無しさん@お腹いっぱい。2006/07/23(日) 01:26:07
それPl(ry
0794名無しさん@お腹いっぱい。2006/07/23(日) 09:50:43
>>792
漏れだったら、perlで全部処理するけどな。LWPモジュール+Socketモジュール+cron
0795名無しさん@お腹いっぱい。2006/07/23(日) 10:19:06
俺ならwgetで取ってきてsedとtrで必要なところだけ取り出すな。
0796名無しさん@お腹いっぱい。2006/07/23(日) 10:46:56
まあ、何でもすぐperlに走っちゃうのは利工じゃないってことで。
0797名無しさん@お腹いっぱい。2006/07/23(日) 12:34:51
簡単にできるものを車輪の再発明してる方が(ryってことで。
0798名無しさん@お腹いっぱい。2006/07/23(日) 12:43:07
シェルの方が歴史がずーーっと古いわけだが。perl自体が車輪の再発明。
0799名無しさん@お腹いっぱい。2006/07/23(日) 12:47:14
perlはごった煮の闇鍋。
0800名無しさん@お腹いっぱい。2006/07/23(日) 12:47:38
つーか、シェルスレで質問してる以上、シェルでのやりかたを聞いてるわけだから、
perlしか知らない厨が不安になって自己弁明するために「俺ならperlでやる」みたいな
カキコするのいいかげんやめれ。
0801名無しさん@お腹いっぱい。2006/07/23(日) 12:50:57
車輪の再発明ってバカみたいだよね。言ってるほうが。
0802名無しさん@お腹いっぱい。2006/07/23(日) 12:53:04
シェル(スクリプト)でやることにこだわるなら答えは「できない」になりますが
0803名無しさん@お腹いっぱい。2006/07/23(日) 13:04:11
>>802
「お前にはシェルではできない」だな。
0804名無しさん@お腹いっぱい。2006/07/23(日) 13:14:55
それじゃお得意のシェルでやって見せてくれよw
0805名無しさん@お腹いっぱい。2006/07/23(日) 13:19:12
シェルっていうなクズ。
0806名無しさん@お腹いっぱい。2006/07/23(日) 13:22:57
空ageすんなクズ。
0807名無しさん@お腹いっぱい。2006/07/23(日) 13:24:31
>>804
>>795 に書いてあるのが見えないのか?

>>806
誰もageてないわけだが…?
0808名無しさん@お腹いっぱい。2006/07/23(日) 13:37:02
(プ
0809名無しさん@お腹いっぱい。2006/07/23(日) 15:22:00
>>805
久しぶりに言えて良かったねw
0810名無しさん@お腹いっぱい。2006/07/23(日) 16:11:25
俺ならCでやる。
0811名無しさん@お腹いっぱい。2006/07/23(日) 16:34:22
shでもperlでもcでもいいけど具体的なコード示したら
0812名無しさん@お腹いっぱい。2006/07/23(日) 16:42:18
おねがいします、って言えよ
0813名無しさん@お腹いっぱい。2006/07/23(日) 16:56:32
空ageすんな
0814名無しさん@お腹いっぱい。2006/07/23(日) 16:57:19
こんなテキストファイルが有るとき(行頭の数字は行数)
----------------
1 あああ
2 てすと
3 <html>
4 おちんぽ
5 あへあへ
6 ぶりぶりー</html>
7 あげあげ
8 ふとったーt
----------------
<html>〜</html> の間だけ抜き出したいんですがどうやったらええんでしょうか。
それぞれ行は可変です。

\nを削除してしまって一行にして、sedで s/.*<html>.*</html>/\1/g みたいなのとかは思いつくんですが
イマイチ美しゅうないと思うとります。

マッチする行数をゲッツ出来れば、tail&headでがっつり抜き出せそうなんですが、
行番号をゲッツする方法が分かりませぬ。
エロ胃人お願いします
0815名無しさん@お腹いっぱい。2006/07/23(日) 17:02:54
>>814
\nを削除しなくても、↓でできるよ。

sed -n '/<html>/,/<\/html>/p'

ただしこれだと<html>や</html>と同じ行のタグ外の部分も出てくるから、
あとsedの置換で<html>より左の部分と</html>より右の部分を削除すれば良い。
0816名無しさん@お腹いっぱい。2006/07/23(日) 17:30:33
>>815
ありがとおおおおお


と言うことでドブの素人の俺様が作ってみました

url='http://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8'
rm temp.html
wget -nv --output-document=temp.html $url
sed -n '/今日は何の日/,/訃報/p' temp.html | sed 's/<[^>]*>//g'

今日はこれくらいで勘弁してください>>792
0817名無しさん@お腹いっぱい。2006/07/23(日) 20:26:09
wikipediaのメインページ、何故こんなに重い?
0818名無しさん@お腹いっぱい。2006/07/23(日) 20:57:24
# echo "蔵" >file
# /usr/bin/printf "%.1s" $(cat file) | wc -c

わかれば教えてください。
一連、動作なんですが、特に書式指定子の.(ドット)の意味がわからないです。
0819名無しさん@お腹いっぱい。2006/07/23(日) 23:32:36
>>818
man printf
info printf
0820名無しさん@お腹いっぱい。2006/07/23(日) 23:33:47
まあどうせ探せんだろうから、.は小数点。.2は小数点以下2桁
0821名無しさん@お腹いっぱい。2006/07/23(日) 23:34:16
>>819
それだとなんか英語のようなものが表示され、(END)のところでハングたので、
パソコンをリセットしてしまいました。
0822名無しさん@お腹いっぱい。2006/07/23(日) 23:52:04
その釣り何度めだ。
0823名無しさん@お腹いっぱい。2006/07/24(月) 22:52:41
>> 819 さん 820 さん
ありがとうございます。
コマンド実行結果は、1 or 2 のどちらが正しいのでしょうか?
0824名無しさん@お腹いっぱい。2006/07/25(火) 08:30:20
>>823
オレの環境では、マンド実行結果は 0になる。
0825名無しさん@お腹いっぱい。2006/07/25(火) 16:35:46
はじめまして超初心者です。会社の嫌がらせでパソコンぐらいしか使ったことない
私にshellを作れといわれて苦労している45才です。教えてください。

問題が、日付を手入力したときに正常な日付かどうかと、うるう年の計算
方法です。たとえば20051313はエラーですが20060220は正常ですよね。そのときに
曜日も表示したいのでやり方をすいませんがはじめから詳しく教えてください。
すいませんが、お願いします。
0826名無しさん@お腹いっぱい。2006/07/25(火) 16:42:21
いい加減見飽きた。
0827名無しさん@お腹いっぱい。2006/07/25(火) 16:45:46
shellってゆうなクズ。
0828名無しさん@お腹いっぱい。2006/07/25(火) 16:59:35
空ageすんな得た。
0829名無しさん@お腹いっぱい。2006/07/25(火) 19:39:01
いまのプロジェクトでも
シェルスクリプトで日付計算やってるのを数箇所で見て、げんなり。

どうしてもやりたいなら自前で演算するんじゃなくて、
ダミーファイルをtouchするとか、外部でPerlでもよんでほしい。
0830名無しさん@お腹いっぱい。2006/07/25(火) 20:18:08
最近じゃdateで大概のことができるし
0831名無しさん@お腹いっぱい。2006/07/25(火) 21:26:13
date -d 2006/02/02 +%A とかすりゃ曜日出るしね。日付部分は不正だとエラーにも
してくれる。数字8桁はさすがに食ってくれないようだが、ちょいと/を付け足して食わせりゃ
出来上がりだ。
0832名無しさん@お腹いっぱい。2006/07/25(火) 21:34:06
俺の環境ではこうなる。

$ date -d 20060230
Thu Mar 2 00:00:00 JST 2006

数字8桁でもそのまま日付として食ってくれるが、
2月30日はご丁寧にも3月2日として解釈してくれる。

ま、これも、
if [ `date -d 20060230 +%Y%m%d` = 20060230 ]; then

とかでチェックすれば済むことだな。

それより、>>825 はコピペだから詳しくは答えてあげない。
めでたくリストラされてください。
あ、もし自宅が借り上げ社宅なら、リストラ前に個人契約に変更しといた方がいいよ。
リストラ後だと保証人とかの問題で部屋が借りにくくなるから。
0833名無しさん@お腹いっぱい。2006/07/25(火) 23:30:41
>>832 は社宅を追い出されたことがあるの?
0834名無しさん@お腹いっぱい。2006/07/26(水) 11:13:09
dateコマンドを使う方法だと、1969年以前の日付や、2038年以降の日付に対応できないな。
0835名無しさん@お腹いっぱい。2006/07/26(水) 12:02:44
つcal
0836名無しさん@お腹いっぱい。2006/07/26(水) 12:19:54
>>835 は質問の意味を取り違えているようだ。
0837名無しさん@お腹いっぱい。2006/07/26(水) 12:25:09
日付から曜日求める Zellerの公式を使って expr で計算すればできるな。
あと、日付の正当性チェックは閏年、大小の月で case文あたりで場合わけ判断と。
とは言っても、シェルスクリプト自体超初心者の >>825 には無理。
リストラされろ。
0838名無しさん@お腹いっぱい。2006/07/26(水) 13:00:24
>>825-838
>>407-413
0839名無しさん@お腹いっぱい。2006/07/26(水) 13:02:49
>>1を読めまで読んだ
0840名無しさん@お腹いっぱい。2006/07/26(水) 13:23:45
>>838
欲嫁。>>408 では日付の正当性チェックはできてない。曜日計算のみ。
あと、曜日計算なら >>408 よりももっと簡単にできる。
0841名無しさん@お腹いっぱい。2006/07/26(水) 22:41:35
>>825
どうしても解決したいなら、有料でもいいのだろ?
職業別電話帳見ると、街の便利屋さん(何でも屋さん)みたいなの載ってるだろ。
そこに電話して頼め。
もちろん、その便利屋さん本人はshellだのUNIXだの言っても知らないだろうが、
相手もプロだ。shellとかUNIXとかキーワードを頼りにそれ関係の詳しい人に
取り次いで問題を解決してくれる。特殊な用件だから少々高く取られるかもね。
0842名無しさん@お腹いっぱい。2006/07/28(金) 14:25:42
これなんかどう?
# valid-date - validate date, taking into account leap year rules
ttp://www.intuitive.com/wicked/showscript.cgi?007-valid-date.sh
0843名無しさん@お腹いっぱい。2006/07/30(日) 13:16:38
すごくダさいと思った
0844名無しさん@お腹いっぱい。2006/08/05(土) 11:51:54
超初心者的な質問ですが優しい人、教えてください。

Grepを使った検索スクリプトについて

1) あるテキストファイル(Pattern.txt)に検索対象文字列が改行単位で入っている。
2) この文字列ひとつひとつをパターン文字として、/apl/usr配下のファイルをGrepしたい。
3) 最終的にRESULTファイルに以下のような形式に保存したい。(RDB取込用ファイルの作成)
     <検索対象文字列> , <ヒットしたファイル名>

多分、Ptternファイルを一行ずつ読み込んで、Grepする処理を
ループさせるようなスクリプトになると思うんですけど・・

0845名無しさん@お腹いっぱい。2006/08/05(土) 12:31:30
http://pc8.2ch.net/test/read.cgi/unix/1152364804/532
はいはい、マルチマルチ。
0846名無しさん@お腹いっぱい。2006/08/06(日) 00:31:32
質問です
CGIやPHPでシェルスクリプトを実行するにはどうしたらできますか?
実行方法がわからないのでおしえてください。
0847名無しさん@お腹いっぱい。2006/08/06(日) 00:45:02
>>846
(1)先頭に
#!/bin/sh
のように陽にshellのmagicを書いておいて、
(2)CGIやPHPが動くときのuser id での実行許可をたてて、
(3)system()やexec()を呼ぶ。スクリプトのパスは原則フルパスで。
0848名無しさん@お腹いっぱい。2006/08/06(日) 00:46:03
>>847
ちょw
08498472006/08/07(月) 03:14:47
え?駄目かえ?厨なりに一所懸命に考えたんだが。
0850名無しさん@お腹いっぱい。2006/08/07(月) 03:36:41
(1) ホームセンターに行き鉄定規を購入
(2) CGI鯖のあるプロバイダに接続
(3) 鉄定規をF5キーの箇所に置き、ハイパーオリンピックの要領で弾く
(4) 頃合いを見て80番ポートからログイン
(5) 自分のディレクトリの実行許可を書き換え
(6) /bin/shを実行
0851名無しさん@お腹いっぱい。2006/08/07(月) 03:54:34
>>849
CGIとPHPが一緒くたな時点で「ちょw」
CGIは文字通りインターフェースだから、シェルスクリプト自体を直接実行できるのをわるれるな。
0852名無しさん@お腹いっぱい。2006/08/07(月) 09:06:47
「わるれるな」に、ちょw
0853名無しさん@お腹いっぱい。2006/08/11(金) 23:09:46
% echo a:~
a:~

となるのに、
% a=a:~
% echo $a
a:/home/giko
となるのはなぜですか?
0854名無しさん@お腹いっぱい。2006/08/11(金) 23:44:49
なんでだろね♪
0855名無しさん@お腹いっぱい。2006/08/12(土) 00:27:26
bashだからか?
0856名無しさん@お腹いっぱい。2006/08/12(土) 00:43:01
>>855
NetBSD の sh と zsh でそうなりました。
0857名無しさん@お腹いっぱい。2006/08/12(土) 00:57:13
$ a=a:~; export a
$ export a=a:~

このふたつの違いを考えてみるとわかる。
~ がコマンド引数の一部なのか、変数代入文なのか。
0858名無しさん@お腹いっぱい。2006/08/12(土) 01:16:36
>>857
どっちの echo $a の結果は同じなのですが…
0859名無しさん@お腹いっぱい。2006/08/12(土) 01:34:16
うそーん。うちの sh は違う結果になるが。
0860名無しさん@お腹いっぱい。2006/08/12(土) 01:35:05
うちの、つーてもわからんか。FreeBSD 5.4 の /bin/sh。
0861名無しさん@お腹いっぱい。2006/08/12(土) 16:04:10
なんでだろ〜おなんでだろ〜
0862名無しさん@お腹いっぱい。2006/08/12(土) 16:44:30
PATH=~/hoge:~/fuga
てことがしたくて変数代入のときだけ小細工してるから
0863名無しさん@お腹いっぱい。2006/08/12(土) 19:24:24
Tilde Substitution.

After alias substitution is performed, each word is checked to see if it begins with an unquoted ~. For tilde substitution, word
also refers to the word portion of parameter expansion (see ParameterExpansion below). If it does, then the word up to a / is
checked to see if it matches a user name in the password database (often the /etc/passwd file). If a match is found, the ~ and
the matched login name are replaced by the login directory of the matched user. If no match is found, the original text is left
unchanged. A ~ by itself, or in front of a /, is replaced by $HOME. A ~ followed by a + or - is replaced by the value of $PWD and
$OLDPWD respectively.

In addition, when expanding a variable assignment, tilde substitution is attempted when the value of the assignment begins with
a ~, and when a ~ appears after a :. The : also terminates a ~ login name.

つまり普通はワードの先頭が~のときしかtilde substitutionが行われないが、変数代入のときだけは:の後でもやる
というわけね。これはいかにも知ってないと混乱しそうな仕様だな。便利は便利なのだろうが。
0864名無しさん@お腹いっぱい。2006/08/12(土) 22:10:32
HOME_DIR="/export/home/.../..." ; export HOME_DIR
このような書き方を良く見かけるんだが、2行に分けず
1行にまとめて書いてるのは、何か技術的な理由があるの?
それとも、ただ単に行の節約とか見やすさを考慮しただけ?
0865名無しさん@お腹いっぱい。2006/08/12(土) 22:20:56
書いた奴の気分
0866名無しさん@お腹いっぱい。2006/08/12(土) 22:39:34
export HOME_DIR="/export/home/.../..."
このような書き方を良く見かけるんだが、2行に分けず
1行にまとめて書いてるのは、何か技術的な理由があるの?
それとも、ただ単に行の節約とか見やすさを考慮しただけ?
0867名無しさん@お腹いっぱい。2006/08/12(土) 22:47:22
# 一個でコメントアウトできる。(という事まで考えているかは知らない)
0868名無しさん@お腹いっぱい。2006/08/17(木) 16:30:16
20060817ってな感じの日付を
基準時点 (UTC の 1970 年 1 月 1 日 00:00:00; time(3) 参照) からの秒数
に変換するスマートなやりかた教えて
0869名無しさん@お腹いっぱい。2006/08/17(木) 16:40:48
>>868
date -u +%s -d 20060817
0870名無しさん@お腹いっぱい。2006/08/17(木) 16:42:31
% date -d 20060817 +%s
1155740400
0871名無しさん@お腹いっぱい。2006/08/17(木) 16:42:49
うちのdateだとこうかな
date -j -f "%Y%m%d%H%M%S" 20060817000000 +%s
0872名無しさん@お腹いっぱい。2006/08/17(木) 16:42:50
20060817がJSTなら -u は要らない。
date +%s -d 20060817
0873名無しさん@お腹いっぱい。2006/08/17(木) 17:23:45
>>866
・その文法しか知らないから
・その文法をサポートしている OS でしか動かす予定がないから
・その文法をサポートしてない /bin/sh を持つ OS への嫌がらせ
のいずれか
0874名無しさん@お腹いっぱい。2006/08/17(木) 17:28:15
>>866 は、質問じゃなくて >>864 の修正コピペだろ。

で、>>864 は、>>866 的な exportと代入を同時にやる bash依存文法に反対する意味をこめて
あえて1行で書いてるんだと思う。

でも、俺的には

HOGE=hoge
HAGE=hage
export HOGE HAGE

↑の書き方が好み。
08758682006/08/17(木) 18:07:27
サンクス
869,870は無理だった
871でおk FreeBSD

0876名無しさん@お腹いっぱい。2006/08/17(木) 18:17:31
>>874
export VAR=value
をbash依存文法とする根拠を述べよ。


0877名無しさん@お腹いっぱい。2006/08/17(木) 18:34:09
>>876
「bashで使えて Bourne shで使えないから」そのままやん。

先に言っとくと、*BSDのsh=ash≠Bourne shだからね。
0878名無しさん@お腹いっぱい。2006/08/17(木) 18:37:17
>>876
やれやれ。最近は export VAR=value がbash依存文法であることも知らない新参者が多いのう。
0879名無しさん@お腹いっぱい。2006/08/17(木) 18:48:28
なぜかほこらしげ
0880名無しさん@お腹いっぱい。2006/08/17(木) 19:50:30
>>878
bash依存というより、ksh依存といった方が正しい。
0881名無しさん@お腹いっぱい。2006/08/17(木) 20:06:58
bash依存というけれど他がbashに合わせるべきだよね。
立場をわきまえないと。
0882名無しさん@お腹いっぱい。2006/08/17(木) 22:22:58
ああ、どれが釣りなのかわからん…

"export var=value"という書き方はPOSIXシェルで有効な文法で、
bash依存の仕様と言うわけではない。
SolarisではkshはPOSIXとの互換性を使いたい場合のシェルで、
/bin/shは上記文法を受け付けず、POSIXに準拠しない。
0883名無しさん@お腹いっぱい。2006/08/18(金) 00:24:41
>>878
POSIXくらいは確認してから書こうな。テンプレにも入れてあるんだし。
0884名無しさん@お腹いっぱい。2006/08/18(金) 00:47:04
で、POSIX準拠かどうかということが実践では役に立たないのも事実なわけで、
POSIXよりも、「/bin/shで使える文法かどうか」の方が重要。
0885名無しさん@お腹いっぱい。2006/08/18(金) 01:17:06
/bin/shがPOSIX準拠でないOSにはそろそろ引退してもらいましょう
0886名無しさん@お腹いっぱい。2006/08/18(金) 02:45:19
仕事で使うなら、いいわけもえり好みもできない。
だから確実性が最優先だし、選択肢が存在すると考えること自体が間違い。
/bin/shが何者か分からなければ、bourne shellサポート範囲内かつbash拡張範囲外で書くべき。

POSIXシェルでなければならない理由が本当にあるかどうか分からないが、
もし仮に本当に必要ならば明示的に指定して使ってやればいいんだよ。
/bin/bashや/bin/xpg4/sh(Solaris)や/bin/ksh(Solaris)が存在するなら
ベンダが保証したPOSIXシェルとして使えるんだから、
何者か分からない/bin/shをおっかなびっくり使うよりマシ。
0887名無しさん@お腹いっぱい。2006/08/18(金) 07:39:23
autoconfが生成するconfigure.shはnon-POSIXでも動くよう書かれているんだよね...
0888名無しさん@お腹いっぱい。2006/08/18(金) 07:57:41
そういうクズなシステムを例にだしてもなんの意味も無い。
0889名無しさん@お腹いっぱい。2006/08/18(金) 08:11:18
一番混乱させているのが、*BSD。

Linux(の多くのディストロ)は標準をbashと決めているから、そういうものとして理解すればいいが、
*BSDの/bin/shはそれぞれで勝手に拡張されているし、バージョンによってコロコロ変わってたりするから、
わかりにくい。
0890名無しさん@お腹いっぱい。2006/08/18(金) 08:14:41
FreeBSDのshで、printfが外部コマンドに変更されたのは許せん。
0891名無しさん@お腹いっぱい。2006/08/18(金) 08:31:30
実装違いに悩まされないためにPerlで書いてしまう手もあるが
やはり/bin/shで何とかするのが心意気というものであろう
0892名無しさん@お腹いっぱい。2006/08/18(金) 11:31:48
実行前にshを調べてperlで整形すれば解決ですよ。
■ このスレッドは過去ログ倉庫に格納されています