シェルスクリプト総合 その15at UNIX
シェルスクリプト総合 その15 - 暇つぶし2ch521:名無しさん@お腹いっぱい。
09/10/03 09:28:17
>>481のやり方ってネストは2個まで?

commandD `commandC \`commandA \`commandB\`\``
でやったら上手くいかなかったような。。。(bash)

522:名無しさん@お腹いっぱい。
09/10/03 09:42:57
あたりまえ。\もエスケープしなければダメ。

523:名無しさん@お腹いっぱい。
09/10/03 09:46:57
>521

commandD `commandC ¥`commandA ¥¥¥`commandB¥¥¥`¥``


524:名無しさん@お腹いっぱい。
09/10/03 09:48:20
>>521
3個でもできるよ。

commandD `commandC ¥`commandB ¥¥¥`commandA¥¥¥`¥``

525:名無しさん@お腹いっぱい。
09/10/03 09:50:21
>>522-523
お、言われて見ればその通りだ。
ありがとぅ。

526:名無しさん@お腹いっぱい。
09/10/03 09:51:31
>>524
ありがとぅ。


527:名無しさん@お腹いっぱい。
09/10/04 17:20:27
時々シェルスクリプトで簡単なツールを作ったりしてるのですが
perlを勉強してみたくなりました。

>>1
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。

とありますが、具体的にどのような観点でシェルスクリプトとperlを使い分けするのでしょうか?
このような処理ケースではperlを使う方が効果的みたいな例を教授
(もしくはそのような事が記載されているサイトに誘導)していただけたら幸いです。


528:名無しさん@お腹いっぱい。
09/10/04 17:26:53
現状でシェルスクリプトで問題なくやってるなら、
perlなんて覚えない方がいい。

529:527
09/10/04 17:27:13
少し調べてみてるのですがPerlは文字列処理等が得意であるというのを見ますが、
そうするとsedやawkを使う場面なんかがperlでやった方がよりよいでしょうか?

530:527
09/10/04 17:34:22
>>528

現状、何とか目的の機能は達成してるって感じですが、
同じ事がperlなら断然簡潔かつ高速処理で出来たりするのかな?なんて思うもので。。。

531:名無しさん@お腹いっぱい。
09/10/04 17:47:06
3項演算子は両方とも評価するのか?

532:名無しさん@お腹いっぱい。
09/10/04 18:05:40
>>529
例えば一行の処理毎に、シェルスクリプトでは外部コマンドを起動する必要がある、
perlでは不要。というような場合、データが大きくなればperlの方が速くなる。

533:529
09/10/04 18:31:28
>>532

それはテキストの一行に対して処理する事に対し、シェルスクリプトならその行数分外部コマンドが実行、
つまりシェルスクリプトでテキストの1行に1コマンド処理実行させてる場合、
100行なら100回外部コマンドが実行される事になるが
perlなら1コマンド?で処理が終了するので大きいテキストに対してだと
処理スピードに差がでるって事でしょうか?

534:名無しさん@お腹いっぱい。
09/10/04 18:45:38
テキストの一行じゃないんじゃないの。sedもawkも複数行を処理できるでしょ。
あとマルチコアプロセッサとかだと、プロセスが分かれていた方が処理が早く
終わったりもするね。

キッチンシンクアプローチとツールボックスアプローチを調べてみると良いと思うよ。

535:名無しさん@お腹いっぱい。
09/10/04 18:58:02
>>533
そう。プロセスの生成は非常にハイコスト。

536:529
09/10/04 19:12:23
>>534-535
ありがとう。
うーん、でも完全に理解し切れてない。
何かを実現させる時、シェルスクリプトの場合複数のコマンド発行(プロセス起動)が
perlなら少プロセスで可能な場合(主にテキスト処理などで)があるって事でしょうか?

>キッチンシンクアプローチとツールボックスアプローチを調べてみると良いと思うよ。

調べてみます。

537:名無しさん@お腹いっぱい。
09/10/05 00:38:28
python

538:名無しさん@お腹いっぱい。
09/10/05 02:27:03
オライリーのミニマルPerlって本があって、
sh&sed&awk の粗探しをして Perl への移行を薦めるような内容なんだが、
これ読むと逆に、とくに大規模でもないテキスト処理なら
シェルで無問題じゃんって感じなんだよね。
Perlが受けたのは、第一に実装が優秀で速かったのと、
あと Perl はベル研系の厳格な雰囲気がないというか、
何となく書いて動いちゃうとこがある。そのへんの寛容さが人気の秘密かと

539:名無しさん@お腹いっぱい。
09/10/05 15:57:27
結局適材適所と、それを判断出来る能力の問題だと思うよ。
シェルスクリプトで遅いなら、perlなりでやる。それでも遅いならCとか。


540:名無しさん@お腹いっぱい。
09/10/05 18:06:14
echoで最後に改行したくない場合、
echo -n "unko"
では期待通りに出力されるのですが、
echo "unko\c"
だとunko\cと改行して出力されてしまいます。
Cygwinで\cに対応させるにはどうしたらよいでしょうか。
よろしくお願いいたします。

541:名無しさん@お腹いっぱい。
09/10/05 18:15:13
>>541
CygwinということはGNU coreutilsのechoか。
-e オプション?


542:540
09/10/05 19:05:48
>>541
おおお、ありがとうございます。
$ echo -e "unko\c"
で期待通り
unko$
と出力ができました。

本番の環境はHP-UXを使用しておりまして、
逆に-eオプションが無い(?)ため、
$ echo -e "unko\c"
とした場合、
-e unko$
と出力されてしまいすが、とりあえず、
alias echo='echo -e'
で解決いたしました。

ありがとうございました!!!!

543:名無しさん@お腹いっぱい。
09/10/05 21:56:31
そのへんの移植性に関するバッドノウハウはGNU autotoolsに詰まってる。

544:名無しさん@お腹いっぱい。
09/10/21 12:16:25
RCSで、チェックイン済みの最新リビジョンと、そのひとつ前のリビジョンを比較
ということをよくやります。
今は、rlog -r fileで最新リビジョン番号を調べて、たとえば 1.123 だったとすると、
頭の中でリビジョンを1引いて、rcsdiff -r -r1.122 file みたいに実行しています。
これを1発でやるシェルはできませんか?

あ、sed/awk等でゴニョゴニョやる方法じゃなく(それしかないなら自分でやるので)、
奇麗にエレガントにやる方法を希望します。

545:名無しさん@お腹いっぱい。
09/10/21 18:10:19
よく知らないで申し訳ないが
current=`rlog -r file | grep 'なんとか'`
current=`expr $current - 0.001`
rcsdiff -r -$current file
空白とか改行とか考慮せずかなり適当に書いたけど。

exprでできないならbc使えばできるかもしれない。

546:名無しさん@お腹いっぱい。
09/10/21 18:32:38
それはエレガントじゃないらしいよ

547:名無しさん@お腹いっぱい。
09/10/21 20:25:10
シェルってゆうな。クズ。

548:名無しさん@お腹いっぱい。
09/10/21 22:12:01
エレガントさが求められていたのか
知らんかったよ、すまん

549:名無しさん@お腹いっぱい。
09/10/21 22:41:49
奇麗でエレガントな質問を募集します。

550:名無しさん@お腹いっぱい。
09/10/24 13:10:57
>>545
エレガント云々を除いてもそれじゃ駄目だよ。
リビジョン番号は、 1.8 1.9 1.10 1.11 ... 1.99 1.100 1.101 ...
って進むから、expr で 0.001 引くのは全然見当違い。

551:名無しさん@お腹いっぱい。
09/10/26 22:08:08
どうしてもわからないので質問させてください。

#!/bin/sh

DIR=`pwd`

cd $DIR/file
./play


のようにC言語で記述したplayファイルを実行しているのですが
play内では簡単に表すと以下のような処理をしています

while(true){
ファイルの読み込み処理
sleep(1);
}

このように1秒ごとにファイルを監視してるのですが
シェルスクリプトで実行すると1秒待たずにwhileループが回っているのですが
どうすればよいのでしょうか?

552:名無しさん@お腹いっぱい。
09/10/26 22:13:23
>>551
そのwhileループの具体的なスクリプトを出さずに質問したいなら、
エスパースレに池。

sleepコマンド自体が文法またはオプションエラーになってて
1秒待ててないんじゃないの?

553:名無しさん@お腹いっぱい。
09/10/26 22:15:27
問題点を人に伝える能力が欠けすぎ

554:名無しさん@お腹いっぱい。
09/10/26 22:17:39
>>552
whileループはC言語で書いてるんだろ。(プログラムは出てるじゃん)

コマンドラインで直接 ./play を実行すると1秒毎に処理されるのに、
>>551 のシェルスクリプト経由で ./play を実行すると1秒待たずにループする、
という話だろ。

555:名無しさん@お腹いっぱい。
09/10/26 22:20:28
で、答えは?

556:名無しさん@お腹いっぱい。
09/10/26 22:20:58
>>551
sleep()関数はシグナルで中断される可能性がある。
シグナルが到着すればsleep(1)は1秒未満で終了する。
代わりにnanosleep()使え。

たぶん、シェルスクリプト経由の時だけシグナルが発生するような
別の条件が加わってるんだろ。

557:名無しさん@お腹いっぱい。
09/10/26 22:36:54
>>551
play コマンド側は特に何もせずシェルスクリプト側で sleep 1; すればいいんじゃね?


558:名無しさん@お腹いっぱい。
09/10/26 22:58:35
>>556
ありがとうございます。
試してみましたが同じ状態になりました。

説明が不足していてすみません
GNU Chessを改造していたので、その部分のコードを切り抜いても分かりづらいので自分なりに説明したのですが、説明力がなくてすみません。

ファイルの読み込み部分の処理は

while(true){
sleep(1);
if(rlogfp=fopen("./black.log","r")){
fgets(inp, MAXSTR, rlogfp);
fclose(rlogfp);
remove("./black.log");
break;
}
}


black.logというのは次の手を指定した文字列が収められているファイルです。
C言語で書くのもうまくないので下手なコードですが、ご了承ください。

559:名無しさん@お腹いっぱい。
09/10/26 23:01:09
>>557
whileで監視しているのでsleep(1)がないとファイル作成時に読み込みが実行されるのか、うまくデータが受け取れないので
sleep(1)を追加している次第です。

560:名無しさん@お腹いっぱい。
09/10/26 23:39:32
後からこんなことを追加するのはすみませんが

どうやら監視しているファイルが存在しないのに、ファイルがあるように動いているみたいで、
ファイル読み込む→whileを抜け出す→間違った手だと解釈→whileに入りファイルを読み込む
を繰り返すようになっているみたいです。
シェルスクリプトではなくターム上で実行するとうまくいくのに
スクリプトだとこの現象がおこるのはどういったわけでしょうか?

561:名無しさん@お腹いっぱい。
09/10/26 23:56:55
>>560
シェルスクリプトの cd $DIR/file あたりがうまく行ってないとか。
別のディレクトリの black.logを読んでループしてるとか。

562:名無しさん@お腹いっぱい。
09/10/27 00:11:19
>>561 レスありがとうございます
他のディレクトリではblack.logは生成していないのでそのケースはないかと思います
ディレクトリの場所も間違いはないです

563:名無しさん@お腹いっぱい。
09/10/27 00:23:15
sleepはループの先頭なの?それなら確実に1秒待つでしょ?
説明に一貫性がないと回答者も混乱するし、いいことないよ。
あとは、fgets, fclose, removeの戻り値をちゃんとチェックしてみる。

564:名無しさん@お腹いっぱい。
09/10/27 00:30:07
ぱおーん

ってそれはエレファント

565:名無しさん@お腹いっぱい。
09/10/27 00:40:24
>>551
>シェルスクリプトで実行すると1秒待たずにwhileループが回っている

これはどうやって確認したの?

原因を切り分ける為に、問題を再現出来る最小限の
プログラムを作ってみると良いと思うよ。

566:名無しさん@お腹いっぱい。
09/10/27 00:46:46
>>563,565
アドバイス通り明日調べてみます。


