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

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

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

□お約束 
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。 
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。 
 Linuxユーザは/bin/shの正体がbashなので特に注意。 
 FreeBSDユーザは/bin/shの正体がashなので注意。 
 v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。 
  http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/ ;
  http://heirloom.sourceforge.net/sh.html ;
・csh/tcshのシェルスクリプトは推奨されません。 
 (理由は「csh-whynot」でググれ) 
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。 
 manや参考リンクを見ましょう。 
 aproposないしはman -kでそれらしい単語による簡単な検索もできます。 
・シェルスクリプトのことをシェルってゆーな 
・シェルで使えるワイルドカード等は正規表現ではありません。 
 正規表現の話題はスレ違い(正規表現スレへ) 

□初心者へのアドバイス: 
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも 
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。 
・知らないコマンドが出てきたらmanを引きましょう。 
・思い通りに動かないときは、まずは sh -x でトレースしましょう。 

前スレ 
シェルスクリプト総合 その15
http://pc12.2ch.net/test/read.cgi/unix/1246408968/l50
0647名無しさん@お腹いっぱい。2010/09/03(金) 19:38:51
>>645 は実際のシェルはexec使わずに実装されてるとでも思ってるのだろうか
0648名無しさん@お腹いっぱい。2010/09/03(金) 20:12:21
printf("hoge> "),gets(b)

カンマ区切りの実行順は確定だっけ?
0649名無しさん@お腹いっぱい。2010/09/03(金) 20:41:07
カンマ演算子は左が先。
関数引数のカンマで区切られた各項の評価順序は不定。

「副作用完了点」でぐぐろう。
0650名無しさん@お腹いっぱい。2010/09/05(日) 19:15:10
そんなに上げ足とらなくても、シェルスクリプトとシェルの誤用くらい文脈でわかるだろ。
SQL ServerをSQLって呼ぶのに比べりゃ大したことない。
0651名無しさん@お腹いっぱい。2010/09/05(日) 19:44:10
じゃあPC98をさして一太郎といってもいいんですか?
0652名無しさん@お腹いっぱい。2010/09/05(日) 19:51:18
そもそも誤用でもないし
0653名無しさん@お腹いっぱい。2010/09/05(日) 20:53:42
>>650
揚げ足ってどのレスのことだよ
0654名無しさん@お腹いっぱい。2010/09/05(日) 21:11:54
>>653
>>617に対する>>619から始まったシェルを作るって話のこと。
0655名無しさん@お腹いっぱい。2010/09/06(月) 00:34:26
俺は50ccATミッション車を総合的に「ラッタッタ」と呼ぶ。
異論は認めない
0656名無しさん@お腹いっぱい。2010/09/06(月) 08:56:24
俺は JIS規格のステープラのことを総合的にホッチキスと呼ぶ
異論は認めるw
0657名無しさん@お腹いっぱい。2010/09/06(月) 16:07:08
俺は、白い綿シャツを「ホワイトシャツ」と呼ぶ、ネイティブな
発音は認めない
0658名無しさん@お腹いっぱい。2010/09/06(月) 16:14:46
もういいです。
0659名無しさん@お腹いっぱい。2010/09/06(月) 16:21:04
俺はPCなどのコンピュータハードウェアのことをミシンと呼ぶ(サーバーミシン等)
縫製機械のことを連想してしまうやつは認めない。
0660名無しさん@お腹いっぱい。2010/09/06(月) 18:58:16
うちのおかんはゲームコンソールは全てファミコンという
0661名無しさん@お腹いっぱい。2010/09/06(月) 20:06:12
for file in *
do
mv "$file" "${file/hoge/piyo}"
done
0662名無しさん@お腹いっぱい。2010/09/06(月) 20:48:12
同時に8スレッド走るCPUで大量のシェルスクリプトを実行したくてxargsつかっているのですが、
うまく動かなくて困っています。分かる人教えてください。

