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

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

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。2005/04/17(日) 00:17:17
シェルスクリプトの総合スレです。スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-10くらい)をご覧ください。

□前スレや過去スレ:
シェルスクリプト総合 その1
http://pc8.2ch.net/test/read.cgi/unix/1101820646/
☆シェルスクリプトを勉強するにあたって☆
http://pc5.2ch.net/test/read.cgi/unix/989659936/
便利なシェルスクリプト見せろ
http://pc5.2ch.net/test/read.cgi/unix/996949546/
【貝】第1回シェル講座【殻】
http://fun.kz/test/read.cgi/unix/1016372780/

□関連スレ:
sed
http://pc8.2ch.net/test/read.cgi/unix/1085730992/
おまえら! shell は何を使っているんですか?
http://pc5.2ch.net/test/read.cgi/unix/1012330865/
Eshell の使い方とか設定とか【Emacs Shell、Lisp】
http://pc8.2ch.net/test/read.cgi/unix/1102921590/

□他板の関連スレ:
Macでシェルスクリプト総合 Part 1
http://pc7.2ch.net/test/read.cgi/mac/1105074933/
【Shell】どのシェル使ってる?【Script】
http://pc8.2ch.net/test/read.cgi/linux/1067330754/
02622572005/06/03(金) 19:08:53
>>261
stat(1)のない古めのOSもあるんです。

POSIX標準の話を付け加えれば、stat(1)は標準にないようです。
0263名無しさん@お腹いっぱい。2005/06/03(金) 19:21:44
とりあえず進む。ダメな環境にぶち当たった時点で個別に考える。
0264名無しさん@お腹いっぱい。2005/06/03(金) 22:06:44
>>259
なんでwc嫌なの? wcだってfstatしてるだけじゃない。
0265名無しさん@お腹いっぱい。2005/06/04(土) 00:40:25
>264
どのUNIXでも、wc -cはfstatするの?
02662652005/06/04(土) 00:51:41
Solaris 9 はreadの繰り返し。
Red Hat Linux 9 は fstat64
FreeBSD 4.xはfstat
0267名無しさん@お腹いっぱい。2005/06/04(土) 14:40:08
> wc呼ぶぐらいなら、Cのコードで行くとは思いますが...
じゃあスレ違いなんでどっか行ってください。
0268名無しさん@お腹いっぱい。2005/06/04(土) 17:50:01
ファイルサイズもまともに取れないOSって糞ですね
0269名無しさん@お腹いっぱい。2005/06/04(土) 19:23:01
>>268
必死だなw
0270名無しさん@お腹いっぱい。2005/06/04(土) 23:41:27
関数を呼び出してその戻り値をある変数に入れたいのですがどうやればいいのか分りません。

    VAL=func1()