567:名無しさん@お腹いっぱい。
09/10/27 08:05:15
>>559
> whileで監視しているのでsleep(1)がないと
> ファイル作成時に読み込みが実行されるのか、
> うまくデータが受け取れないので

busy waitになるだけでちゃんと動くはずだろ。
だから動かないのは、sleep()以外のところがおかしい。



568:名無しさん@お腹いっぱい。
09/10/27 11:08:26
そのファイル、NFS かなんかの領域に置いてないか?
おかしなキャッシュが効いてるような気がする。

569:名無しさん@お腹いっぱい。
09/10/27 11:38:40
>>568
特に変わった場所には置いてません。

とりあえずthreadやwhileループとファイルの読み込みの部分だけ同じ形でtestファイルを作ってみたのですが
直接実行、シェルスクリプトで実行で共に問題がなかったので、もっと別の場所だと分かりました。
もう少し試行錯誤してみたいと思います。

570:名無しさん@お腹いっぱい。
09/10/27 12:26:31
ちょっと説明が長くなるのでアップロードしてみました。
お手数をおかけしてもうしわけありません。
DLkey:unix

URLリンク(www1.axfc.net)

571:名無しさん@お腹いっぱい。
09/10/27 13:04:39
input_threadが動き出す前にwait_for_inputに入ると、
input_statusが初期値(INPUT_NONE)のままなので、whileを抜けてしまう。

572:名無しさん@お腹いっぱい。
09/10/27 21:14:09
test が表示されないという現象はウチでは一度も再現しませんでした。
Dual Core の Mac です。

外してたらスマソ。

test.sh を実行する
Ctrl-C で test.sh を止める
a.out のプロセスは残ったまま

とかじゃないよね?

まあそれでも test が表示されない理由にはなりませんけど。

573:名無しさん@お腹いっぱい。
09/10/27 21:50:45
一度目がその症状があって
もう一度試したら治っていました

>>571
どのように記述すれば回避できるのでしょうか?
丸投げのようですみません^^;

574:名無しさん@お腹いっぱい。
09/10/28 00:03:20
以前動作していたスクリプトが動かなくなってしまいました…
ここ最近kshのアップデートを行ったのが原因なのでしょうか…

何か情報をお持ちの方いらっしゃいましたらご教授願います。

