• ベストアンサー

シェルスクリプトの変数の制限?

こんにちは。 シェルスクリプトで謎の現象が起こりまして悩んでいます。 現在、 #!/usr/bin/sh var='foo' if [ $? - eq - 0 ]; then mv xxx.bz2 xxx.old.bz2 echo $var | bzip2 -z >xxx.bz2 fi といった感じのシェルスクリプトを動かしています。 これを手作業で、 foo | bzip2 -z >xxx.tmp.bz2 とやると、xxx.tmp.bz2は1.2MB程度のファイルとなるのですが、 上記のシェルスクリプトで実行すると8KBほどにしかなりません。 シェルスクリプトの変数のサイズの制限かと思い、調べてみましたが、 特に制限があるとの資料はみつかりませんでした。 fooの出力がバイナリなので、そのせいかとも思ったのですが、unix系列の場合、windowsと違ってテキスト/バイナリの区別はないはずだしということで、理由がわかりません。 シェルの変数には、やはり制限があるのでしょうか?それとも他の理由でしょうか。ご存知の方がいらっしゃいましたら、ご教示お願いします。 環境はsolarisです。バージョンは、 $ cat /etc/release Solaris 10 8/07 s10s_u4wos_12b SPARC Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms. Assembled 16 August 2007 です。よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4903/10364)
回答No.4

変数と言うより、シェルのコマンドライン長の制約の気がします。 圧縮して1.2MBということはfooの出力は数十~数百MB? 外部コマンド起動の場合は、Linuxだと128KBが上限のようですが、echoは組み込みコマンドなので、もっと上限は大きいはずです。 変数に200MBいれてみると、入りましたけど、echoしてみるとbashが落ちました。SolarisだとOSが違うので、上限も異なると思いますが。 やはり変数に入れない方がいいでしょうね。 foo | bzip2 -z >xxx.tmp.bz2 ただ、ステータスを調べるのは面倒。パイプのステータスはパイプの最終段のコマンドつまりbzip2のステータスになります。 bashだと、${PIPESTATUS[0]} でfooのステータスが取れるのですが、shだとちょっと細工が要ります。 status=`((foo ; echo $? >&3) | bzip2 -z >xxx.tmp.bz2) 3>&1` if [ $status = 0 ] then mv xxx.bz2 xxx.old.bz2; mv xxx.tmp.bz2 xxx.bz2 else rm xxx.tmp.bz2 fi

titokani
質問者

お礼

なるほど、ありがとうございます。 どうやら変数に入れないほうがいいのは確かなようですね。 >ただ、ステータスを調べるのは面倒。パイプのステータスはパイプの最終段のコマンドつまりbzip2のステータスになります。 はい、ステータスを調べる必要があるので・・。必要なければ素直に foo | bzip2 -z >xxx.tmp.bz2 で、よかったのですが。 >status=`((foo ; echo $? >&3) | bzip2 -z >xxx.tmp.bz2) 3>&1` >if [ $status = 0 ] >then mv xxx.bz2 xxx.old.bz2; mv xxx.tmp.bz2 xxx.bz2 >else rm xxx.tmp.bz2 >fi 参考になります。試してみます。

titokani
質問者

補足

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

すると、全ての回答が全文表示されます。

その他の回答 (3)

回答No.3

んー。fooの出力結果をbz2で保存したいというのが目的でよいのかな? Solaris は、時々コマンドが微妙に違っていたりするのであまり自信ないですけど シェルでは、基本的にクォーティングする癖をつけた方がよいですよ。 #!/usr/bin/sh var="$(foo)" if [ $? -eq 0 ]; then mv xxx.bz2 xxx.old.bz2 echo "$var" | bzip2 -zc >xxx.bz2 || echo error fi としてみたら、どんなです? もしうまくいったとしたら、$varに0x0dが混ざっていたのでしょう。

titokani
質問者

お礼

お返事ありがとうございます。 テストコードを書いてみました。 $ cat test.sh #!/usr/bin/sh var0="\0015" var=12345${var0}A echo $var echo "$var" $ test.sh A2345 A2345 と、なりましたので、どうやら改行が原因ではないようです。 他、 var0="\0042" としても試してみましたが、結果、 12345"A 12345"A と、なりましたので、バイナリであることはおそらく問題がないのかなと思います。 いずれにせよ、あまり大きなデータを変数に入れるのは問題があるようなので、変数に入れない方向で考えてみます。

すると、全ての回答が全文表示されます。
  • OKwebb
  • ベストアンサー率44% (92/208)
回答No.2

echo は文字列しか処理できないんじゃない? シェルにも echo $var | bzip2 -z >xxx.bz2 じゃなくて foo | bzip2 -z >xxx.tmp.bz2 って書けばどう?

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

この場合 echo $var = echo foo だから, 「コマンド foo の出力を bzip2 で圧縮する」んじゃなくて「文字列 foo を bzip2 で圧縮してる」んだよ.

titokani
質問者

お礼

重ねてすみません。 間違えたというのは、転記ミスということです。 うまく動かないスクリプトに書いてあるのは、 var=`foo` です。

titokani
質問者

補足

すみません、間違えました。 var='foo' じゃなくて、 var=`foo` でした。申し訳ないです。

すると、全ての回答が全文表示されます。

関連するQ&A