としただけでは
line 3: syntax error near unexpected token `('
となってしまいます。
0271名無しさん@お腹いっぱい。2005/06/04(土) 23:45:31
func1
VAL=$?
0272名無しさん@お腹いっぱい。2005/06/04(土) 23:49:47
>>271
ありがとうございます。さすがシェルスクリプトですね。ダサすぎますw
PerlやRubyが流行るのも分るような・・・
0273名無しさん@お腹いっぱい。2005/06/04(土) 23:57:14
>>271 で取得出来るのは終了ステータスだが、それで良いのか?
インタラクティブ用途がメインの言語にケチ付けるのもアレだな
0274名無しさん@お腹いっぱい。2005/06/04(土) 23:57:37
関数呼び出しに()はいらないよ
0275名無しさん@お腹いっぱい。2005/06/05(日) 00:10:23
>>273>>274
関数内でreturnした値が得られたみたいです。
$ function hello(){ return 3;};hello;echo $?
3
ただし、returnできる値はunsigned charに限られるようで、
0〜255までの値しか返せませんでした。ここは注意しないとダメっぽいです・・・

あともう一つお願いします。
$ if [ echo ];then echo "true";fi
true
$ if [ echo "abc" ];then echo "true";fi
bash: [: echo: unary operator expected

これはどうしてなんでしょうか?
0276名無しさん@お腹いっぱい。2005/06/05(日) 00:18:39
>>275
>unary operator expected

って書いてある通り
0277名無しさん@お腹いっぱい。2005/06/05(日) 00:39:38
$ if(echo "abc"&&date);then echo "true";fi
abc
Sun Jun 5 00:39:09 JST 2005
true

testをやめて()にしたら、なぜだかいきました。
でも()ってたしかサブシェルの起動だったような・・・よくわからん
0278名無しさん@お腹いっぱい。2005/06/05(日) 00:45:13
if echo "abc";then echo "true";fi
ってどうなるかわかる?
0279名無しさん@お腹いっぱい。2005/06/05(日) 00:55:16
>>277
なんか基本的な部分が分かってない気がする。
とりあえず、man testしてみなさい。
0280名無しさん@お腹いっぱい。2005/06/05(日) 01:08:54
いや、たぶん man sh をじっくり読むべきじゃないかな。
それが bash なら test の説明もあるし。

>>272
Perl や Ruby よりもシェルスクリプトが勝る点は、
どんなアホにもすぐに書き散らかすくらいのことは出来るようになるってこと
だからしょうがないよ。がんばれ。
0281名無しさん@お腹いっぱい。2005/06/05(日) 01:08:59
man sh だろ。
0282名無しさん@お腹いっぱい。2005/06/05(日) 01:09:45
>>279
test(1)の中の記述で、

  (expression) True if expression is true.

というものがあるんですが、これはなんでしょう?

>>278
ifというのは「以下に続くコマンドを実行した、その終了ステータスを
判定する」ということなのですね。
$ if cat /etc/password > /dev/null 2>&1;then echo "true";else echo "false";fi
false
$ if [ -z `cat /etc/password` ];then echo "true";else echo "false";fi
cat: /etc/password: No such file or directory
true

先のif(echo "abc"〜では、起動したサブシェルの終了ステータスを
判定していたということですか。なるほど。
0283名無しさん@お腹いっぱい。2005/06/05(日) 01:11:25
>Perl や Ruby よりもシェルスクリプトが勝る点は、
>どんなアホにもすぐに書き散らかすくらいのことは出来るようになるってこと
〜よりも〜が の用法が逆です。
0284名無しさん@お腹いっぱい。2005/06/05(日) 01:21:54
あと最初に戻って、
$ test echo
$ test ! echo
これらがなんのメッセージも出さないのはちょっと謎です。
まあどうでもいいか。
0285名無しさん@お腹いっぱい。2005/06/05(日) 01:45:59
>>284
うちの man test には以下の記述があります。

s1 True if s1 is not the null string.

なんのメッセージも出さないのは、そもそも echo が実行されないからですね。
0286名無しさん@お腹いっぱい。2005/06/05(日) 03:13:50
>>282
括弧を付けてもいいってこと。まあ普通は付けない
>>284
test echoはtest hogeと同じ
0287名無しさん@お腹いっぱい。2005/06/05(日) 03:48:56
>>265
しない例を挙げてください
0288名無しさん@お腹いっぱい。2005/06/05(日) 04:13:41
(´・ω・`)
0289名無しさん@お腹いっぱい。2005/06/05(日) 13:09:11
>>288 ハゲワロス 壺にハマッタ〜 (゜∀。)ワヒャヒャヒャヒャヒャヒャ
0290名無しさん@お腹いっぱい。2005/06/06(月) 22:14:47
真か偽か、コレの表示出すにはどないしたらええの?
0291名無しさん@お腹いっぱい。2005/06/06(月) 22:17:07
echo 真か偽か
0292名無しさん@お腹いっぱい。2005/06/06(月) 22:40:07
test hoge && echo 真 || echo 偽
0293名無しさん@お腹いっぱい。2005/06/09(木) 23:15:07
/var/qmail/bin/maildir2mbox && exec elm ${1+"$@"}
この ${1+"$@"} ってどういう意味?
0294名無しさん@お腹いっぱい。2005/06/09(木) 23:41:09
本家 Bourne シェルにあったバグを避けるおまじない。
詳しい意味はUNIXプログラミング環境に書いてあった
希ガス
0295名無しさん@お腹いっぱい。2005/06/10(金) 07:25:39
本家Bourne shellの系統と思われるSolaris/SunOSの/bin/shでさえ、
${1+"$@"}と書く必要はなかったよ。
(引数ゼロ個の場合、"$@"は空文字列にならず、完全に消えてくれる)