やりたいことは、数値計算の実効シェルスクリプト(300個くらいある)を同時に最大8個走らせ、
一つ終了したら次が始まるようにしたい。

args.listファイルにシェルスクリプトの絶対パスを1行ずつ書き並べて
xargs --arg-file=args.list --max-procs=8 -L 1
としましたが、topコマンドで確認しても全く動いている気配がありません。

クラスター用のjobマネージャは使わず、あくまでlinuxで一般的に使えるコマンドで済ませたいです。
0663名無しさん@お腹いっぱい。2010/09/06(月) 20:57:54
犬板に(・∀・)カエレ!!
0664名無しさん@お腹いっぱい。2010/09/06(月) 21:32:30
>>662
--arg-file はあくまで「引数」リストだから。
実行するシェルスクリプトを書き並べても引数になるだけで実行されない。

実行するには xargsのコマンドとしてシェルを書かないと。

xargs --arg-file=args.list --max-procs=8 -L 1 sh
0665名無しさん@お腹いっぱい。2010/09/06(月) 23:46:45
そんなに時間が惜しいなら、最低限LLでやるべきだろ。
06666622010/09/07(火) 01:41:39
おお、できました!
自分も引数リストであることは引っかかっていたのですが、どう解決すればいいか分かりませんでした。
ありがとうございました。


>>665
これは私に対するレスですか?LLというのはAWKとかParlとかのことですか?
『LLを使うと時間短縮になる』というイメージが湧かないのですが、具体的にどんな方法があるんでしょうか?
0667名無しさん@お腹いっぱい。2010/09/07(火) 01:43:34
実際Perlとかで書いてみて時間計って、
シェルスクリプトと比べてみるといいよ。
0668名無しさん@お腹いっぱい。2010/09/07(火) 06:33:27
>>664
> シェルを書かないと。

↑シェルを書いちゃう回答者現るw
0669名無しさん@お腹いっぱい。2010/09/07(火) 08:15:01
shってシェルじゃないの?
0670名無しさん@お腹いっぱい。2010/09/07(火) 08:15:29
そこはシェルでおけ
0671名無しさん@お腹いっぱい。2010/09/07(火) 09:37:54
>>669
一般的な呼び方だと、ボーンシェル、Bシェル(ビーシェル)と
呼ぶんで、シェルとは呼ばない。
0672名無しさん@お腹いっぱい。2010/09/07(火) 09:47:45
指定したシェルスクリプトを実行するシェルなんだからいいじゃんか
そのうちshと想定して回答しただけだろ
字面で反応した恥ずかしいミスを指摘されてキョドるなよ
0673名無しさん@お腹いっぱい。2010/09/07(火) 09:59:19
>>672
スクリプトの前にアンカー覚えろよ
0674名無しさん@お腹いっぱい。2010/09/07(火) 12:29:12
> 数値計算の実効シェルスクリプト(300個くらいある)
これって「数値計算」をシェルスクリプトでやってるのかなあ?
06756662010/09/07(火) 12:30:37
>>667
科学計算についてどの程度知った上でのレスでしょうか?

300個ある実行シェルスクリプトは全て、中でFortranのプログラムを呼び出しているだけです。
シェルスクリプトは初期値や環境変数の設定に使うだけであって、それで数値計算しているわけではないです。

『Perlで書いてみて』というのは、具体的にどの部分を言っているのですか?
06766662010/09/07(火) 12:32:32
レスがかぶった。
0677名無しさん@お腹いっぱい。2010/09/07(火) 12:55:12
さー
情報後出し祭りに突入してきましたよ
0678名無しさん@お腹いっぱい。2010/09/07(火) 12:59:10
情報後出しじゃないだろ

>>662 の質問は >>664 で解決してる。解決報告は >>666

質問の解決後に >>667 の Perl厨が余計なことを言い出した。
それに対する反論として >>675 が書かれただけ。

Perl厨はきっと今ごろ赤面w
0679名無しさん@お腹いっぱい。2010/09/07(火) 14:21:26
>>678
そうか?
別に深く追求しないで
「単純に時間を計って比べてみな」ってだけなんだから