<事象>
特に問題なく見えるkshがsyntax Error `(' unexpectedで異常終了
コメント内のスペースを1つ削除or2つ追加すると正常に動作する

<やったこと>
kshとbashのアップデート
ksh 20060214-1.4 → 20080202-14.el5
bash bash3.1-16.1 → bash3.2-21.el5

<環境>
redhat Linux 5.1
uname -a結果
Linuc 2.6.18-53.el5 #1 SMP Wed Oct 10 16:34:19 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux

<備考>
ksh -nで構文チェックをかけると、構文エラー以外に「" quote may be missing」という警告が必ずついてきます。
コメントを弄ってエラーを抑止するとこの警告も発生しなくなります。

575:551
09/10/28 00:05:16
. play.shで実行したらうまく動きました。
結局原因はわかりませんでしたが、サブシェルだと何か環境とちがったのかな?と素人ながら思います。
お騒がせしてすみませんでした。

576:名無しさん@お腹いっぱい。
09/10/28 00:59:40
それたまたまだから

577:名無しさん@お腹いっぱい。
09/10/28 01:16:52
while(true)なんてしないで、openの返り値でなんとかならんの?

578:名無しさん@お腹いっぱい。
09/10/28 07:06:37
>>574
おいおい、redhat 5.1というのは10年くらい前のOSで、
カーネルは2.0の時代のもの。(libc5からやっとglibc2に変わった時代)
カーネル2.6で動くわけがない。

579:574
09/10/28 11:18:44
>>578
今確認したところ、redhat 5.1ではなく
RHEL 5.1でした

redhatLINUXとRHELを混同していました
申し訳ありません


580:名無しさん@お腹いっぱい。
09/10/28 11:43:19
>>574
スクリプト晒せ

581:名無しさん@お腹いっぱい。
09/10/28 11:44:15
libc5なつかしいな。
glibc2(libc6)になってようやくLANG関係がマトモになったんだっけ

582:名無しさん@お腹いっぱい。
09/10/28 11:44:22
どうせShift_JISのコメントだろ。

583:574
09/10/28 23:54:47
>>580
手元にスクリプトがない上に動く動かないの条件がよく分からないので再現できず…
申し訳ないです。

>>582
コメント等もう一度文字コードを見直しましたが、すべてUTF-8でした。

584:名無しさん@お腹いっぱい。
09/10/28 23:56:51
手元にスクリプトがないのにコメント等見直した?意味が分からんのだが

585:名無しさん@お腹いっぱい。
09/10/28 23:57:32
不思議な話だなw

586:名無しさん@お腹いっぱい。
09/10/29 22:50:29
LOTO6用の数字列を生成する

for x in $(seq 1 5); do echo $(seq 1 43 | shuf | head -6 | sort -n); done


587:名無しさん@お腹いっぱい。
09/10/30 23:17:20
>>586
for((i=0;i++<5;)){ echo `shuf -i 1-43 -n 6 | sort`; }

↑の方が簡単

588:名無しさん@お腹いっぱい。
09/11/10 09:10:20
質問です。記法1と2では違いがありますか?どちらが正しいとか…
doの後に改行入れるべきかどうなのか,ということですが。

記法1
for i in *
do
echo $i
done

記法2
for i in *
do \
echo $i
done


589:名無しさん@お腹いっぱい。
09/11/10 09:48:42
>>588
記法2は間違いではないがバックスラッシュが余分。
もともと do の直後には、空白、タブまたは改行の区切り文字があればなんでも良い。
「行の継続」をする必要はないので、バックスラッシュは不要。

590:588
09/11/10 11:02:41
>>589
ありがとうございました。

591:名無しさん@お腹いっぱい。
09/11/10 11:33:58
今のトレンドは↓の書き方。
bash依存じゃないぞ。純正シェルでもちゃんと動くから安心して使え。

for i in *
{
echo $i
}

592:名無しさん@お腹いっぱい。
09/11/10 11:37:50
どこのトレンドだよwwwww

593:名無しさん@お腹いっぱい。
09/11/10 11:43:46
for は { ... } でもいいけど、
while は do ... done じゃないといかんというのがアレ。


594:名無しさん@お腹いっぱい。
09/11/12 08:07:11
kshで標準出力と標準エラーをデフォルトでファイル&画面に出力するやり方はありますか?
毎行、| tee -a hoge.log を書くのが大変なので。

595:名無しさん@お腹いっぱい。
09/11/12 08:19:07
>>594

(
command1
command2
command3
:

) 2>&1 | tee -a hoge.log

596:名無しさん@お腹いっぱい。
09/11/12 08:41:02
>>594
scriptコマンドは?

597:名無しさん@お腹いっぱい。
09/11/12 08:58:07
俺はそういうとき
telnet localhost | tee hoge.log
ってやってる

598:名無しさん@お腹いっぱい。
09/11/12 09:27:34
正解(>>595)が出た後にボケ回答(>>596-597)が出てくる、の法則

599:名無しさん@お腹いっぱい。
09/11/13 19:18:09
自分よりいい答えが出たのがそんなに悔しかったのか

600:名無しさん@お腹いっぱい。
09/11/13 19:57:03
> 毎行、| tee -a hoge.log を書くのが大変なので。
毎行と言っているし、ここはシェルスクリプトスレなのでスクリプトの中での記述に
関しての質問だと言う事が容易に予想できる。

スクリプトに関しての質問にscript使えだの、telnetをリダイレクトしろだの、
ボケまくりの回答してる奴らは何なのだろう?
匿名掲示板だからボケ回答も恥ずかしくないのだろうか?

601:名無しさん@お腹いっぱい。
09/11/14 03:03:51
必死だなw

602:名無しさん@お腹いっぱい。
09/11/20 10:11:52
>>599
只の知ったかだろ
半角数字とか学生の分際で早くも理系気取りかよ

603:名無しさん@お腹いっぱい。
09/11/20 10:44:29
>>602
日本語で頼むわ……

604:名無しさん@お腹いっぱい。
09/11/20 20:00:12
> 半角数字とか学生の分際で早くも理系気取りかよ

これは新コピペになりそうな気がする

605:名無しさん@お腹いっぱい。
09/11/21 01:23:51
>>604
新コピペとか学生の分際で早くも理系気取りかよ
…こんな感じ?

606:名無しさん@お腹いっぱい。
09/11/21 02:02:27
bashを使用しています。
数字が入っている変数に3桁毎にカンマを入れる方法が分かりません。
どうやれば3桁毎にカンマを入れれるようになりますか?

607:名無しさん@お腹いっぱい。
09/11/21 12:27:50
>>606
printf "%'d" "$var"

608:名無しさん@お腹いっぱい。
09/11/21 22:05:46
>>607
これはいいことを聞いたと、試してみたができないぞ?
$ bash --version
GNU bash, version 4.0.28(2)-release (i686-pc-linux-gnu)

609:名無しさん@お腹いっぱい。
09/11/21 22:13:00
>>608
varの中にちゃんと数字入れてるか?

610:名無しさん@お腹いっぱい。
09/11/21 22:17:56
>>607 では printfの書式に改行が入ってないから、
シェルのプロンプト設定によってはprintfの出力をプロンプトが上書きしてしまう
とエスパー。

それとは別に、zshの内蔵printfでは動作しないね。

611:606
09/11/21 23:23:18
>>607さん
有難うございました。ウチの環境ではうまくいきました。

612:名無しさん@お腹いっぱい。
09/11/22 14:57:44
$ printf "%'d\n" "123456"
123456
$ var="12345667"
$ printf "%'d\n" "$var"
12345667

なにがいけないのかねー

613:名無しさん@お腹いっぱい。
09/11/22 17:20:06
$ printf "%aqd\n" "123456"

614:名無しさん@お腹いっぱい。
09/11/22 17:29:35
>>612
localeの設定じゃない?
printf(3)によると、

>>printf("%'.2f", 1234567.89);
>>results in '1234567.89' in the POSIX locale, in '1234567,89' in the nl_NL locale,
>>and in '1.234.567,89' in the da_DK locale.

615:名無しさん@お腹いっぱい。
09/11/23 00:52:46
>>614
ロケールの問題でした。ありがとう。
ちょっと気になるのは、printfコマンドする時に
LC_ALLを明示的に与えても上手く動作しなかったんですよね
組み込みコマンドだと伝わらないのかな?

$ locale
LANG=ja_JP.eucJP
LC_CTYPE="ja_JP.eucJP"
LC_NUMERIC=C
LC_TIME=C
LC_COLLATE="ja_JP.eucJP"
LC_MONETARY="ja_JP.eucJP"
LC_MESSAGES=C
LC_PAPER="ja_JP.eucJP"
LC_NAME="ja_JP.eucJP"
LC_ADDRESS="ja_JP.eucJP"
LC_TELEPHONE="ja_JP.eucJP"
LC_MEASUREMENT="ja_JP.eucJP"
LC_IDENTIFICATION="ja_JP.eucJP"
LC_ALL=
$ LC_ALL=da_DK printf "%'d\n" "123456789"
123456789
$ LC_ALL=da_DK bash
$ locale
LANG=ja_JP.eucJP
LC_CTYPE="da_DK"
(省略)
LC_ALL=da_DK
$ printf "%'d\n" "123456789"
123.456.789

616:名無しさん@お腹いっぱい。
09/11/23 06:55:47
$ printf "%'d" "123456789"
printf: %': invalid directive

617:名無しさん@お腹いっぱい。
09/11/23 13:08:26
>>615
>>$ LC_ALL=da_DK printf "%'d\n" "123456789"

LC_ALL を LC_NUMERIC にしてもダメ?

618:名無しさん@お腹いっぱい。
09/11/23 15:32:07
(優先される)強さは、
強 LC_ALL > LC_個別 > LANG 弱
のはずだから、LC_ALL があってダメなら LC_NUMERIC でもダメな希ガス。



619:名無しさん@お腹いっぱい。
09/11/23 15:44:54
>>617
ダメでした。
というかlocale(7)に書いてあるロケールの決定順序を見る限り
$ LC_ALL=da_DK printf "%'d\n" "123456789"
で動かなければ、LC_NUMERICを使っても同じなのではないかと。

ところで、
$ LC_ALL=da_DK locale
の結果は$ LC_ALL=da_DK bashで作ったシェル上でlocaleした
(参考>>615の2個目のlocale)のと同じ結果になります。
(つまりLC_ALLも、LC_NUMERICもda_DK)

その癖に、
$ LC_ALL=da_DK printf "%s\n" "$LC_NUMERIC" と
$ LC_ALL=da_DK echo "$LC_NUMERIC" はどちらも「C」が出力
(参考>>615の1個目のlocale)になるんですよね。LC_ALLはもちろん、改行のみです。
環境変数の伝わり方が変ですよね?

つまり、
localeだとLC_ALL(もしくはLC_NUMERIC)がexportされてて、
printfとechoはexportされない。

それと、
>>615で「組み込みコマンドだと・・・」といいましたが、
$ type -a echo したら、builtinと/bin/echoの2つのエントリがあったので、
どちらも試してみましたが、exportされませんでした。
どういうメカニズムでこうなっちゃうんでしょう。

620:名無しさん@お腹いっぱい。
09/11/23 15:54:16
>>618 とレスが一部被ってしまった

連レスですみませんが、
コマンドの前に環境変数定義をつけるシンタックスって
なんという名前で呼ばれていますか?

そもそもどういうものなのかを調べたいのですが、ググりづらくて。

621:名無しさん@お腹いっぱい。
09/11/23 16:04:31
>>620
shじゃなくてbashのマニュアルで申し訳ないが、
A simple command is a sequence of optional variable assignments
followed by blank-separated words and redirections, and terminated
by a control operator.
だそうな。
optional variable assignments (省略可能な変数代入)


622:608,612,615,619
09/11/23 18:22:28
>>621 ありがとう。man bash読みました。
組み込みコマンドでの、optional variable assignmentの挙動についてまとめてみました。

COMMAND EXECUTION ENVIRONMENT節に以下の記述があります。
When a simple command other than a builtin or shell function is to be
executed, it is invoked in a separate execution environment

つまり組み込みコマンドはseparate execution environmentで呼び出されない。
これは当たり前のことで、組み込みコマンドは別シェルで実行されないということですよね。
そして個人的に新たに知ったのは、optional variable assignmentは別シェルにしか
伝えられないということです。(現在のシェル変数には代入されない)
だから、>>615で $ LC_ALL=da_DK printf "%'d\n" "123456789"
がコンマ区切りにならなかったんですね。

だったら、敢えてシェル変数を伝えられた実行環境を作って、printfするとどうなるか。
#include <stdlib.h>
int main()
{
 system("printf \"%s\n\" \"$LC_NUMERIC\"");
 system("printf \"%'d\n\" \"123456789\"");
 return 0;
}
をコンパイルしたa.outに対して試してみました。
(a.outは組み込みコマンドではないので別シェルで実行され、
optional variable assignmentが伝えられる)

623:608,612,615,619,622
09/11/23 18:25:17
$ ./a.out
C
123456789
$ LC_NUMERIC=da_DK ./a.out
da_DK
123.456.789
$ LC_ALL=da_DK ./a.out
C
123.456.789
となりました。

>>615の後半のようにLC_ALL=da_DK bashで環境作ってからやる方が楽なので、
本末転倒になりましたが。。。


ところで、これで興味深いのは、LC_ALLはLC_NUMERICに影響を及ぼさないことです。
>>615では LC_ALL=da_DK bash 後にlocaleすると、LC_ALL=LC_NUMERIC=da_DKになりますが、
bashの初期化処理でLC_ALLの値をLC_NUMERICにコピーしているのかも?


最後に。619の訂正。
SIMPLE COMMAND EXPANSIONの節の 4.にあるように、
parameter expansionされてからコマンドが実行されるようなので、
$ LC_NUMERIC=da_DK printf "%s\n" "$LC_NUMERIC"
はコマンドが実行される前に引数の$LC_NUMERICが「C」(参考>>615)と展開される。
そのため、Cが表示される。


長文失礼しました。

624:名無しさん@お腹いっぱい。
09/11/23 18:52:34
組み込みコマンドがseparate execution environmentで呼び出されないのは
bashの場合の話。

kshでは組み込みコマンドでもseparate execution environmentで動作する。

625:名無しさん@お腹いっぱい。
09/11/23 19:12:34
やはり、sh系といえども、何を使っているかは明示すべきなんだな。


626:名無しさん@お腹いっぱい。
09/11/23 19:17:36
確かにその通りですね。
上は全部>>608の環境で試してた。

627:名無しさん@お腹いっぱい。
09/11/26 14:47:50
"aa-1125.txt" "aa-0001.txt"
"aa bb-1125.txt" "aa bb-0001.txt"
"aa bb cc-1125.txt" "aa bb cc-0001.txt"
同じディレクトリにこの6ファイルがあるとします。
この中から「aa bb-????.txt」の形式で且つ最も新しいファイルを
探したいんですが、
(当然のことですが)ls -ltr "aa bb-????.txt"|tail -1とやるとエラーになってしまいます。
どうすればいいでしょうか?シェルはbashです。

628:名無しさん@お腹いっぱい。
09/11/26 15:01:32
ls -ltr (ここに6個のファイル名を羅列)|tail -1

629:名無しさん@お腹いっぱい。
09/11/26 15:01:41
ls -lt aa\ bb-????.txt | head -1

630:名無しさん@お腹いっぱい。
09/11/26 15:14:14
bbの無いファイルもあるぞ

631:名無しさん@お腹いっぱい。
09/11/26 15:28:45
あるよ
だから?

632:名無しさん@お腹いっぱい。
09/11/26 15:49:56
申し遅れましたが、
実際にはファイル数、ハイフンより前の部分のファイル名は不定です。
>>627は単純化した例です。
>>627の時点で知りたかったことは自動でエスケイプする方法もしくはそのコマンドです。

633:名無しさん@お腹いっぱい。
09/11/26 16:00:11
一体何がしたいんだよ
何とマッチさせたいんだ?

634:名無しさん@お腹いっぱい。
09/11/26 16:07:04
>>627の下から2行めをエスケイプしたものが
>>629なわけですが、(実質的に)
そのようなことをスクリプト内で自動でおこないたいということです。
sed,awkを使うのかなと思いますが、インタラクティブだと[tab]キーを押すと
できるようなことなので、bash内部でも出来ないかなとも思います。

635:名無しさん@お腹いっぱい。
09/11/26 16:13:40
ハイフンより前にスペースが含まれていようがいまいが
*-????.txt で>>627の6ファイル全てにマッチするんだけど
それで何か困るのか

636:名無しさん@お腹いっぱい。
09/11/26 17:03:15
unix超ど素人です。
本を参照しても見つからないので、
質問させてください。
ちなみにここで推奨されてないcshを使っています。

例えば80.0というように小数点がある数字を
80といった整数に書き直すスクリプトをつくりたいのですが、
うまくいきません。

#!/bin/csh
set y_info = 80.0
echo int($y_info) > aaa.dat
どうすれば解決できますでしょうか?

637:名無しさん@お腹いっぱい。
09/11/26 17:23:05
解決の第一歩は、cshを捨てる事だ。

638:名無しさん@お腹いっぱい。
09/11/26 17:24:52
>>627
スペースだけをクォートすればいい。シングルクォートの方がお勧め

ls -ltr ??' '??-????.txt | tail -1

639:名無しさん@お腹いっぱい。
09/11/26 17:30:24
>>636
cshは捨てさせていただくので、shでどうぞ。

#!/bin/sh
y_info=80.0
printf '%.0f¥n' $y_info

640:名無しさん@お腹いっぱい。
09/11/26 20:10:12
>>636
cshなら拡張子を削る機能が組み込まれてるので、
悪くないチョイスだよ

#!/bin/csh
set y_info=80.0
echo $y_inf:r > aaa.dat

なんと :r を付けるだけで小数点以下を削れるんだぜ

641:名無しさん@お腹いっぱい。
09/11/26 20:11:11
echo $y_info:r > aaa.dat
のミス

642:名無しさん@お腹いっぱい。
09/11/26 20:13:04
あと、csh スクリプトは
#!/bin/csh -f
にした方がなにかと幸せ

643:名無しさん@お腹いっぱい。
09/11/26 20:30:51
>>640
それだと、 .5 みたいに頭の 0が省略されてる小数で誤動作する。

644:名無しさん@お腹いっぱい。
09/11/26 20:34:08
>>640
(数値じゃなく)拡張子とみなして削る方式なら shでもできる。

#!/bin/sh
y_info=80.0
echo ${y_info%.*}


csh(笑)の出番なし。

645:636
09/11/26 21:13:03
>>640
うまくいきました
トンクス

他の方もレスありがとうございます

シミュレーションで得られたデータを出力する際にスクリプトを使用しています。
周りがcsh使ってたので、それを使ってましたが、
shの方が問題点が少なそうなので、
そっちにシフトしてみようと思います。




646:名無しさん@お腹いっぱい。
09/11/26 21:16:33
半導体屋か? あいつら何でcsh好きなんだ?

647:名無しさん@お腹いっぱい。
09/11/26 21:19:13
>>640 だと四捨五入されない。>>639 がお勧め。

648:名無しさん@お腹いっぱい。
09/11/28 11:45:22
以前にcshで作って、それですんでりゃそうなるだろう。

649:名無しさん@お腹いっぱい。
09/11/28 12:14:17
tcsh以外に便利なインタラクティブシェルがなかった時代の負債といえようか

650:名無しさん@お腹いっぱい。
09/11/28 12:33:23
ちょっとしたスクリプトの場合、cshの方が書きやすい場合もある。
四則演算が出来るとか配列が使えるとか、要はケースバイケース

651:名無しさん@お腹いっぱい。
09/11/28 12:38:06
>>650
四則演算も配列も、今時のsh(系)でできる。

652:名無しさん@お腹いっぱい。
09/11/28 12:46:50
ケースバイケースでcshスクリプトなんて混ぜられちゃ迷惑だ

653:名無しさん@お腹いっぱい。
09/11/28 13:18:36
コピペで数千行を超えるのcshスクリプト作るんだぜ。
ちょっとしたを遥かに超越している。

654:名無しさん@お腹いっぱい。
09/11/28 13:23:31
実績があります、とか言ったりなんかしちゃったりして

655:名無しさん@お腹いっぱい。
09/11/28 17:21:38
UNIXド素人です。
手詰り状態なのでアドバイス頂けると幸いです。

◆処理内容
 Aディレクトリから、Bディレクトリにファイルをコピーする。
 (コピーオプション:-p -f)

◆コピー条件
 Bディレクトリのファイルの更新時間とAディレクトリのファイルの
 更新時間が異なる場合。

◆その他
 更新時間が異ならない場合は、エラーとし、1を戻り値とする。

上記のようなスクリプトを作成したいのですが
どのような処理にしたらよろしいのでしょうか?




656:名無しさん@お腹いっぱい。
09/11/28 18:05:43
書いてあるとおりに処理しよう

657:655
09/11/28 18:21:04
すいません。。
意味わからない質問になっていました。。

やり方がわからない処理は「更新時間を比較する」点です。
お互いの更新時間を変数に入れ、同じ場合と違う場合で処理を決めれば
いいことはわかるのですが、更新時間を比較することなどできるので
しょうか?

658:名無しさん@お腹いっぱい。
09/11/28 18:23:44
>>655
要点だけ書くよ。

if [ "$file1" -nt "$file2" ]; then
cp -pf "$file1" "$file2"
fi

659:655
09/11/28 18:43:33
>>658

ありがとうございます。
ファイルが更新された場合、サイズや更新時間で比較するしかないと思われるのですが
更新時間や、ファイルの詳細?を変数に格納することは可能なのでしょうか?

660:名無しさん@お腹いっぱい。
09/11/28 18:47:33
>>659
md5sumとかでハッシュ値を見たら?

661:名無しさん@お腹いっぱい。
09/11/28 18:54:17
>>659
せっかく回答もらってるのに意味をちゃんと理解しろよ。

[ A -nt B ]
ってやったら、これで更新時間を比較してるんだよ。
別に更新時間を変数に入れる必要なんかない。

-nt は、"newer than" ね。

662:655
09/11/28 19:16:35
>>658 >>661

そういうことですね!!
ファイルの更新時間ではなく、ファイル自体を比較すればいいのですね!!

理解力が無く、ご迷惑おかけいたしました・・・
アドバイスを参考にスクリプトを作成してみたいと思います。
ありがとうございました。

663:名無しさん@お腹いっぱい。
09/11/28 19:19:11
>>662
違うよ。

ファイル自体なんて比較してない。
更新時間を比較してるの。

if [ fileA -nt fileB ]; then ...

ってやると、fileA と fileBの更新時刻を比較して、
その結果で動作が決まるんだよ。
fileA/fileBの中身は読んでない。

664:名無しさん@お腹いっぱい。
09/11/28 19:23:46
URLリンク(hashinfo.com)

665:名無しさん@お腹いっぱい。
09/11/28 19:28:45
md5sumとかハッシュとか言ってる回答者の言うことはここでは無視しとけ。
単純にシェルスクリプトから [ ] (testコマンド)で時刻比較できるんだから。

666:名無しさん@お腹いっぱい。
09/11/28 19:33:06
>>662は日本語読解力からしてダメだな。

667:名無しさん@お腹いっぱい。
09/11/28 19:36:34
更新時刻が異なる場合、なのに、newer than だけでいいんだろうか

668:655
09/11/28 19:36:40
>>663

少し調べてみましたところ、ファイルのタイムスタンプ、つまり更新時間
を比較しているのですね。

ファイルの比較には -nt -ot の2種類があるようですが
"="や"!="で比較することは無理と理解してよろしいのでしょうか?

669:名無しさん@お腹いっぱい。
09/11/28 19:42:39
>>667
だから>>658 は「要点だけ」って言ってるんだよ。

せっかく >>668 が -nt と -ot を調べたんだから、
それを -o すれば 時刻の "!=" を条件を記述できることに気づくはず。

670:名無しさん@お腹いっぱい。
09/11/28 21:50:23
>>668
> ファイルの比較には -nt -ot の2種類があるようですが

>>663を読み直せ…



671:名無しさん@お腹いっぱい。
09/11/28 22:22:24
rsync 使え、で終わる気がする

672:名無しさん@お腹いっぱい。
09/11/29 00:01:55
>>668
> "="や"!="で比較することは無理と理解してよろしいのでしょうか?
そう考えていいよ。「異なる場合」って言ってるんだから、
「「新しい場合」または「古い場合」」
っていう条件が必要なんでしょ?
それぞれ>>663の書式を使って-ntと-otでできるよ。君の言うとおりだよ。
あとは二つをつなぐ「または」を調べてみてごらん。>>669もそう言ってるけどね。

>>671 俺もそう思う。

673:655
09/11/29 00:32:15
>>672

if [ FILE1 -nt FILE2 -o FILE1 -ot FILE2 ] ; then
cp -p -f …
exit 0
else
exit 1
fi
とすればいいのですね!

>>658 >>663 そこまで読み取ることができず、ご迷惑おかけいたしました。。


674:名無しさん@お腹いっぱい。
09/12/04 21:09:44
$ echo "URLリンク(aaa.kp)" | sed -e 's@//*@/@g' -e 's@http:/@URLリンク(@g)<)

一応目的の動作は達成しているのですが、sedがマヌケです。


もうちょっと素敵な方法はありますか?

675:名無しさん@お腹いっぱい。
09/12/04 21:32:24
>>674
echo 'URLリンク(aaa.kp)'

676:名無しさん@お腹いっぱい。
09/12/05 00:35:32
sed -e 's@\([^:]\)//*@\1/@g'

677:名無しさん@お腹いっぱい。
09/12/05 00:49:25
マジキチ

678:名無しさん@お腹いっぱい。
09/12/05 19:23:28
複雑多数のサブディレクトリを持つディレクトリAを複製したい
但し、いくつかのサブディレクトリについては複製対象外としたい。
現状以下のようにやってます。
cp -rp A B
rm -rf B/a/b/c
rm -rf B/bb/aa/cc
・・・消したい対象分ひたすら羅列。

サブディレクトリ内のサイズが大きく、cp,rmで余計な時間が掛かってしまいます。
AをBとして複製する場合に、「このサブディレクトリ以外すべてコピー」
またいな記述方法はありますでしょうか?
sh,bashでお願いします。

679:名無しさん@お腹いっぱい。
09/12/05 19:40:24
cd A
tar cf - . --exclude a/b/c --exclude bb/aa/cc | tar xf - -C /path/to/B

680:名無しさん@お腹いっぱい。
09/12/05 19:49:17
>>679

なるほど、tarのアーカイブファイルを経由させるのですね。
ありがとう。やってみます。

681:名無しさん@お腹いっぱい。
09/12/05 22:18:32
find . -print |egrep -f exlude-pattern-file |cpio -pumd destdir

さらに、コピーでなくてハードリンクで済ませられるなら、高速、省スペース。
find . -print |egrep -f exlude-pattern-file |cpio -pumdl destdir

682:名無しさん@お腹いっぱい。
09/12/05 23:09:18
ありがとう。一考してみます。

683:名無しさん@お腹いっぱい。
09/12/06 23:26:04

>>676
規制で書けかなった。ありがとう。

684:名無しさん@お腹いっぱい。
09/12/10 10:18:03
findの判別式を単独のファイルに適用して、真偽値だけほしいんだけど
どうしたらいい?

685:名無しさん@お腹いっぱい。
09/12/10 10:27:52
例えば

[ -n "`find /path/to/file -mtime 7 ...`" ]

みたいな感じか?

686:名無しさん@お腹いっぱい。
09/12/10 10:34:08
いや、

find /path/to/file -mtime 7 2> /dev/null; echo $?

だろ。

687:名無しさん@お腹いっぱい。
09/12/10 10:39:11
ファイルが正常に処理されれば、判定結果にかかわらず戻り値はいつも0だよ

688:名無しさん@お腹いっぱい。
09/12/10 10:42:01
>>686
マッチしてもしなくても$?は0なのよ

>>685
なるほど文字列の長さを見るのか
とりあえずこれでやってみるわ超サンクス

689:名無しさん@お腹いっぱい。
09/12/10 19:44:25
他サーバ上のtar.gzファイルを解凍する方法はないでしょうか?

690:名無しさん@お腹いっぱい。
09/12/10 20:28:24
sshとか可能なら普通に解凍できるから、そうじゃない質問だとして、
エスパー募集だな

691:名無しさん@お腹いっぱい。
09/12/10 20:55:52
>>690
たとえばftpで他サーバに接続して、gzip -cd | tar xvf -
のようなことはできないでしょうか?

692:名無しさん@お腹いっぱい。
09/12/10 20:59:06
>>691

wget fURLリンク(user:pass@)他サーバ/path/to/hoge.tar.gz -O - | tar zxvf -

693:名無しさん@お腹いっぱい。
09/12/10 21:08:14
>>692
ありがとうございます。
ちょっと試してみます。

694:名無しさん@お腹いっぱい。
09/12/12 13:37:48
URLリンク(v6shell.org)
にてるような、変わっているような。

695:名無しさん@お腹いっぱい。
09/12/20 13:17:58
すみません、スクリプト内で使用されている変数について教えてください。
使用しているOSはCentOS5.3です。

今、勉強がてら/etc/init.d/functionsを読んでいるのですが、
functions内で使用されている変数$LSBの意味がわかりません。

使用例 :[ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] のように記述されています。

例えば、上記例の$BOOTUPは、/etc/sysconfig/init内で定義されているのを確認できました。
しかし$LSBは/etc/sysconfigや、/etc内のファイルをざっと検索してみても大本の定義が発見できません。
setにもenvにもありません。

$LSBは、意味ありげに見えるだけで、単になんでもない、普通の変数なんでしょうか?
それとも、ちゃんとどこかで定義されているんでしょうか?
もしかしたら、変数ではなく別のものなんでしょうか?

しょうもない質問で申し訳ありませんが、ご教授ください。よろしくお願いします。

696:名無しさん@お腹いっぱい。
09/12/20 14:00:20
教授はあげません。

697:名無しさん@お腹いっぱい。
09/12/20 14:33:04
Linux Standard Base準拠なら定義しておく、ってやつかな?



698:名無しさん@お腹いっぱい。
09/12/20 15:05:57
「ご教授」で正しいんだよ。

699:名無しさん@お腹いっぱい。
09/12/20 15:28:33
そして、それに対する>>696の返しは絶妙だったな。

700:名無しさん@お腹いっぱい。
09/12/20 15:42:03
いや、正しくない。
「教授する」というのは体系だててきちんと教えるという意味なので、
どこの馬の骨かわからない匿名掲示板の単発質問者には「教授」しない。

701:名無しさん@お腹いっぱい。
09/12/20 15:53:37
>>700
だから「体系だててきちんと教え」てください、って >>695 が言ってるんだから
言葉として正しいじゃん。

それに対して、>>696 は「教授する」自体が間違いだと勘違いして
恥を晒しちゃったね。

702:名無しさん@お腹いっぱい。
09/12/20 16:04:02
恥を晒してる奴がいると思うとすかさず飛びつく奴って流石だよな。
楽しい休日の午後のひとときって感じ。

703:名無しさん@お腹いっぱい。
09/12/20 17:18:06
>>701
メクラ? >>695のどこに「体系だててきちんと教えてください」と書いてあるんだ?
揚げ足とったつもりが恥晒して惨め過ぎ。

704:名無しさん@お腹いっぱい。
09/12/20 17:51:05
>>695
定義してない可能性があるから:-なんやで!

705:名無しさん@お腹いっぱい。
09/12/20 18:08:34
>>703
「ご教授ください」=「体系だててきちんと教えてください」(同値)

>>695 には「ご教授ください」と書いてある、
イコール
>>695 は「体系だててきちんと教えてください」と言っている

706:名無しさん@お腹いっぱい。
09/12/20 18:46:44
けんかをやめて~
ふたりをとめて~
わたし~の~ために~
あらそ~わない~で
もう こ~れ~い~じょ~う~♪

707:名無しさん@お腹いっぱい。
09/12/20 18:50:49
じゃあ体系だてて回答してやれ

708:名無しさん@お腹いっぱい。
09/12/20 19:44:15
695です。皆さまなんだかお騒がせしてすみませんでした。
>>697 >>704
ありがとうございます、Linux Standard Baseですか。規格だとしか捉えていなかったので、
関係あるとは想像もしていませんでした。

$BOOTUP=verboseだとold-style bootupらしいので、
加えてLinux Standard Base準拠でないことを確認したいとかなんでしょうかね。

Linux Standard Baseのページには、
「個々のライブラリのインターフェースの装備、および、、各インターフェースに関連したデータ構造・定数を規定しています」
とあったので、どこかで何か定義されているんでしょうね。以下のページを見つけたのですが探しきれませんでした。

URLリンク(dev.linux-foundation.org)

実体がわからないのは残念ですが、私自身が納得できたので、先に進むことができそうです。
皆さま、本当にありがとうございました!

709:名無しさん@お腹いっぱい。
09/12/20 21:01:27
${LSB:-}

:- ってどういう意味?だれか教えて。

#一瞬 :-) かと思ったけど違ったので :-p

710:名無しさん@お腹いっぱい。
09/12/20 21:03:54
・・・と書いておいてなんだけど、man bashに書いてあった

${parameter:-word}
デフォルトの値を使います。 parameter が設定されていないか空文 字
列であれば、 word を展開したものに置換されます。そうでなければ、
parameter の値に置換されます。

へー。しらなかった。

711:名無しさん@お腹いっぱい。
09/12/20 21:06:40
:-)

712:名無しさん@お腹いっぱい。
09/12/20 23:43:43
>>705
バカメ。「ご教授ください」と「体系だててきちんと教えてください」は同値だが、
>>695は誤用だから同値じゃ無いという指摘だ。

論理的思考の出来ないバカは恥を晒すだけだから引っ込んでろ。

713:名無しさん@お腹いっぱい。
09/12/20 23:58:55
日曜日最後のレスがそれじゃあな…

714:名無しさん@お腹いっぱい。
09/12/21 00:50:09
ご教示ください
とすればおkだったような予感w

715:名無しさん@お腹いっぱい。
09/12/21 02:38:22
>>714
ご教授くださいだろ、バーカ!
こんな展開だと予想

716:名無しさん@お腹いっぱい。
09/12/21 07:41:23
>>712
そうじゃなくて、
あくまで誤用であって、「ご教授する」という言葉は日本語として正しい、
というのが主張。
(誤用だけど、言葉自体は正しいの)


ところが、>>696 曰く、
>教授はあげません。

という突っ込みは、「ご教授する」という言葉自体も間違っていると
思い込んでいる。

もし、「誤用」に対する突っ込みなら、
「(こんな掲示版では)ご教授はできません」
となるはずで、
「教授はあげません」みたいには言わないはず。

よって、
>>696 は、「ご教授する」という言葉自体を知らなかったという天で
恥を晒したんだよ。

717:名無しさん@お腹いっぱい。
09/12/21 11:12:52
なにそれこわい

718:名無しさん@お腹いっぱい。
09/12/21 13:14:13
うわ、まだ続けてるのかよ

719:名無しさん@お腹いっぱい。
09/12/21 18:25:12
>>716
アホ丸出しの言い訳止めろ。>>695の用法も正しいと言うのがお前の主張(>>705)。
>>696はオレじゃないが、誤用に対して「あげない」とからかっている。
お前は用法を知らずに揚げ足とったつもりで恥を晒したうえに、小学生並みの見苦
しい言い逃れを続けている単なるバカ。お前の負け。

>>705
> 「ご教授ください」=「体系だててきちんと教えてください」(同値)
> >>695 には「ご教授ください」と書いてある、
> イコール
> >>695 は「体系だててきちんと教えてください」と言っている


720:名無しさん@お腹いっぱい。
09/12/21 19:46:10
関係ない話はくだらないからやめようぜ。
>>695の質問の本質はLSBはどんな意味をもつ変数なの?ってことだろ
LSBについてまともに答えてるの>>697くらいじゃねーか

721:名無しさん@お腹いっぱい。
09/12/21 20:31:51
レスありがとうございます
と書くだけでスレが荒れるのと同じだな

722:名無しさん@お腹いっぱい。
09/12/21 21:02:19
>>721
FreeBSDって何???

723:名無しさん@お腹いっぱい。
09/12/21 22:46:41
>>722
URLリンク(www.freebsd.org)

荒したいならスペースが足らぬわ

724:名無しさん@お腹いっぱい。
09/12/23 17:35:56
cshについて質問させてください
変数の中身が文字列か数字か判断して処理をしたいのですがどうやったらわかりますか?
if ($1 == [0-9]*)
こんな感じでいけるのかなっておもったけどうまくいかずで…

725:名無しさん@お腹いっぱい。
09/12/23 17:40:30
回答が欲しいなら「ご教授ください」って書かないと誰も答えないよ。

726:名無しさん@お腹いっぱい。
09/12/23 19:16:51
パイプラインについて質問です.
% ls
foo.txt bar.txt baz.txt
の状態で,
% ls | wc -l
とやると3が返ってきます.
これは,パイプラインを通すとlsの結果に改行が挿入されるということなのでしょうか?
% ls | xargs echo | wc -l
とすると1が返ってくるので,この結果の違いが不思議です.

727:名無しさん@お腹いっぱい。
09/12/23 19:24:28
まずは ls | cat して確かめてみなさい

一応、はまりそうなので正解を言っておくと、ls が、出力先がパイプか端末かを
調べて、出力を変えています。パイプが変えてるのではありません。

728:名無しさん@お腹いっぱい。
09/12/23 19:26:27
724です。
是非ともご教授いただきたいです。
よろしくお願いいたします。

729:名無しさん@お腹いっぱい。
09/12/23 20:19:56
>>724
先頭が数字かどうかなら 
 if ( $1 =~ [0-9]* )
でいけるけど、より正確に数値かどうか判定するとなると
cshでは難しいかもしれない

教授は付けないほうがいい

730:名無しさん@お腹いっぱい。
09/12/23 20:37:33
「ご教授」で正しいんだよ。

731:名無しさん@お腹いっぱい。
09/12/23 20:38:39
>>727
lsが状況に応じて出力を変えてるとは思いませんでした.
ありがとうございます.

732:724
09/12/23 20:42:48
>729さん
cshでは難しいですか。。。

回答ありがとうございます。


733:名無しさん@お腹いっぱい。
09/12/23 20:46:57
>724
if ( { ( echo -n "$1" | grep '^[0-9][0-9]*$' > /dev/null ) } ) echo yes,yes,yes

734:名無しさん@お腹いっぱい。
09/12/23 23:37:25
>>724にかなり近いのですが、質問します。

kshで「変数の中身が半角英数14桁」であることを確認したいのですが、上手くいきません。

if [ `expr $hoge : [a-zA-Z0-9]+` -ne 14 ] ; then
# 半角英数14桁以外
fi

と書いてみたのですが、+が正規表現になってくれず。
[a-zA-Z0-9][a-zA-Z0-9]*も最初2桁分しかチェックできず。

上手く正規表現でチェックできる術はないでしょうか?
お分かりの方、ご教授お願いします。

735:名無しさん@お腹いっぱい。
09/12/24 01:15:38
$ echo "foo" | if egrep -qs '^[a-zA-Z0-9]+$'; then echo yes; fi
yes
$ echo "_foo" | if egrep -qs '^[a-zA-Z0-9]+$'; then echo yes; fi
$

736:名無しさん@お腹いっぱい。
09/12/24 04:12:15
>>734
if [ `expr $hoge : "[a-zA-Z0-9]\+"` -ne 14 ]




737:734
09/12/25 07:48:46
>>735
>>736
アドバイスありがとうございます。
見た目に単純な736の記述を試して上手く動作したので、この形で実装したいと思います。

\でエスケープすると正規表現になるとは知りませんでした。完全に逆だと思ってました。
エスケープもダブルクオートも試したのですが、両方やるとは思いつかず…

ありがとうございました。

738:名無しさん@お腹いっぱい。
09/12/26 18:19:46
えーと、複数ファイルを結合したいのですが、

・ファイル名の一部が一致している
・結合すべきファイルの数は分かっている
・一致している部分の文字数、箇所も分かっている
・このようなファイルの組がディレクトリ内に複数組ある

というような条件で、例えば

file01abc.txt
file02abc.txt
file03abc.txt

file01def.txt
file02def.txt
file03def.txt

file......

で、わざわざ
cat file??abc.txt > fileabc.txt
cat file??def.txt > fileabc.txt
cat............

などと書かずに一致部分を判別して全ての組を結合させたいのです。うまく出来る方法はあるでしょうか?

739:名無しさん@お腹いっぱい。
09/12/26 18:35:08
>>738
普通に、

for f in abc def
do
cat file??"$f".txt > file"$f".txt
done

740:名無しさん@お腹いっぱい。
09/12/26 19:13:07
すみません、ちょっと説明足りませんでした。
そのabc、defってのが異なる組がかなり大量にあって、かつその文字列が
そこそこ長いこと、毎回その生成される文字列が異なることから、いちいちinの後の部分を
書き出さずに出来るようにしたいのです。つまりこの場合、7,8,9文字目が
(具体的な文字列は何だか分からないけれど)一致しているファイル全てを結合する、
というような指定は出来ないでしょうか?

741:名無しさん@お腹いっぱい。
09/12/26 19:19:01
>>738
普通に、

for ff in *
do
f=${ff:6:3}
cat file??"$f".txt > file"$f".txt
done

742:名無しさん@お腹いっぱい。
09/12/26 19:35:08
>>740
これで合ってる?

ls | sed -n 's/^......//p' | sed 's/....$//' | sort | uniq | while read i
do cat file*${i}.txt > file${i}.txt
done

743:名無しさん@お腹いっぱい。
09/12/26 19:36:00
10
22
3
11
25
90
12




ってあるTextで平均から飛び出る奴(今回は90)切りたいんだけど
ヒントないっすか?

744:名無しさん@お腹いっぱい。
09/12/26 19:38:28
偏差値求めて標準偏差の何倍とかで検出だな

745:名無しさん@お腹いっぱい。
09/12/26 20:34:25
>>741
>>742
ありがとうございます。どっちも動作は完璧です。
さらにお手数をおかけしますが後学のために、
軽く何をやってるのか教えてもらえないでしょうか。

741はワイルドカードの挙動がよく分からないので3行目の時点で
ffに何が入っているのかよくわかりません。ffの6バイト目から3文字分を
fに代入し直しているって理解は合っていますか?

742は-n以降何をやってるか全く分かりません…
特に並んでいるドットの意味を教えてもらえないでしょうか?
察するに文字数ですよね?

746:名無しさん@お腹いっぱい。
09/12/26 20:50:17
>>745
>ffに何が入っているのかよくわかりません。ffの6バイト目から3文字分を
>fに代入し直しているって理解は合っていますか?

あってる

>742は-n以降何をやってるか全く分かりません…
>特に並んでいるドットの意味を教えてもらえないでしょうか?

sedの正規表現です

747:名無しさん@お腹いっぱい。
09/12/26 21:01:15
>>745
's/^......//p'

s は sbustitution == 文字の置換。s/aaa/bbb/ で aaa を bbb に置き換える。
^...... は正規表現。^ は行頭を表していて、. は文字一つ分を表している。
p は print == 印字。s で置き換えた後の文字列を表示する。

sed 's/....$//'

さっきと基本は同じ。
$ は行末を表している。....$ は行末の任意の4文字にマッチする正規表現。

sort | uniq

入力をソートして重複を除去する。
ここまでの処理結果は abc, def 等がファイル数分重複しているので、
重複を取り除く。

while read i; do ...

read で一行ずつ読み込んで、変数 i に格納する。i には abc や def 等が入る。

シェルスクリプトは普段それほど使っていないので、多分、もっと良い
方法があると思います。

748:名無しさん@お腹いっぱい。
09/12/26 21:09:21
スマソ。
s/sbustitution/substitution/

749:名無しさん@お腹いっぱい。
09/12/26 21:15:50
>>746
>>747
度々御丁寧にありがとうございます。よく分かりました。

750:名無しさん@お腹いっぱい。
09/12/27 15:16:39
>>744
そか、いったん合計して偏差値出すしかないか


751:正月前
09/12/29 21:51:50
シェルスクリプトの中で以下のようにperlで重複部分の文字を削除する場合は、最後の文字は消されない理由はなんでしょうか?
perlの中で同じことをすると、最後の文字は消されるのに。
教えて頂ければ、ありがたいです。
--------------------------
hoge='a:b:c:d:a:b:c:d:a'
echo $hoge
echo " "
echo $hoge | perl -F: -ane 'chop;foreach(@F){$s{$_}++ or push(@b,$_)}print join(":",@b)'
echo " "


--------------------------

752:名無しさん@お腹いっぱい。
09/12/29 22:24:22
>>751
echo -n

753:正月前
09/12/29 22:45:31
ありがとうございました!!!
perlの中でchopではだめで、echo -n で改行を消さないといけないんですね!


754:名無しさん@お腹いっぱい。
09/12/30 00:24:04
auto-split後だからchopするとしたら
chop($F[$#F]);

755:名無しさん@お腹いっぱい。
10/01/07 21:10:23
run.shファイルの中で、script_file.shをsourceした場合。
sourceされているscript_fileの中でscript_file自身の絶対パスを得る方法を調べています。

bashの場合はscript_fileの中で$BASH_SOURCEから得られるが、他のシェル(zsh/tcsh/ksh)でscript_file.shのパスを得られる方法を
教えていただけませんか?

>>>>>>>>>>>>>>>>>>>>>>
script_file.shファイルのある場所
/path/to/script_file.sh
>>>>>>>>>>>>>>>>>>>>>>

実行例:
%./run.sh

期待結果:
/path/to/


ファイル <run.sh>の中身
-------------
#!/bin/(sh/zsh/tcsh...)
source $path/script_file.sh
-------------

ファイル script_file:
-------------
script_file_path=`******`
echo $script_file_path;
-------------



756:名無しさん@お腹いっぱい。
10/01/07 21:31:48
>>755
他のシェルのソースを改造して $BASH_SOURCEの機能を実装すれば桶。

757:名無しさん@お腹いっぱい。
10/01/07 21:50:29
>>756
早速のレスありがとうございます。今環境がないので明日試してみます。

758:名無しさん@お腹いっぱい。
10/01/07 22:13:18
こりゃ、わかって無いな。

759:名無しさん@お腹いっぱい。
10/01/08 13:35:29
制限時間を設定して、2つのプロセスを実行して、時間内に1つでもプロセスが終了しなかったら2つともキルして、もう一度最初から実行するにはどのように記述すれば良いのでしょうか?
ご教授ねがいます

760:名無しさん@お腹いっぱい。
10/01/08 14:04:43
どこの馬の骨かわからん奴に教授はしない。

761:名無しさん@お腹いっぱい。
10/01/08 14:41:28
>>759
同条件で、最初から再実行したら、また時間内に
プロセスが終了しないのでループしちゃうのでは?

762:名無しさん@お腹いっぱい。
10/01/08 14:52:01
>>716
ループしてもいいから、まずはやり方を教授しろよ

763:名無しさん@お腹いっぱい。
10/01/08 14:57:34
>>761
ネットとか、I/Oポートとか、外的要因が絡んでるのなら
同条件で、最初から再実行してもループしない。

764:名無しさん@お腹いっぱい。
10/01/08 15:00:24
>>762
だから、誤用だけど言葉として正しい
と言ってるだろバカ


765:名無しさん@お腹いっぱい。
10/01/08 18:36:31
>>764
誤用する奴には教えないと言っているのだ。バカ。

766:名無しさん@お腹いっぱい。
10/01/08 18:43:35
うるせー馬鹿

767:名無しさん@お腹いっぱい。
10/01/08 18:53:46
いい加減ウザイよ。

768:名無しさん@お腹いっぱい。
10/01/08 19:02:39
>>765
仮に誤用してなかったとしても肝心の質問の答を知らないくせに

769:名無しさん@お腹いっぱい。
10/01/08 19:22:50
煽って答えがもらえるのは小学生まで

770:名無しさん@お腹いっぱい。
10/01/08 19:24:23
>>768
惨めだなあ。馬鹿丸出しの言い逃れを↓で完璧にのされたのを忘れてまた出てきやがった。

From: [719] 名無しさん@お腹いっぱい。 <sage>
Date: 2009/12/21(月) 18:25:12

>>716
アホ丸出しの言い訳止めろ。>>695の用法も正しいと言うのがお前の主張(>>705)。
>>696はオレじゃないが、誤用に対して「あげない」とからかっている。
お前は用法を知らずに揚げ足とったつもりで恥を晒したうえに、小学生並みの見苦
しい言い逃れを続けている単なるバカ。お前の負け。

>>705
> 「ご教授ください」=「体系だててきちんと教えてください」(同値)
> >>695 には「ご教授ください」と書いてある、
> イコール
> >>695 は「体系だててきちんと教えてください」と言っている

771:名無しさん@お腹いっぱい。
10/01/08 21:13:41
>>759

#!/bin/sh
program1 &
p1=$!
program2 &
p2=$!

sleep 60

kill -0 $p1; is_p1=$?
kill -0 $p2; is_p2=$?
if [ $is_p1 = 0 -o $is_p2 = 0 ]
then
   kill -9 $p1 $p2
   sh $0
fi

772:名無しさん@お腹いっぱい。
10/01/08 21:24:43
1 SIGKILLは安易に使ってはいけない。
2 exec sh $0

773:名無しさん@お腹いっぱい。
10/01/08 21:57:52
シェルをexecし直すのは効率が悪い。while文で書ける。

#!/bin/sh
while :
do
program1 &
p1=$!
program2 &
p2=$!

sleep 60

kill -0 $p1; is_p1=$?
kill -0 $p2; is_p2=$?
if [ $is_p1 = 0 -o $is_p2 = 0 ]
then
kill -9 $p1 $p2
continue
fi
break
done

774:名無しさん@お腹いっぱい。
10/01/08 22:06:04
SIGTERM と SIGINT のどちらを使うべきか
いまだによくわからないのはオレだけでいい

775:名無しさん@お腹いっぱい。
10/01/08 22:11:32
SIGKILLでおk

776:名無しさん@お腹いっぱい。
10/01/08 22:19:31
>>771 >>773
program1やprogram2が 60秒以内に正常終了した場合には、
sleep 60 せずにスクリプトもすぐ終了したいんですが、、

777:名無しさん@お腹いっぱい。
10/01/08 22:45:57
「ご教授ねがいます」なんていう奴は、これだよ

778:名無しさん@お腹いっぱい。
10/01/08 22:56:17
ご教授ねがえります

779:名無しさん@お腹いっぱい。
10/01/08 23:06:34
ご教授ねがえったか

780:名無しさん@お腹いっぱい。
10/01/08 23:47:21
謀反でござる!
謀反でござる!

781:名無しさん@お腹いっぱい。
10/01/09 05:41:48
女教授おながいします

782:名無しさん@お腹いっぱい。
10/01/09 07:47:50
質問 >>759 >>776 について、
「ご教授」の突っ込みと誤答ばかりで、

==== ここまで正解ゼロ ====

783:名無しさん@お腹いっぱい。
10/01/09 11:58:33
釣り板の釣りスレでマジ回答したら負け

784:771
10/01/09 14:46:50
>>776
sleep 60の代わりに、それらのプロセスが終了したか
チェックすればいい

   t=0
   while t=`expr $t + 1`; [ $t -lt 60 ]
   do
        kill -0 $p1; is_p1=$? 
        kill -0 $p2; is_p2=$? 
        if [ $is_p1 != 0 -a $is_p2 != 0 ] 
        then 
              break
         fi
        sleep 1
    done

785:名無しさん@お腹いっぱい。
10/01/09 15:03:34
お題を良く読みましょう。「制限時間」
オレはご教授しないけどな。

786:名無しさん@お腹いっぱい。
10/01/09 15:06:52
>>784
それ、1秒間隔でポーリングしてるだけなので、
やっぱり最大1秒遅れるので、ダメです。

787:名無しさん@お腹いっぱい。
10/01/09 19:46:58
#!/bin/sh
T1=`date "+%s"`
T2=0
T3=0
STS=1

while t=`expr $T3 - $T1`; [ $t -lt 最大制限時間 ]
do
program1 &
p1=$!
program2 &
p2=$!
T2=`date "+%s"`
T3=0

while t=`expr $T3 - $T2`; [ $t -lt 制限時間 ]
do
kill -0 $p1; is_p1=$?
kill -0 $p2; is_p2=$?
if [ $is_p1 != 0 -a $is_p2 != 0 ]; then
STS=0
break 2
fi
T3=`date "+%s"`
done
kill -9 $p1 $p2
done
exit $STS

もっとスマートに書けると思う ご教授しる

788:名無しさん@お腹いっぱい。
10/01/09 19:47:22
いやです

789:名無しさん@お腹いっぱい。
10/01/09 20:33:37
>>787
それ、ビージーループになってて重いのでNGです

790:名無しさん@お腹いっぱい。
10/01/09 22:00:20
waitすればいいやん
sleep 60 &して、これも含めた三つのpidをwait。
コードは書かないでおくが。

791:名無しさん@お腹いっぱい。
10/01/09 22:03:13
>>790
複数のプロセスをwaitすると、全部が終了するまで返って来ないという仕様なのでNG

792:名無しさん@お腹いっぱい。
10/01/09 22:34:21
ソケット通信でprogram1,2の終了を
管理プロセスに通知する仕組みにすれば
何とかなるかもしれないが、
シェルだけでは無理だね

793:名無しさん@お腹いっぱい。
10/01/09 22:38:41
んなぁこたー無いが、ご教授はしない。

794:名無しさん@お腹いっぱい。
10/01/11 01:17:26
下の input.txt から output.txt を作るにはどうすればよいでしょうか?
input.txt は1列のデータで、output.txt は、
input.txt の1列目から1行目を削除して2列目に並べたものです
perl か何かに全部読み込んで・・・という方法しか思いつかないのですが
ワンライナーでさくっとやる方法あったら教えてください

### input.txt
1
2
3
5
6

### output.txt
1 2
2 3
3 5
5 6

795:名無しさん@お腹いっぱい。
10/01/11 01:25:06
(read a; while read b; do echo $a $b; a=$b; done) <input.txt >output.txt

796:名無しさん@お腹いっぱい。
10/01/11 01:53:40
>>795
ありがとうございます
目から鱗です

797:名無しさん@お腹いっぱい。
10/01/11 12:54:30
>>794
横方向に連結する場合、 paste を使うのが基本
paste - - < input.txt


798:名無しさん@お腹いっぱい。
10/01/11 12:59:32
あ、よく読んでなかった。こうか
# tail -n +2 input.txt | paste input.txt - > output.txt

799:名無しさん@お腹いっぱい。
10/01/11 13:27:17
>>798
なぜ #プロンプト…


800:名無しさん@お腹いっぱい。
10/01/11 13:49:45
あ、いや、特に考え無しに・・。 $ が一般ユーザで、# が root だっけ

801:759
10/01/11 14:32:31
放置してしまってすみません。
みなさんありがとうございます。
>>776さんは自分ではありません、まったくレスしていないので逆に失礼ですが。


802:名無しさん@お腹いっぱい。
10/01/11 19:14:45
>>800
古くはさらに、$と%をそれぞれBourne ShellとC Shellの一般ユーザー
プロンプトとしたものだけれど、いまはそこまで厳密に使う人はいない
かもなー。
zshは基本的には$系のはずなのにデフォルトが%なのはちょっと不思議。


803:名無しさん@お腹いっぱい。
10/01/11 23:07:53
以下の処理のリダイレクトについて教えていただけますでしょうか?
もしくは、よくある処理のようなので解説しているサイトを教えていただけますでしょうか?

commandの結果を取得しつつ、画面及びファイルに出力
status=`exec 3>&1; { command 2>&1 3>&-; echo $? 1>&3; } | tee command.log 1>&2 3>&-`
echo $status

①execにより3で1を指した後にcommand実行時に3を閉じてるのは何故でしょうか?
必要性がよくわからないです。
同時に1が閉じられることはないですよね?

②どういう経路でcommandの結果はstatusに格納されているのでしょうか?

③tee実行時に行っているリダイレクトの意味はどのようなものでしょうか?

正直言って全体的によく分からないです。

804:名無しさん@お腹いっぱい。
10/01/11 23:22:23
>>803
機種依存文字は書き換えました

(1)commandが3に出力しないように念のため

(2) echo $? が 3に出る。3には、あらかじめexec 3>&1 によって、
パイプではなく、コマンド置換(バッククォート)に通じる標準出力が
複製されている。よって、echoが 3に出せば 変数statusに入る。

(3)teeがcommandの出力をcommand.logに書くと同時に
同じものを 1に出そうとするが、1にそのまま出すと変数statusに入ってしまうので
2にリダイレクトして画面に表示されるようにしている。
3>&-は(1)と同じく念のため。


以上、ご教授しましたw

805:名無しさん@お腹いっぱい。
10/01/11 23:49:50
>>804
ありがとうございました。

command時に3を閉じてるので、echo時に1>&3としても出力されないと勘違いしておりました。

それと(3)について、command時に2>&1としていますが、
これはtee時の2には引き継がれないのでしょうか?
引き継がれていると、1>&2とすると元に戻って1に出力して
statusに上書きしてしまうように見えます。


806:名無しさん@お腹いっぱい。
10/01/12 06:29:53
>>805
commandとechoは無関係。
exec 3>&1したものが、commandとechoに並列して引き継がれる。
command側では3は不要なので閉じてるだけ。

commandの2とteeの2は無関係。
commandの1はパイプにつながっているので、
commandの2もパイプに流すためにcommand 2>&1 してるだけ。
teeはそのパイプを0で受けとる。
teeの1や2はcommandとは無関係で、デフォルトのまま。
そこで tee 1>&2 で画面に出す。

以上、俺もご教授しましたw

807:名無しさん@お腹いっぱい。
10/01/12 09:40:26
>>806
ありがとうございました。
全て理解できました。

808:名無しさん@お腹いっぱい。
10/01/12 18:20:04
つまり要約すると「ご教授」で正しかったのですね。
全て理解できました。

809:名無しさん@お腹いっぱい。
10/01/12 18:37:12
つまり要約すると「ご教授」で正しかったのですね。
全て理解できました。

810:名無しさん@お腹いっぱい。
10/01/12 19:15:58
大事なことなので二度言いましたよ

811:名無しさん@お腹いっぱい。
10/01/12 19:41:07
>>803ではありませんが・・・

パイプがあっても1 2ともにデフォルト
(パイプの左側で1 2が書き換えられていても、右側ではデフォルトに戻る)
ただし新しいfdが作られていると、その先も残ったまま。
(パイプの左側で3が作られていると、右側でも3が作られている状態)

パイプの左側では標準出力がパイプに渡される
パイプの右側ではパイプから標準入力を受け取る

コマンド置換は、最初のパイプの前までの標準出力を受け取る

これで理解できてますか?

812:名無しさん@お腹いっぱい。
10/01/12 20:32:25
>>811
違うね。

>(パイプの左側で1 2が書き換えられていても、右側ではデフォルトに戻る)

「右側ではデフォルトに戻る」のではなく、
そもそも最初からデフォルトのまま変化しない。


>ただし新しいfdが作られていると、その先も残ったまま。

パイプの左側で新しいfdが作られても、その先には無関係(残らない)。
>>803 では、あらかじめ execでfdを作っているから、
それを全体が受け継いでいるだけ。これと混同してはいけない。


>コマンド置換は、最初のパイプの前までの標準出力を受け取る

「最初のパイプの前」じゃなく、パイプラインの最後のコマンドの標準出力を受け取る


で、お約束の「ご教授しました」

813:名無しさん@お腹いっぱい。
10/01/12 21:37:11
誤教授しましたと言うべき。

814:名無しさん@お腹いっぱい。
10/01/12 22:00:01
>>812 thx
おおよそ理解しましたが、
2個目と3個目のレスが気になります。
> パイプの左側で新しいfdが作られても
新しいfdを作るにはexecしかないと思っていたのですが、これ以外で作れるのですか? ・・①
それとも、シェルから呼び出されたコマンドの中で作られたfdでは
> 無関係(残らない)
だけど、execで作っているときは受け継ぐという意味ですか?・・・・・・・・・・・・・・・・・・・・・・・・・②

それと
> それを全体が受け継いでいるだけ。
というのはそのシェル内で n>&- するまで有効という意味でよいですか?・・・・・・・・・・・・・・③
更にサブシェルにも受け継がれますか?・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・④

3個目の方は
> パイプラインの最後のコマンドの標準出力
とありますが、これはteeの標準出力ではないのですか?・・・・・・・・・・・・・・・・・・・・・・・・・・・・・⑤
(でも1>&2しているので、どうなるんだろう。teeは標準出力がなくなるので、3に書き込んだechoということなのかしら)

質問ばかりですみません。

815:名無しさん@お腹いっぱい。
10/01/12 22:02:31
④更にサブシェルにも受け継がれますか?
forkするプログラム書いたことあるのを思い出しました。
たしか親からfd受け継いだはずなので、これは受け継がれますよね。

816:名無しさん@お腹いっぱい。
10/01/12 22:23:58
>>814
だから、機種依存文字を使うなと、、

(1)exec以外でも勝手に新しいfdを使えるよ。
ただ、そのコマンド1つだけに有効になる。
(ここでいうコマンドには、サブシェルなどのコマンド群全体も含む)

(2)execでは、シェル自体のfdが変わるので、以降のコマンドすべてに影響。
(ただし、サブシェル内でexecした時はそのサブシェル内のみ)

(3)いいよ。あと、n>&-だけじゃなく、n>&mで別の値を複製しなおすと
execの影響は無関係になる。

(4)サブシェルにも受け継がれる

(5)teeの標準出力だよ。で、標準出力に出ないように 1>&2してる。
3に書き込んだechoもパイプライン全体の標準出力だからコマンド置換に取り込まれる。
teeで1>&2するのと、echoとは無関係。


817:名無しさん@お腹いっぱい。
10/01/13 18:38:41
丁寧なご説明ありがとうございます!

818:名無しさん@お腹いっぱい。
10/01/13 23:59:12
しかしほんとに「機種」依存文字なのか?

乗っかってるソフトウェア依存文字じゃないのか?
とりあえず俺は読めるし、歴史的に俺の使っている機種が
④を表示できるはずは無いのだけれど、表示出来ているわけよ。
(どのようにタイプしたらその字が出せるか解らんが、とりあえずコピペは出来る)

FreeBSD で LANG eucJP なのだが、2ちゃんねるビューワだと④が読めるし
コピペで転記できるよ。(書き方は不明)

ほんとに機種に依存するの?

819:名無しさん@お腹いっぱい。
10/01/14 00:04:36
ググレカス

820:名無しさん@お腹いっぱい。
10/01/14 00:38:24
丸数字やローマ数字を機種依存文字と呼ぶのは
おかんが家庭用ゲーム機ならPS3も360もファミコンと呼ぶのと同じで
言葉にこだわる必要はありません

821:名無しさん@お腹いっぱい。
10/01/14 00:52:50
丸数字が機種依存とか言われたのは歴史的経緯だわな
今や機種依存どころかUnicodeというれっきとした国際標準に含まれてる

2chで今更丸数字使うなっても化石じみてて何だかな

822:名無しさん@お腹いっぱい。
10/01/14 00:55:09
2chが化石Shift_JIS使ってるかぎり言われつづける

823:名無しさん@お腹いっぱい。
10/01/14 03:41:02
2chはcp932だろ

824:名無しさん@お腹いっぱい。
10/01/14 04:14:23
時代は UTF-8 ですよ

825:名無しさん@お腹いっぱい。
10/01/14 04:16:28
いまどきの機種依存文字といえば「~」かな

826:名無しさん@お腹いっぱい。
10/01/14 08:28:32
>>825
誰もがWindows-31JとShift_JISの区別を付けるようになれば
片が付くのにね……


827:名無しさん@お腹いっぱい。
10/01/14 09:05:59
うちのMacちゃんでは2chのカキコのローマ数字が化けるざんす。

828:名無しさん@お腹いっぱい。
10/01/14 09:44:45
この板の住人ならOSは関係ないってことくらい分かるだろ
MacJapaneseの代わりにWindows-31Jで処理するようなライブラリ使って
FirefoxでもChromiumでも何でもビルドすればいいだけ

829:名無しさん@お腹いっぱい。
10/01/14 21:53:24
半角カナは使ってもいいと思う

830:名無しさん@お腹いっぱい。
10/01/14 23:02:10
>>828
じゃあsafariをビルドする方法を教えてください。

831:名無しさん@お腹いっぱい。
10/01/14 23:41:43
フィルタリングプロキシを立てて
Windows_31JくさいShift_JISなページをUTF-8に変換してやるのが楽じゃないかな

832:名無しさん@お腹いっぱい。
10/01/15 00:12:46
それはクライアント側でフォントいじれよっていうのと等価では?

833:名無しさん@お腹いっぱい。
10/01/15 00:29:34
丸数字使うな。カス。と言う方が楽だしecoだな。

834:名無しさん@お腹いっぱい。
10/01/15 01:08:33
エコロジストならスレ違いネタでスレを消費しないでくれ

835:名無しさん@お腹いっぱい。
10/01/16 01:23:40
bashでif~とする時、[ と [[ ができますが
[ は 外部のtestコマンドで、[[が内部コマンドなんですよね?

[ ではなく [[ を使った方が
速度が速いのでしょうか?


836:名無しさん@お腹いっぱい。
10/01/16 01:50:26
bash の [ と test は builtin。[[ は compound command。
[[、[、外部コマンドの test の順に速い。
外部コマンドを呼んだ場合がダントツで遅くて、他の50倍ぐらい遅い。[[ と [ は大して変わらん。

837:835
10/01/16 02:16:10
お答えありがとう。


838:名無しさん@お腹いっぱい。
10/01/16 12:01:06
>>834
富豪プログラマのスレです。

839:名無しさん@お腹いっぱい。
10/01/26 12:21:42
●やりたいこと
カレントディレクトリ以下の全ファイル(レギュラーファイル,かなり大量,何百万単位)を
検索し,ファイル名,ファイルサイズ,MD5ハッシュ値を出力したい。
1ファイルにつき1行。

※効率よくやりたいのでファイルの数ごとにstatやmd5プロセスを起動する,という
ことは避けたい。

●やったこと
ファイルサイズだけ,とかMD5だけなら下記の方法で満足な早さで出力が得られます。
環境はMac OS Xです。
find . -type f | xargs stat -f '%N,%z' > outputfile.txt
find . -type f | xargs md5 $1 | sed -E 's/^MD5 \((.*)\) = (.*)/\1,\2/' > outputfile.txt

上の二つを合わせたようなことをしたいのですが,うまい方法を教えて下さい。



840:名無しさん@お腹いっぱい。
10/01/26 12:24:01
補足
各行が
ファイル名,ファイルサイズ,MD5ハッシュ値
という出力にしたいです。


841:名無しさん@お腹いっぱい。
10/01/26 12:27:06
コピペミスです。>>839の2つ目のfindは正しくは
find . -type f | xargs md5 | sed -E 's/^MD5 \((.*)\) = (.*)/\1,\2/' > outputfile.txt
でした。

842:名無しさん@お腹いっぱい。
10/01/26 12:49:51
perlかpythonかrubyで書きなよ。

843:名無しさん@お腹いっぱい。
10/01/26 12:52:31
●解答
joinすればいいだけ。

●補足
箇条書での質問は失礼

844:名無しさん@お腹いっぱい。
10/01/26 13:01:19
●傍観者の感想
ワロタ

845:名無しさん@お腹いっぱい。
10/01/26 13:31:04
pasteというコマンドがあってだな。



846:名無しさん@お腹いっぱい。
10/01/26 14:55:29
sed が起動するのは気にならないのかw

847:名無しさん@お腹いっぱい。
10/01/26 15:05:51
>>846
そりゃ、sedは1回しか起動しないし

848:名無しさん@お腹いっぱい。
10/01/26 16:46:34
次スレのテンプレに↓入れとけよ

●解答
perlかpythonかrubyで書きなよ。

849:名無しさん@お腹いっぱい。
10/01/26 16:50:45
>>848
>>1

・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。

Pythonも入れればよいわけだな。


850:名無しさん@お腹いっぱい。
10/01/26 16:52:39
で、今回の質問の場合 perlもpythonもruby関係なくて、
joinかpasteで済む問題だったわけだが、、

851:名無しさん@お腹いっぱい。
10/01/26 17:03:54
join, pasteは中間ファイルを作るわけだが、数百万ファイルになるとかなりのオーバーヘッドになる。
実行時間はファイルIOが支配的なのでインタプリタが消費するCPUは隠される。

従ってLLでの実装を勧めたわけだが、初心者にはわからないらしい。覚えておく事だ。

852:名無しさん@お腹いっぱい。
10/01/26 17:35:37
>>851
中間ファイルを作らずにnamed pipeでやる方法を知らない初心者らしい、、

853:名無しさん@お腹いっぱい。
10/01/26 18:31:25
この件では I/O にかかる時間でいちばん支配的なのは
find, md5, stat,(+ join を使う場合は sort)であって、
中間ファイルを使うことによるオーバーヘッドなんぞ誤差にしかならんよ。


854:名無しさん@お腹いっぱい。
10/01/26 18:34:04
中間ファイルって、MS-DOSじゃないんだから・・・

855:名無しさん@お腹いっぱい。
10/01/26 18:40:42
find × 2 → named pipe → paste

で、中間ファイルなしでメデタシメデタシ

856:名無しさん@お腹いっぱい。
10/01/26 19:28:25
一部のシェルの
diff <(command) <(command2)
みたいなのは中間ファイル作るのかしらん?


857:名無しさん@お腹いっぱい。
10/01/26 19:30:24
>>856
だから、それが named pipeなんだよw

858:名無しさん@お腹いっぱい。
10/01/26 19:31:07
mknod で作らなくてもいいのかー


859:名無しさん@お腹いっぱい。
10/01/26 22:34:39
findは全てのファイルにstatかけるのを知らない初心者? w

860:名無しさん@お腹いっぱい。
10/01/26 22:37:15
っつーか >>839>>842 をそれぞれ時間計測して比べりゃすむ話だろ
漏れは後者の勝ちだと思う


861:名無しさん@お腹いっぱい。
10/01/26 22:38:26
>>854-855
パイプのIOは発生するだろ。バカ。

862:名無しさん@お腹いっぱい。
10/01/26 22:38:31
漏れww

863:名無しさん@お腹いっぱい。
10/01/27 00:35:27
2ch初心者発見。

漏れ、とかで煽られても、、、
半年ROMってれば。

864:名無しさん@お腹いっぱい。
10/01/27 00:52:28
2ch上級者(;´Д`)

