cshでの配列の使用方法について

シェルの中で複数の入力値のエラーチェックを行う場合に、エラーを発見する度にエラーメッセージを表示するようなスクリプトを書くとソースが読み辛くなってしまいます。そこで、エラーの内容を配列に持たせて、後でまとめて表示させようと思い、cshでの配列の使い方について調べてみました。変数を定義する際、括弧内に半角スペース区切りで値を設定すると配列になります。

set test = (a b c)

なるほど、なるほど。では、配列に項目を増やしていくにはどうすれば良いんだろう、と思って調べていたのですが、手元にある資料には配列の値を減らすshiftについての説明しかありません。ネットで調べてみてもなかなか良いものが見つかりません…。そんなことを隣の席の先輩社員に聞いたところ、以下のURLを見つけてくれました。

http://www.not-enough.org/abe/manual/unix2/howto-csh-array.html

ここの説明を読むと、配列の内容を全部出力したものに新しい値を追加する、という力技が載っていました。やっぱりこれしかないのかしら。

set test = ($test d)

この内容を参考にして、配列に値を足した後、最後に1行ずつ表示させるシェルを書いてみました。cshでは配列は0ではなく1から始まるので要注意です。

array_test.sh

#! /usr/bin/csh

set test = (a b c)
echo $test
# echo $test[*] としても同じ結果が得られる

# 配列に値を追加
set test = ($test d)
echo $test

# 配列の値を一行ずつ出力

set i = $#test
set j = 1

echo "--------------------"
while ( $j <= $i )
  echo $test[$j]
  @ j++
end
echo "--------------------"

出力結果は以下のようになります。

a b c
a b c d
--------------------
a
b
c
d
--------------------

よしよし、これでエラーチェック後のエラー表示もまとめて上手いことできますなぁ、と油断したのが間違いでした…。

array_test2.sh

#! /usr/bin/csh

set test = ('ERROR NO.1' 'ERROR NO.2')
echo $test
echo $#test

# 配列に値を追加

set test = ($test 'ERROR NO.3')
echo $test

# 配列の値を一行ずつ出力

set i = $#test
echo $i
set j = 1

echo "--------------------"
while ( $j <= $i )
  echo $test[$j]
  @ j++
end
echo "--------------------"

実際に配列に入れたい内容はエラーメッセージなので、それっぽい例で試してみようと思い、上記のシェルを作ってみました。その出力結果に問題があったのです。

ERROR NO.1 ERROR NO.2
2
ERROR NO.1 ERROR NO.2 ERROR NO.3
5
--------------------
ERROR
NO.1
ERROR
NO.2
ERROR NO.3
--------------------

2つ値を持った配列に1つ項目を追加しただけなのに配列の数が5つになってます…。(出力結果の4行目をご覧ください。)3つ目の値を追加する際、元々の配列にあったシングルクォートが無視されてしまっているのです。(ダブルクォートでも試してみましたが、同じ動作でした。)echoでの出力を見てもクォートはありません。こんな罠が潜んでいるとは…。出力結果の1行目からも分かる通り、配列自体はスペースを含んでいたとしてもクォートで区切られている内容を1つの値として扱えます。配列に値を追加するコマンドがないのが悔やまれます…。
エラーメッセージをまとめて出力したいのであれば、配列に持たせるのはエラーコードだけにしておいて、エラー情報DB(あるいはエラー情報管理ファイル)を参照してエラーメッセージを出力するような処理にした方が良さそうですね。awkあたりを使って無理やりクォート付きの値を配列に追加することも可能だと思いますが、あまり格好良くないので却下。