「現状が速いです」で済む話なんだが?


0680名無しさん@お腹いっぱい。2010/09/07(火) 15:07:59
>300個ある実行シェルスクリプトは全て、中でFortranのプログラムを呼び出しているだけです。
なんで、ここもプログラムにしないの?
普通は、函数化はしてあるだろうから、それを呼び出すようにするだけじゃん。
わざわざシェル経由して、xargsでこねくり回す意味がわからんわ。

完全に情報後出しの下手ないい訳だなw
0681名無しさん@お腹いっぱい。2010/09/07(火) 15:13:56
>>680
よくよめ

xargs使うのは、-max-procs=8 を指定したいから。
同時に動くプロセスを常に8個に保った状態で回したい。
これはFortranだけではできない。

-max-procs=8については最初の質問の >>664 に書かれている。

全く持って「後出しではない」
0682名無しさん@お腹いっぱい。2010/09/07(火) 15:17:44
>>680
>普通は、函数化はしてあるだろうから、それを呼び出すようにするだけじゃん。


それを呼び出すようにするだけだとシングルスレッドにしかならないよ。
8スレッド使いたいという質問だったのでは?
0683名無しさん@お腹いっぱい。2010/09/07(火) 15:43:23
だから、並列化の部分のところを含めてプログラムにすれば?
と、言ってると思うんだが?
>>これはFortranだけではできない。
数値計算の並列化なんて、Fortranの最も得意とするところじゃん。
0684名無しさん@お腹いっぱい。2010/09/07(火) 15:44:00
>>680
特定のパラーメータ振ったデータを生成して、fortranの解析プログラムを起動する
スクリプトなんだろ。そもそもそういう解析プログラムはコマーシャルソフトや別
部門が作ったソフトの場合が多く、それを呼び出すようになど出来ない場合が多い。
他にも、解析プログラムに、汎用でない特定の用途のパラメータ振りを組み込む事
は嬉しくないから、スクリプトで対応する可能性もある。

>>662を読んでその程度を推測できないアマチュアはネチネチと絡むんじゃねーよ。
0685名無しさん@お腹いっぱい。2010/09/07(火) 16:21:55
>>683
>>これはFortranだけではできない。
>数値計算の並列化なんて、Fortranの最も得意とするところじゃん。

話をすり替えてはイカン。
数値計算の並列化の話ではなくて、
既存の複数のFortranプログラムを「プロセスをちょうど8個に保ったまま並列起動」したい
という話。
0686名無しさん@お腹いっぱい。2010/09/10(金) 07:17:49
長い文字列を変数に代入するとき読みやすいように、その文字列を複数行に
分けたいのですけど、お勧めの方法はなんでしょうか?
0687名無しさん@お腹いっぱい。2010/09/10(金) 07:24:23
>>686
普通にバックスラッシュで改行すればいい。
「バックスラッシュ+改行」は消えてなくなって代入される
0688名無しさん@お腹いっぱい。2010/09/10(金) 08:46:11
>>687
つまり

declare str="xxx"\
"yyy"\
"zzz"

ということですか。
ちょっと見辛いのですよね。
他にありませんでしょうか?

C++だと

declare str="xxx"\
        "yyy"\
        "zzz"

のように書けるのですが。
0689名無しさん@お腹いっぱい。2010/09/10(金) 09:30:34
>>680
こんな馬鹿もプログラマーなのか?
0690名無しさん@お腹いっぱい。2010/09/10(金) 09:30:45
>>688
おいおい、C/C++ならそんなことしなくても、

str = "hoge"
"boke"
"aho";


と書けるだろw
0691名無しさん@お腹いっぱい。2010/09/10(金) 09:52:25
>>688
データ上はあくまで1行の文字列を、
文字列が長過ぎる(たとえば100文字以上)だから、
スクリプト上では2行以上にわけて記述したいという話だろ?