865:名無しさん@お腹いっぱい。
10/01/27 01:11:09
今時漏れなんて使わねぇよw

866:名無しさん@お腹いっぱい。
10/01/27 06:54:47
>>839 自身、find×2 を個別に実行した状態で
「満足な早さで出力が得られます」
と言っているのだから、それがすべて。
問題はそこじゃなくて、2つの出力を効率良くまとめる方法が質問点。
で、そのベストアンサーはpaste。

867:名無しさん@お腹いっぱい。
10/01/27 11:51:49
自演乙

868:名無しさん@お腹いっぱい。
10/01/27 12:54:46
>>866
負け犬の何とか…

869:名無しさん@お腹いっぱい。
10/01/27 13:17:04
>>859
ここではstatは問題にならないんだよ、初心者クン

>>860
>後者の勝ちだと思う
「思う」だけじゃ間違ったことでも言えてしまうねw

>>861
パイプのI/Oでは物理I/Oは発生しないんだよ、初心者クン

870:名無しさん@お腹いっぱい。
10/01/27 13:26:19
>>869
前言撤回? w

871:名無しさん@お腹いっぱい。
10/01/27 13:28:37
>>870
良く良め。869 は 「named pipe+paste の方が速い」という主張を一貫してしてるぞ

872:名無しさん@お腹いっぱい。
10/01/27 13:40:18
(1)シェルスクリプトでの多少高度な質問がなされる