今時、"$@"でいいんじゃないか?
逆に、${1+"$@"}と本当に書かなきゃならないshが存在するOSを
教えてくれ。
0296名無しさん@お腹いっぱい。2005/06/10(金) 08:24:03
つくればあるもーん
0297名無しさん@お腹いっぱい。2005/06/10(金) 09:42:11
ハッキングから、消防のたわごとまで、これが うにっx クオリティ
0298名無しさん@お腹いっぱい。2005/06/10(金) 22:27:08
sed の d と D の違いを教えてください。
>d
> パターンスペースを削除する。次のサイクルを開始する。
>D
> パターンスペースの最初の改行までを削除する。次のサイクルを開始するが、パターンスペースにまだデータが残っていたら、入力からの読み込みをスキップする。
0299名無しさん@お腹いっぱい。2005/06/10(金) 22:33:39
>>298
sedはsedスレへ
http://pc8.2ch.net/test/read.cgi/unix/1085730992/l50
0300名無しさん@お腹いっぱい。2005/06/14(火) 23:20:41
1時間に10000個のファイルを消そうとしているのですが
forで回してひとつひとつ消すと
時間はかかるけどvmstatで表示されるidが95 をキープする。
forのなかで5個ずつ消すと
時間はかからないけどidが90を切っちゃう。

時間かけず、idを高く保って、大量のファイルを削除する方法ありますきあ?
0301名無しさん@お腹いっぱい。2005/06/14(火) 23:24:24
xargs
0302名無しさん@お腹いっぱい。2005/06/14(火) 23:31:43
>>300
idって何よ。priorityあるいはniceか?どっちにしてもエスパーな質問だな……
0303名無しさん@お腹いっぱい。2005/06/14(火) 23:47:02
>>302
vmstatコマンドを打つとcpuのしたにus,sy,idと表示されますよね?
idleだとおもいます。
0304名無しさん@お腹いっぱい。2005/06/15(水) 00:16:38
思いますじゃなくてmanを嫁。
0305名無しさん@お腹いっぱい。2005/06/15(水) 00:24:48
idle timeだよね
0306名無しさん@お腹いっぱい。2005/06/15(水) 05:12:02
>>300
ファイルを削除ディレクトリに移動してディレクトリごと削除
0307名無しさん@お腹いっぱい。2005/06/15(水) 09:32:12
>>306
移動の時に同じ質問が
時間かけず、idを高く保って、大量のファイルを移動する方法ありますきあ?
0308名無しさん@お腹いっぱい。2005/06/15(水) 10:09:42
そもそも何でそんな馬鹿げた要求が出てきてるのかわからんなぁ。
idle を増やしたいなら、ファイル消すたびに sleep 10 とかしたら?

>forのなかで5個ずつ消すと

rm file1; rm file2; ... と rm file1 file2 ... で
だいぶ違うわけだがどっちよ?
0309名無しさん@お腹いっぱい。2005/06/15(水) 20:21:21
借鯖とかでキャップされてるんじゃないの
0310名無しさん@お腹いっぱい。2005/06/16(木) 00:09:18
>>308

rm file1 file2
でしょ

rm file1; rm file2;
は時間かかるぽい
0311名無しさん@お腹いっぱい。2005/06/16(木) 06:27:49
fork に時間がかかるんでしょ
じぶんで thread で unlink するコマンドを書けば
0312名無しさん@お腹いっぱい。2005/06/16(木) 07:42:19
じぶんで thread で unlink するコマンドを書けるシェルなんてあるのか?

まぁ正解はシェルスクリプトで書くのをあきらめろってとこか。
0313名無しさん@お腹いっぱい。2005/06/16(木) 08:04:16
つ[Java]
0314名無しさん@お腹いっぱい。2005/06/16(木) 20:58:46
基本的なことで悩んでいます。
コマンドラインから
ls -ld /hoge/???/????? | awk "{print $9}"
と実行しますと<結果1>のように動作するのですが、
このコマンドをsh(bash)で実行すると<結果2>のように
エラーが吐かれてしまいます。
どのようにすればshで動作させることが出来るのか教えていただけないでしょうか?

<結果1>
/hoge/aaa/bbbbb
/hoge/aaa/ccccc
/hoge/ddd/eeeee