だったら、2行目以降はインデントせずに
行頭から記述した方が、前の行からデータが継続していて
実際は1行であることがわかりやすい。
(変にインデントするとスペースやタブや改行がデータに入ってるように誤解する)

よって、>>687 の言う方法で良い。
0692名無しさん@お腹いっぱい。2010/09/10(金) 09:59:25
str="xxx
yyy
zzz"
0693名無しさん@お腹いっぱい。2010/09/10(金) 10:02:42
>>692
質問良く良め。それだと改行が入るだろw (質問は >>686 な)
0694名無しさん@お腹いっぱい。2010/09/10(金) 10:16:11
>>686
そういうのは最低限LLでやるべきだろ。
実際Perlとかで書いてみて、
シェルスクリプトと比べてみるといいよ。
0695名無しさん@お腹いっぱい。2010/09/10(金) 10:31:54
>>690
意地悪ですねw。

>>694
LLってなんですか?
学がなくて申し訳ないです。
0696名無しさん@お腹いっぱい。2010/09/10(金) 10:35:47
むかし英語の教材であったな。ステレオトラックの片chに自分の発音を重ねて録音できる。
0697名無しさん@お腹いっぱい。2010/09/10(金) 11:23:06
バックグランドで動いているプロセスが吐き出すメッセージを
スクリプトで取得したいのですが、上手くいきません

$ hoge.sh > log &
とのようにすれば可能なのは理解しているのですが、
$ hoge.sh & > log
を実現したいのです

hage.sh内でhoge.sh &を実行しているのですが、
どちらも改変不可なのでhige.sh->hage.sh->hoge.sh
と呼び出さざるを得ません

コマンドラインからhage.shを実行するとhoge.shの出力が画面上で
得られますが、hige.shから呼び出すと、なにも出力されなくなります

このようなことは可能でしょうか?
0698名無しさん@お腹いっぱい。2010/09/10(金) 11:39:30
(hoge.sh &) > log
06996972010/09/10(金) 12:31:26
>>698

できました!
サブシェルを使うんですね

07006972010/09/10(金) 14:52:39
引き続きですいません

どうも出力がバッファリングされているようで、
hoge.sh終了までファイルに書き込まれません

ぐぐるとsttyで制御するようなので

stty raw; ( hoge.sh & ) > log ; stty sane; tail -f log
とか
( stty raw ; hoge.sh & ) > log ; stty sane; tail -f log
とかやってみましたが、バッファリングが止まりません

解決するための設定・コマンドはありますでしょうか?
0701名無しさん@お腹いっぱい。2010/09/10(金) 16:41:21
>>697

(hoge.sh &) > log
hoge.sh > log &

そもそも、前者によって何を実現したくて、それが何故後者では実現できないのかが分からない。
hage.sh, hoge.shが改変不可で、そのラッパーであるhige.shを作る(のですよね?)、そして

> コマンドラインからhage.shを実行するとhoge.shの出力が画面上で
> 得られますが、hige.shから呼び出すと、なにも出力されなくなります

のようにしたい(のですよね?)って言う話と、最初の話がいまいち繋ってこないんだけど。

ってか
exec > log
hoge.sh &
じゃ駄目なんだろうか?
0702名無しさん@お腹いっぱい。2010/09/10(金) 16:49:27
>>700
stty無関係。

仮にhoge.shが下のようなのだと、ちゃんと出てくるはず。
#!/bin/sh
echo 1
sleep 5
echo 2
sleep 5
echo 3

hoge.shの中で動かしているプログラムが端末以外に出力するときに
勝手にバッファリングするようになってるんじゃないか?
07036972010/09/10(金) 17:49:17
>>701

それです!

さらにこの先に、1分間だけ出力ログを監査して問題なければlogoutというのが待っていまして、
そのため第一弾としてログに吐かせようとして、なんだか山にぶつかってたというところです
上手くいけばログをパイプ変更して監査スクリプトに渡すところを作って完了です
土日で終わるといいな。。。