(2)「それはPerlかPythonかRuby使った方が速い」と誰かが投稿

(3)別の人からシェルスクリプトでのマトモな回答が投稿される

(4)質問者、傍観者とも納得

(5) (2)が発狂 ← 今ココ

873:名無しさん@お腹いっぱい。
10/01/27 13:50:58
>>871 アルツハイマー?

>>853
> find, md5, stat,(+ join を使う場合は sort)であって、

874:名無しさん@お腹いっぱい。
10/01/27 13:53:01
>>869>>853 じゃないよ。

875:名無しさん@お腹いっぱい。
10/01/27 13:57:01
>>853 が言ってる statは、xargsから起動されるstatコマンドのことであって、
find内部のstatのことじゃないだろ。

876:名無しさん@お腹いっぱい。
10/01/27 14:22:00
LL:
ディレクトリ読み込み 1回
stat(i-node読み込み) ファイル個数
MD5 ファイル個数
出力

paste:
ディレクトリ読み込み 2回
stat(i-node読み込み) ファイル個数×3
MD5 ファイル個数
中間ファイル(パイプ)書き出し/読み込み
出力

ファイル数が多くてiノードのキャッシュは期待できない。
MD5はCでの実装もあるから、インタープリターのオーバー
ヘッド見込んでも、おそらくLLの方が速いね。