<結果2>
sh -xf hoge.sh
#ls -ld /hoge/???/?????
/hoge/???/?????は見つかりません。
0315名無しさん@お腹いっぱい。2005/06/16(木) 21:15:14
>>314
ルートにhogeはあるのか?
03163142005/06/16(木) 21:31:28
>>315さん
ルートにhogeがあります。
補足説明しますと、
今回求めたいディレクトリは
ルート直下のhogeの中に/日付/時間と作られています。
パスの長さは一定なのでワイルドカードの[?]を用いて取得したのですが、
shに組み込むとうまくいかなかったのです。
0317名無しさん@お腹いっぱい。2005/06/16(木) 21:49:28
sh -c 'ls -ld /hoge/???/????? ' してみたらどうなる?
0318名無しさん@お腹いっぱい。2005/06/16(木) 22:26:41
awk '{print $9}'
0319名無しさん@お腹いっぱい。2005/06/16(木) 22:30:34
>>315
sh -xf しちゃ駄目だよ。
f はワイルドカード禁止オプション。
sh -x hoge.sh
でやってみろ。

あと、回答してる香具師、みんなハズシ。
0320名無しさん@お腹いっぱい。2005/06/16(木) 22:46:14
ここってC言語スレより殺伐としてないですね・・・。
03213142005/06/16(木) 22:56:16
>>317さん、318さん、319さん
回答有難うございます。
只今実行できる環境ではないので報告は明日になると思います。

>-f はワイルドカード禁止オプション。
知りませんでした。。。
0322名無しさん@お腹いっぱい。2005/06/16(木) 23:02:51
知らないオプションむやみにつける癖やめたほうがいいよ。
ディレクトリ消すとき 必ず rm -fr するタイプ?
0323名無しさん@お腹いっぱい。2005/06/16(木) 23:08:08
それがなんかいかんのか?
0324名無しさん@お腹いっぱい。2005/06/16(木) 23:20:13
>>323
美しくない。
0325名無しさん@お腹いっぱい。2005/06/16(木) 23:31:12
わけもわからずperl -wと付けていた時期が俺にもありました
0326名無しさん@お腹いっぱい。2005/06/16(木) 23:34:36
-f 付けるのはCシェルスクリプターだね
03273142005/06/18(土) 03:08:00
結果報告。
「-f」を外した所無事に出来ました。
有難うございました。
何故「-f」を付けたかというと、手元にあった書籍に書いてあったと認識してたんですけど
再度読み直してみるとそんな事は一言も書かれてませんでした。
凹みました。

>>322さん
するタイプであります・・・
0328名無しさん@お腹いっぱい。2005/06/18(土) 20:07:42
>>324
後学のために美しいやりかたを教えてくれたまえないか
0329名無しさん@お腹いっぱい。2005/06/18(土) 20:51:30
rm -r ですむときは -f は除いたほうがいいし、
rmdir ですむときはそうしろってことじゃないの。
美しい美しくないというより、
rm -fr は危ない。
0330名無しさん@お腹いっぱい。2005/06/18(土) 23:57:02
f なんかなくてもサクっと消えてくれます
0331名無しさん@お腹いっぱい。2005/06/19(日) 18:15:14
おれはmvもrmも-iつきでエイリアスしてるけど、

ワイルドカードや再帰削除の場合はいちいち聞かれるとウザいので
-fつける。でもこういう危険な場合に限って-fつけるんでは、実は
あまり意味が無い気がする

二回ぐらい
rm -f *.jpg
のつもりで
rm -f *>jpg
とtypoして、カレントディレクトリの中身全削除したことある。
シフトキーの入力が甘かったりするとこうなる。
0332名無しさん@お腹いっぱい。2005/06/19(日) 18:22:38
rmはゴミ箱スクリプトにすればよい。
0333名無しさん@お腹いっぱい。2005/06/19(日) 21:21:53
touch ' -i'
0334名無しさん@お腹いっぱい。2005/06/20(月) 00:43:47
>>333
touch ./-i
やってみたが、目からウロコ
0335名無しさん@お腹いっぱい。2005/06/20(月) 08:16:33
http://www.nurs.or.jp/~asada/FAQ/UNIX/section3.6.html
0336名無しさん@お腹いっぱい。2005/06/20(月) 18:23:18
ダウンロードしたファイルを、ファイルの作成日ごとに、日付の入ったフォルダを作成して、移動するうまい方法ってありませんか?
もしよろしければ、何か手がかりをください。
0337名無しさん@お腹いっぱい。2005/06/20(月) 19:12:39
m9(^Д^)プギャーーーッ
0338名無しさん@お腹いっぱい。2005/06/20(月) 19:13:00
>>336
まず、「日付の入ったフォルダ名」の名称自体を得るには、
dateコマンドに適当なスイッチをつければよい。厳密には
環境依存だからmanせよ。