> exec > log
> hoge.sh &
これ、あっさりいけました!
execって引数なしだとリダイレクトなんですね
この使い方初めて知りました


>>702

その通りでした
hoge.shの中でいろいろコマンド呼び出してるんですが、
それがバッファリングしてました
こっちは改変できそうなのでなんとかなりそうです


これで先に進めますm(__)m
0704名無しさん@お腹いっぱい。2010/09/10(金) 23:52:06
>>703
> この使い方初めて知りました
シェルの基本ですよ。
ttp://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/sh-text/sh/node62.html
他にも以下を知ってることを確認しておくと良いです。
ttp://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/sh-text/sh/node31.html
ttp://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/sh-text/sh/node40.html
ttp://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/sh-text/sh/node64.html
ttp://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/sh-text/sh/node65.html
ttp://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/sh-text/sh/node66.html

また、時間があるときにでも、全部読んでおくべきです。
ttp://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/sh-text/sh/sh.html

0705名無しさん@お腹いっぱい。2010/09/11(土) 00:02:24
ttp://www.google.com/search?q=csh+whynot
0706名無しさん@お腹いっぱい。2010/09/12(日) 04:53:07
シェルスクリプトで、変数値を変数名として使用したいのですが可能でしょうか?

例えば、
===============
VAR1="ABC"
VAR2="DEF"
VAR3="GHI"
AAA1="VAR1"
AAA2="VAR2"
AAA3="VAR3"
===============
として、通常であれば、$VAR1・$VAR2・$VAR3となると思うのですが、
これをAAA1〜3の値を変数名としてfor文で「$i」使用してVAR1〜3の値を参照したいのです。

よろしくお願い致します。
07077062010/09/12(日) 04:55:33
書き忘れました。bashスクリプトです。
0708名無しさん@お腹いっぱい。2010/09/12(日) 05:16:42
>>706
for i in AAA1 AAA2 AAA3;
do
i=${!i}
echo ${!i}
done
かな。もちろん/bin/shでは動かないけど。
0709名無しさん@お腹いっぱい。2010/09/12(日) 06:45:55
>>706
bash依存じゃなくてできる。(純正/bin/shでも動く)


VAR1="ABC"
VAR2="DEF"
VAR3="GHI"
AAA1="VAR1"
AAA2="VAR2"
AAA3="VAR3"

for i in AAA1 AAA2 AAA3
do
eval echo '$'$i
done
0710名無しさん@お腹いっぱい。2010/09/12(日) 06:53:48
>>709
2重間接だよ。もう1段 evalが必要。

eval eval echo '"$"''$'$i
0711名無しさん@お腹いっぱい。2010/09/12(日) 20:32:49
そういうのは最低限LLでやるべきだろ。
実際Perlとかで書いてみて、
シェルスクリプトと比べてみるといいよ。
0712名無しさん@お腹いっぱい。2010/09/12(日) 21:26:47
>>711
つまらん。やめとけ。
07136972010/09/13(月) 18:49:51
shで入力待ちのタイムアウト処理をしようと
http://www.edu.ics.saitama-u.ac.jp/~j0114ky/first/html_enshu/10.4.html
のタイムアウト処理を実行したところlinuxで動きませんでした

http://www.nurs.or.jp/~sug/soft/super/bash.htm#sec7
の例も動かず、二日悩んでsolaris10で動かすとちゃんと動く

bashのバージョン違いで挙動が変わるのかと思いつつ、
/bin/配下を眺めてると/bin/bshを発見、あっさり動きました。。。


あんまりこういう使い方はしないと思いますが備忘録的に残しておきます



>>704

ありがとうございます
shはrcを眺めて覚えたんですが、一度はちゃんと仕様から勉強するべきですね
0714名無しさん@お腹いっぱい。2010/09/13(月) 19:00:50
>>713
せっかく bashがあるんならもっとスマートにタイムアウト処理できるよ。
こっちがお勧め(5秒待ちの例)