877:名無しさん@お腹いっぱい。
10/01/27 14:26:16
>>876
はいはい、「おそらく」と書いとけば何でも言えるねw

perl/python/ruby自体のオーバーヘッド(結構大きい)も良く考えて出直してね

878:名無しさん@お腹いっぱい。
10/01/27 14:31:44
マルチコアなCPU環境だと、
同じことやる場合でもパイプで複数のプロセスに分けた方がかえって速かったりする

879:名無しさん@お腹いっぱい。
10/01/27 14:48:09
議論してる時間で問題を解決してしまった人の勝ち。


880:名無しさん@お腹いっぱい。
10/01/27 15:07:26
>>877
ぷぷっ。そのレスはそのまま返してやるよ。w

881:名無しさん@お腹いっぱい。
10/01/27 15:11:54
find ->(パイプ)-> md5
の場合、ファイル1個あたりにかかる時間はmd5の方がはるかに大きく、
find自体の動作はmd5の実行の裏プロセス(別CPU)で行なうから、
findの実行時間はすべてmd5の実行時間内に吸収されてしまって、
結局findの時間は無関係になる。

例: sleep 1 | sleep 10 ってやると、10秒で終了する。
左側のsleep 1は無関係になる。

もう1本のfindの、
find ->(パイプ)-> statコマンド
の方は、find->md5の方よりはるかに速いから、
2つのfindを名前付きパイプでpasteに接続する場合、
実行速度は遅い方の上流パイプであるmd5だけによって決まる。

