68user's page 掲示板

Prev< No. 3643〜3648> Next  [最新発言に戻る] [過去ログ一覧]
No. 3643 # バンガード [URL] [E-mail] 2004/03/22 (月) 16:12:09
>>3642 68user
まず、3行目から10行目を修正した場合の結果は以下の通りです。
0:合計 7
1:-rw-r--r-- 1 furu man 4 Mar 22 15:59 test1
2:-rw-r--r-- 1 furu man 8 Mar 22 16:00 test2
3:-rw-r--r-- 1 furu man 8 Mar 22 16:00 test3
4:-rw-r--r-- 1 furu man 12 Mar 22 16:01 test4
5:-rw-r--r-- 1 furu man 12 Mar 22 16:01 test5
6:-rw-r--r-- 1 furu man 4 Mar 22 16:01 test6
7:-rw-r--r-- 1 furu man 20 Mar 22 16:02 test7

0:合計 7
1:-rw-r--r-- 1 furu man 4 Mar 22 15:59 test1
2:-rw-r--r-- 1 furu man 8 Mar 22 16:00 test2
3:-rw-r--r-- 1 furu man 8 Mar 22 16:00 test3
4:-rw-r--r-- 1 furu man 12 Mar 22 16:01 test4

次に3行目から10行目を修正しない場合の出力結果です。
0:
1:
2:
3:
4:

ちなみに7行目のecho文をコメントにしても結果は同じです。

この様にwhile文をダブルクォーテーションで囲むかどうかでwhile
文を抜けた後で配列を参照できるかが異なってきます。

No.3639でzshさんが回答されている様にダブルクォーテーションで囲んでいるために別プロセスになってしまうのが原因の様です。
whileの出力を変数に格納した上で、whileから抜けた後も配列の内容が参照出来る様にするにはどうしたら良いのでしょうか?

No. 3644 # 68user 2004/03/22 (月) 17:05:31
>>3643 バンガード
> ちなみに7行目のecho文をコメントにしても結果は同じです。
わたしはありえないと思いますが、そういう ksh もあるんですかね。
当方の HP-UX11i で
    #!/usr/bin/ksh
    INDEX=0
    ls -l |
    while read LINE; do
        CMD[$INDEX]=$LINE
        let "INDEX = INDEX + 1"
    done
    INDEX=0
    while [ $INDEX -lt 5 ]; do
        echo $INDEX":"${CMD[$INDEX]}
        let "INDEX = INDEX + 1"
    done
というのスクリプトを実行したところ、
    0:合計 7
    1:-rw-r--r-- 1 furu man 4 Mar 22 15:59 test1
    2:-rw-r--r-- 1 furu man 8 Mar 22 16:00 test2
    3:-rw-r--r-- 1 furu man 8 Mar 22 16:00 test3
    4:-rw-r--r-- 1 furu man 12 Mar 22 16:01 test4
というような、先頭 5 行分だけの出力が得られました。

No. 3645 # バンガード [URL] [E-mail] 2004/03/22 (月) 19:34:47
>>3644 68user
御提示いただいたシェルなら当方(AIX 5.1)でも同様の結果が出
ます。

以下の様に修正した場合に配列の中身が2つ目のwhile文で出力され
なくなります。
        #!/usr/bin/ksh
        INDEX=0
        TEST=`ls -l |
        while read LINE; do
                CMD[$INDEX]=$LINE
                let "INDEX = INDEX + 1"
        done`
        INDEX=0
        while [ $INDEX -lt 5 ]; do
                echo $INDEX":"${CMD[$INDEX]}
                let "INDEX = INDEX + 1"
        done

No. 3646 # 68user 2004/03/23 (火) 01:56:23
>>3645 バンガード
> 御提示いただいたシェルなら当方(AIX 5.1)でも同様の結果が出ます。
そうでしょうね。

> 以下の様に修正した場合に配列の中身が2つ目のwhile文で出力されなくなります。
そうなりますね。`〜` とするとサブシェルが起動されますから、
$CMD が設定されるのはサブシェルだけで、親のシェルには反映
されません。

質問を続ける目的が全く見えません。>>3644 のスクリプトは >>3641
の希望を満たしているように見えますが違うのですか? まだ説明して
いない理由があって、>>3644 は採用できないのですか?

No. 3647 # バンガード [URL] [E-mail] 2004/03/23 (火) 03:49:34
>>3646 68user
>質問を続ける目的が全く見えません。>>3644 のスクリプトは >>3641
の希望を満たしているように見えますが違うのですか? まだ説明して
>いない理由があって、>>3644 は採用できないのですか?
3644のスクリプトでは、最初のwhile文の出力を変数に格納していません。
この形式であれば、最初の私の質問で御提示させていただいている通りで
す。(3行目から10行目を修正したもの)
次に質問を続ける理由ですが、3642で「echo しているからでは?
echo しなければ OK かと思います。」
「ループを抜けた後でも参照が可能だと思います。」と回答されているの
で、そんなことは無いと言うことで3643の回答をしています。

それに対して、3644で「わたしはありえないと思いますが」とお答え
いただいていますよね?
ですから、それに対しての回答で3645の回答をさせていただいていま
す。

3642の回答が無ければ、3639の回答で「なるほど」と納得していた
のですが、3640で「なぜだめなのか?」と言う事ですので状況を説
明させていただいている次第です。

結局3640の回答にある通り、バッククォーテーションで囲んでいる
ために別のジョブとして起動されるためにwhileから抜けた後で配
列を参照できないのですよね。

私としては最初のwhile文での出力を変数に格納した上でwhile文の
外でも配列の中身を参照したいと言うのが最終目標です。
しかしながら、バッククォーテーションで囲んだ以上は別タスクに
なるために、while文の外で配列が参照できないとなれば、最初の
while文の出力をファイルに格納するしかないかと考えています。
もし、それ以外の方法があるのであれば、お教えいただけると助か
ります。

No. 3648 # 68user 2004/03/23 (火) 10:26:19
>>3647 バンガード
やっとわかりました。変数に格納って TEST=`…` のことですか。

わたしの読解力が足らないだけでしょうが、
      「変数 TEST に ls の出力全体を、CMD には 1行ずつの
          結果を代入したい」
     「このスクリプトの目的は ls の結果全体を表示しつつ、
          なおかつ先頭 5 行を表示すること」
などと書いていただければもっと早く理解できたと思われます。

で、スクリプトは以下のような感じでしょうか。

#!/usr/bin/ksh
INDEX=0
ls -l |
while read LINE; do
    CMD[$INDEX]="$LINE"
    TEST="$TEST ${INDEX}:$LINE"
    let "INDEX = INDEX + 1"
done
echo "$TEST"
INDEX=0
while [ $INDEX -lt 5 ]; do
    echo "${INDEX}:"${CMD[$INDEX]}
    let "INDEX = INDEX + 1"
done

Prev< No. 3643〜3648> Next  [最新発言に戻る] [過去ログ一覧]