read -t 5 hoge
0715名無しさん@お腹いっぱい。2010/09/14(火) 00:20:51
>>713-714
参考になったぜ。thx!
0716名無しさん@お腹いっぱい。2010/09/14(火) 22:11:42
指定した年月の月末&その先月末をあっさりと出す方法はないでしょうか。
e.g. 200909 -> 20090931 & 20090831
date -d "1 month 1 day ago YYYYMMDD"でいけると思っていましたが、
「-dなんてネーよバーカ」とSunOSに怒られました。

閏年を考慮しない方法で無理矢理書きはしましたが、
なにかスマートな方法があればお教え下さい。
0717名無しさん@お腹いっぱい。2010/09/14(火) 22:13:37
200909 -> 20090930 & 20090831 でしたねスミマセン
0718名無しさん@お腹いっぱい。2010/09/14(火) 22:40:14
SunOS知らんけど俺の環境では
YYYYMM=200909
date -j -v+1m -v1d -v-1d ${YYYYMM}010000 +%Y%m%d
date -j -v1d -v-1d ${YYYYMM}010000 +%Y%m%d

-v1dは冗長かも
0719名無しさん@お腹いっぱい。2010/09/14(火) 22:47:26
>>718
FreeBSDの話なんかしてねーよ
0720名無しさん@お腹いっぱい。2010/09/14(火) 22:53:40
perl入れてperlで書けや
07217162010/09/14(火) 22:55:40
>>718
そんなべんりーなオプションはなく、
ttp://docs.sun.com/app/docs/doc/819-1210/date-1?l=en&n=1&a=view
こんな感じのオプションしかなかったです
07227162010/09/14(火) 23:00:17
>>720
その処理だけPerlで書いて外部コマンドとして呼ぶことも候補には入れていますが
やっぱりできればシェルスクリプトで書きたいと思っていました。
(モジュールを追加できないので標準モジュールでどこまでできるかも不明ですし)
0723名無しさん@お腹いっぱい。2010/09/14(火) 23:02:28
文字列を年と月に分けて閏年をまじめにチェックするしか方法ないんじゃない?
if文とexprのいい練習課題だね
0724名無しさん@お腹いっぱい。2010/09/14(火) 23:05:27
そういうのは最低限LLでやるべきだろ。
実際Perlとかで書いてみて、
シェルスクリプトと比べてみるといいよ。
0725名無しさん@お腹いっぱい。2010/09/14(火) 23:08:23
配列とか使うわけじゃないし、どっちで書いても大差ないだろうね
とマジレステスト
0726名無しさん@お腹いっぱい。2010/09/14(火) 23:08:54
Solarisのdateコマンドって、現在時刻以外を指定できないんだよ。
だから >>723 が言うような if や expr では解決しない。

Solarisのdateで現在時刻以外を指定するのに、
環境変数TZをいじって 24時間を超える大きなタイムゾーンを捏造するという
裏技があるが、そういう変な方法しかない。
0727名無しさん@お腹いっぱい。2010/09/14(火) 23:12:17
>>726
>>723 は date自体を使わずに、日付の数値を自分で計算しろと言ってるのでは?
0728名無しさん@お腹いっぱい。2010/09/14(火) 23:54:36
閏年とか面倒ならその辺はcalに任せればいいのでは。
0729名無しさん@お腹いっぱい。2010/09/15(水) 00:04:20
参考: 指定月の月末日を求める

set `cal 8 2010`; shift `expr $# - 1`; echo $1
0730名無しさん@お腹いっぱい。2010/09/15(水) 01:02:19
>>729
おもしろいやり方してるな。
俺は普通にgrepとtailとsedあたりでやることを考えてしまうんで、ちょっと新鮮だ。
0731名無しさん@お腹いっぱい。2010/09/15(水) 01:07:27
可搬性はあまり確かめてないけど、Mac(BSD系)では動いてる気がする。