よって、stat云々は一切関係なくなり、
名前付きパイプ+pasteが高速で動作する。

882:名無しさん@お腹いっぱい。
10/01/27 15:18:31
LLが遅いと因縁つけてる奴は実測して証拠出せよ。w

883:名無しさん@お腹いっぱい。
10/01/27 15:34:47
>>860が言うようにtimeで計測すれば済む話なのになぜ誰もやらないのか
あ、俺はrubyとか知らないからパスね^^
誰かfindとperl/python/rubyでベンチ取ってよ

884:名無しさん@お腹いっぱい。
10/01/27 16:40:18
適当に試してみたよ URLリンク(pastebin.com)
$ time test.bash >/dev/null
real 1m50.762s
user 0m17.992s
sys 0m4.473s
$ time test.py >/dev/null
real 1m49.994s
user 0m19.045s
sys 0m5.523s

885:名無しさん@お腹いっぱい。
10/01/28 01:38:29
>>884
そのPythonのソースだと、各ファイルに対してstat()が最大3回呼ばれるのかな

886:名無しさん@お腹いっぱい。
10/01/28 01:58:11
ま、どう考えてもMD5sum取る部分のI/O律速になるので
stat()の回数減らしたところで誤差程度だろうけど

887:名無しさん@お腹いっぱい。
10/01/28 03:34:55
1000倍以上違うだろうね