つぎに、あるコマンド(例えばdate)の結果(標準出力)を
変数に入れたり、もしくは他のコマンドで利用するには、
backquoteを使う。
value=`...`
とか、
mkdir `....`
ね。これで、目的の名前のフォルダできるだろ。

あとは、適当に移動(mv)せよ。

0339名無しさん@お腹いっぱい。2005/06/20(月) 19:32:17
>>338
ありがとうございます。
0340名無しさん@お腹いっぱい。2005/06/20(月) 19:32:38
>>337
> m9(^Д^)プギャーーーッ

笑わないでください。
0341名無しさん@お腹いっぱい。2005/06/20(月) 20:17:47
任意のリモート・ホストの、任意のディレクトリが存在するか
チェックするにはどのようなすればよいでしょうか?
rshとかtestでがんばってたんですが、挫折しました・・・
0342名無しさん@お腹いっぱい。2005/06/20(月) 20:32:04
>>341
ssh HOST test -d DIR
0343名無しさん@お腹いっぱい。2005/06/20(月) 20:32:36
>>341
ssh 使え。
ssh foo test /foo
echo $?
0344名無しさん@お腹いっぱい。2005/06/21(火) 01:51:02
任意のファイルを先頭n列、後ろからm列を取り除いたファイルに
編集したいんですが、どうすればいいでしょうか?
Cでやるのは避けたいんだけど。。。
0345名無しさん@お腹いっぱい。2005/06/21(火) 01:59:08
>>344
cut
0346名無しさん@お腹いっぱい。2005/06/21(火) 02:05:36
>>345
詳しく
0347名無しさん@お腹いっぱい。2005/06/21(火) 02:07:02
>>346
man cut
0348名無しさん@お腹いっぱい。2005/06/21(火) 02:14:08
質問を間違えてた。
任意のファイルを先頭n行、後ろからm行を取り除いたファイルに
編集したいんですが・・

0349名無しさん@お腹いっぱい。2005/06/21(火) 02:16:08
head, tail
0350名無しさん@お腹いっぱい。2005/06/21(火) 02:18:32
head,tailじゃ指定行の表示しかできないでしょ。
0351名無しさん@お腹いっぱい。2005/06/21(火) 02:20:02
>>350
> WORD
Open file WORD for writing as standard output. If the file does
not exist then it is created. If the file exists, and the CLOBBER
option is unset, this causes an error; otherwise, it is truncated
to zero length.
0352名無しさん@お腹いっぱい。2005/06/21(火) 02:20:56
>>350
単独ではな。
0353名無しさん@お腹いっぱい。2005/06/21(火) 02:28:30
うーんわからんです。
ファイルをcatしてパイプで繋げてheadとかですか?
03543482005/06/21(火) 02:43:05
tail 先頭n行-ライン行数
head 後ろm行-ライン行数ってのは思いついたが、
ファイル行数が数万とかだと処理遅いよね・・・
0355名無しさん@お腹いっぱい。2005/06/21(火) 02:44:37
全部でw行あるとして
tail +$((n+1)) |head -$((w-m-n))
0356名無しさん@お腹いっぱい。2005/06/21(火) 19:22:40
tail +$((n+1)) file | tail -r | tail +$((m+1)) | tail -r
0357名無しさん@お腹いっぱい。2005/06/21(火) 20:51:21
結局スクリプトを書くのが早くて速い。

awk 'NR>m{a[NR+n]=$0;if(NR in a) print a[NR]}'
0358名無しさん@お腹いっぱい。2005/06/21(火) 21:35:22
>>355
できました。
ありがとうございました。

結局どれがベストかわかんないけど、、、

0359名無しさん@お腹いっぱい。2005/06/21(火) 21:59:30
スクリプト書いちゃうんだったらrubyで書くぞ。

ruby -e 'ARGF.to_a[n..-m].display'
0360名無しさん@お腹いっぱい。2005/06/22(水) 00:31:22
sedとawkはセーフ
0361名無しさん@お腹いっぱい。2005/06/22(水) 00:50:17
awkは高機能過ぎなので禁止。
0362名無しさん@お腹いっぱい。2005/06/22(水) 06:17:16
wget -i URLリストファイル
で複数サイトを取得し、それをindex.html.1 index.html.2・・のように連番をつけて保存したいのですが、
wget -i url_list.txt -O index.html
だとindex.htmlに次々に上書きしてしまいます。
どのように直すべきか教えてください。よろしくお願いいたします。
■ このスレッドは過去ログ倉庫に格納されています