cal 8 2010 | tr -s ' ' '¥012' | sed -n '$p'
0732名無しさん@お腹いっぱい。2010/09/15(水) 01:23:18
>>731
Solaris 10, Ubuntu 10.04はokだった。
0733名無しさん@お腹いっぱい。2010/09/15(水) 02:32:21
>>729
arg配列のそんな使い方があったのか。 自分が思いつくのは普通の
配列だな。

$ DAYS=(`cal 8 2010`); echo ${DAYS[`expr ${#DAYS[*]} - 1`]}
0734名無しさん@お腹いっぱい。2010/09/15(水) 16:35:01
grepとかsedみたいにshで出力を処理したいんだけど

./example | while read x
do
 なんか処理して変数代入とか
done
変数を利用して後処理

というのをパイプ(サブシェル)を使わずにできない?
変数相当の値を一旦外部ファイルに書き出さないと駄目かな

exampleの出力を自身の入力にできるといいんだけど

0735名無しさん@お腹いっぱい。2010/09/15(水) 16:51:27
>>734

RESULT=`./example | while read x
do
 なんか処理して echo 処理結果
done`

"$RESULT" を利用して後処理
0736名無しさん@お腹いっぱい。2010/09/15(水) 17:44:06
./example |{ while read x; do ... done; echo $hoge;}
のようにすれば、while の外に出ても {} の内側にいるかぎりは変数の値が見える。

以下のようにすればそもそもサブシェルが生成されないが、
何やってるのかひじょーにわかりにくいのでオススメはしない。
while read x; do ... done <<_EOF_
`./example`
_EOF_

bash 限定。
while read x; do ... done <<<"`./example`"
0737名無しさん@お腹いっぱい。2010/09/15(水) 19:46:27
#!/bin/sh

[ -z "$HOGE" ] && { ./example | HOGE=hage exec $0; }

while read x; do
 なんか処理して echo 処理結果
done
07387162010/09/16(木) 01:30:00
cal…正にこれが求めていたものです!
UNIXを初めて触ったころには使っていましたが、
それ以来一切関わることなく脳内から完全に抜け落ちていました。
cal出力の最後を月末とすることでうまくいきそうです。
レスくれた方ありがとうございました!
0739名無しさん@お腹いっぱい。2010/09/16(木) 19:10:11
cal はK&Pの「環境」のシェルスクリプトを作成する例で使用されていて、
斯界のおっさんたちは皆一度は試してるんだぞぉ
07407342010/09/16(木) 19:11:08
>>735>>736>>737
thx!

737は思いもつかなかったが、こういう書き方もあるのか

0741名無しさん@お腹いっぱい。2010/09/16(木) 19:23:19
>>737 って環境によってはハングして動かないよ。
ネタで書いてると思ったよ。
0742名無しさん@お腹いっぱい。2010/09/17(金) 07:42:06
どんなヘボシェルだよ。ww
0743名無しさん@お腹いっぱい。2010/09/17(金) 08:09:55
>>742
FreeBSDの/bin/shで、>>737 動かないよ。

たしかにFreeBSDはヘボだな。
0744名無しさん@お腹いっぱい。2010/09/17(金) 08:31:55
これならヘボいのでも動くだろう。
[ -z "$HOGE" ] && { ./example | HOGE=hage $0; exit; }
0745名無しさん@お腹いっぱい。2010/09/17(金) 08:41:25
逆に、>>737 が動くようなシェルなら、
わざわざこんなことしなくても、
command | while ... がサブシェルにならないから、

最初から command | while ... と書けばいいんだな。

よって、>>737 は全然解決になってない。
0746名無しさん@お腹いっぱい。2010/09/17(金) 08:51:57
改訂版が出てるんだから、言いがかりならそっちに付けろよ。w
0747名無しさん@お腹いっぱい。2010/09/17(金) 09:09:00
採点が終ってから答を直しても単位はあげられないんだよ
■ このスレッドは過去ログ倉庫に格納されています