888:名無しさん@お腹いっぱい。
10/01/28 11:54:30
>>839
> find . -type f | xargs stat -f '%N,%z' > outputfile.txt
> find . -type f | xargs md5 $1 | sed -E 's/^MD5 \((.*)\) = (.*)/\1,\2/' > outputfile.txt

findは -print0でxrgsに渡し、xargsは -0で受け取るようにしましょう。

> find . -type f -print0 | xargs -0 stat -f '%N,%z' > outputfile.txt
> find . -type f | xargs -0 md5 | sed -E 's/^MD5 \((.*)\) = (.*)/\1,\2/' > outputfile.txt

URLリンク(www.otsune.com)

889:名無しさん@お腹いっぱい。
10/01/28 17:51:27
こんなのfind + perl のワンライナーでいいじゃん
> find . -type f -print | perl -l0ne 'use Digest::MD5 qw(md5_hex);$s=-s $_;print $_ ." $s " . md5_hex($_) ."\n"'

890:名無しさん@お腹いっぱい。
10/01/28 18:10:27
>>889
アフォか、ファイル名の md5 計算してどうする www

891:名無しさん@お腹いっぱい。
10/01/28 18:13:23
>>888
日記だからある意味しょうがないのだが。そういう古臭いページなんとかならないもんかね。

892:名無しさん@お腹いっぱい。
10/01/28 18:22:57
>>890
おー、いまperldocしたら 
calculate the MD5 digest of this "message"
ってかいてあったwwはずかしいwwwしぬかも

893:名無しさん@お腹いっぱい。
10/01/28 19:05:07
>>891
どこがどう古臭いんだ?

894:名無しさん@お腹いっぱい。
10/01/28 19:22:17
今書くなら「xargs捨てろ。 -exec {} +使え」

895:名無しさん@お腹いっぱい。
10/01/28 19:22:36
>>894
一緒じゃないの?

896:名無しさん@お腹いっぱい。
10/01/28 20:27:35
-exec だと正しく受け取れないファイルがある。
-print0 |xargs -0のほうが安全

897:名無しさん@お腹いっぱい。
10/01/28 21:09:21
へー知らんかった

898:名無しさん@お腹いっぱい。
10/01/28 21:11:42
>>896
原理的に有り得ないんだけど。

899:名無しさん@お腹いっぱい。
10/01/28 21:13:42
どっちだよ気になるだろ

900:名無しさん@お腹いっぱい。
10/01/28 21:37:46
-exec の + ターミネータ(;でなく)を知らないで答えていたりしてな。


901:名無しさん@お腹いっぱい。
10/01/28 21:52:49
それにしても「正しく受け取れない」は原理的にない。

902:名無しさん@お腹いっぱい。
10/01/28 22:08:06
いや、あるから -0 オプションが後から追加されたんですが。

903:名無しさん@お腹いっぱい。
10/01/28 22:08:48
って、xargs じゃなくて find の方か。ならないや。ごめん。


904:名無しさん@お腹いっぱい。
10/01/28 22:17:25
結局>>896は本当なのかどうなのか答えてくれ
つまり実際に-exec +だと受けとれないファイルがあるのか
それとも単に-exec ;と-exec +を混同してただけなのか

それと>>894の-exec +のほうが良いという根拠は何だ?
-print0 | xargs -0じゃいかんのか?

このままじゃ気になって寝れやしない

905:名無しさん@お腹いっぱい。
10/01/28 22:42:34
>>904
> それと>>894の-exec +のほうが良いという根拠は何だ?
exec +がある環境ならxargsはレガシーコマンド。webで解説する必要は無い。

そもそも、exec +が無い環境がレガシー。 xargsはジジイの胸の奥にしまっておいてくれ。

906:名無しさん@お腹いっぱい。
10/01/28 22:49:15
GNU findutilsにxargs付いてくるじゃない

907:名無しさん@お腹いっぱい。
10/01/28 22:51:58
ジジイの懐古趣味

908:名無しさん@お腹いっぱい。
10/01/29 01:55:18
xargs がいつobsolete になったの?
なんか文書ある?

909:名無しさん@お腹いっぱい。
10/01/29 12:12:24
-exec + のデメリット
コマンドに渡すファイルの数を制御できない(xargs -n)
並列実行できない(xargs -P)

-exec + のメリット
find でひっかかったファイルが存在しなければコマンドが実行されない
(GNU xargs は入力がゼロでもなぜか1回は実行する; xargs -r で抑制可)

つーか、
ps ax | awk '/なんか条件/{print $1}' | xargs -r kill
みたいに find とは無関係に使う場合も多いから、obsolete のはずがない。


910:名無しさん@お腹いっぱい。
10/01/29 16:58:01
findの-execはひとつひとつ実行するから遅いだろ。
grep /dev/null というバッドノウハウもアレだけど。(-h使えって?)

911:名無しさん@お腹いっぱい。
10/01/29 17:01:35
>>910
find -exec + の 「+」の意味を理解していない方は発言を御遠慮ください


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch