-PR-
  • 困ってます
  • 質問No.5692688
解決
済み

Bourne Shell と POSIX について

  • 閲覧数1440
  • ありがとう数19
  • 気になる数0
  • 回答数4
  • コメント数0

お礼率 66% (111/166)

現在、会社でLinux 上でバッチプログラムを何本か作成しています。
その中で、規約に「シェルはB シェルとし、冒頭には /bin/sh と
すること」というようなことが書かれていました。

これは互換性を意識してのことだと解釈し、拡張表現を使用しないことを
意識して書いていました。

具体的には、export VAR=VALUE みたいな書き方はせずに、
VAR=VALUE; export VAR みたいにするとか。

ところが、Solaris を触る機会があって、そのプログラムを
動かしてみると正しく動きませんでした。

その原因は、関数内でローカル変数を宣言するために local を
使っていたのですが、それが Solaris の /usr/bin/sh が
解釈してくれないためでした。

そこで、以下の疑問点が上がってきましたので、
可能な箇所だけでも回答をお願いできたらと思っています。

1. Solaris の /usr/bin/sh は POSIX に準拠しているのでしょうか?

2. 互換性を意識するのであれば local は使用しない方がよいという
結論だと思っています。それでは、local を使用せずにローカル変数を
使用したい場合や再帰処理を行いたい場合はどのような方法を使うのが
一般的なのでしょうか? それとも、拡張機能無しにそのようなことは
できないと考えるべきなのでしょうか?

3. そもそも、POSIX でシェルに求められる必要条件とはどのようなこと
があるのでしょうか?(どのようなことが規定されているか。
Google検索で見つけられなかったので、原文がWeb 公開されているので
あればURL 指定でも・・・)
通報する
  • 回答数4

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

  • 回答No.1
レベル14

ベストアンサー率 45% (1080/2394)

えー、原文でよいということですのでSingle UNIX Specificationを紹介しておきます。
これのShell & Utilities以下にシェルその他の規定があります。
お礼コメント
entree

お礼率 66% (111/166)

回答ありがとうございます。
教えていただいた文書確認しました。

POSIX Shell が意外に高機能で驚きました。
具体的には、$( ) $(( )) alias、・・・
ただ、肝心の「local」については
互換性や別シェルにすることで
問題が回避できるなどの理由により、
は定義されなかったようですね。

現時点では関数部分を別シェルに切り出し、
グローバル変数を export するか、
local が使えないシェルで起動された場合は
local が使えるシェルに exec で切り替える
ことを考えています。
投稿日時 - 2010-02-21 13:28:55
-PR-
-PR-

その他の回答 (全3件)

  • 回答No.4
レベル14

ベストアンサー率 49% (4109/8313)

#2です。さっき投稿してから、スタックの実装を思いつきました。ただし、空白などシェルの特殊記号は値に持たないという前提。位置パラメータを使います。 localで書いた例: foo(){ test $1 = 0 && return local x x=$1 x=`expr $x - 1` foo $x echo $x } foo 10 lo ...続きを読む
#2です。さっき投稿してから、スタックの実装を思いつきました。ただし、空白などシェルの特殊記号は値に持たないという前提。位置パラメータを使います。

localで書いた例:
foo(){
test $1 = 0 && return
local x
x=$1
x=`expr $x - 1`
foo $x
echo $x
}
foo 10

localを使わず書き直した例:
foo(){
test $1 = 0 && return
x=$1
x=`expr $x - 1`
set $x $stack
stack="$*"
foo $x
set $stack
x=$1
shift
stack="$*"
echo $x
}
foo 10
お礼コメント
entree

お礼率 66% (111/166)

実装例を記述していただいてありがとうございます。

# 空白などシェルの特殊記号は値に持たないという前提

とのことですが、その前提が当てはまらないとなれば
さらに複雑化しそうですね。(笑)

おまけに、関数の数は共通部分だけで軽く10個以上あり、
互いに呼び出しあっているので、複雑な実装にしてしまうと
パフォーマンスが問題になってきそうです。
投稿日時 - 2010-02-21 13:58:16
  • 回答No.3
レベル14

ベストアンサー率 49% (4109/8313)

関数の再帰呼び出しの場合ですよね。 再帰呼び出しを行う関数のローカル変数がどうしても必要と言うことであれば(それ以前に、無くて済む処理方法は無いかの検討が必要でしょうけど)、 関数を独立したシェルスクリプトファイルにして、シェルスクリプトの再帰呼び出しに書き換えるくらいですかね。 あとは、スタックをシェル変数上に作る方法も考えられます。その場合、スタックからの取り出しに、sedとかexprを複数回使うこ ...続きを読む
関数の再帰呼び出しの場合ですよね。
再帰呼び出しを行う関数のローカル変数がどうしても必要と言うことであれば(それ以前に、無くて済む処理方法は無いかの検討が必要でしょうけど)、
関数を独立したシェルスクリプトファイルにして、シェルスクリプトの再帰呼び出しに書き換えるくらいですかね。

あとは、スタックをシェル変数上に作る方法も考えられます。その場合、スタックからの取り出しに、sedとかexprを複数回使うことになるので、シェルスクリプト再帰の方が実用的かと。
お礼コメント
entree

お礼率 66% (111/166)

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

別シェルにするという発想は投稿をした後に
思いつきました。さらに、POSIX に local が
含まれなかった背景を記述した文書も確認できました。

現時点では指摘いただいたように、
関数部分を別シェルに切り出して
グローバル変数を export するか、
local が使えないシェルで起動された場合は
local が使えるシェルに exec で切り替える
ことを考えています。
投稿日時 - 2010-02-21 13:35:15
  • 回答No.2
レベル10

ベストアンサー率 87% (87/100)

Solaris で POSIX に準拠している sh は /usr/xpg4/bin/sh になります。 shell のポータビリティについては、GNU Autoconf info マニュアルの "Portable Shell Programming" が参考になると思います。 http://www.gnu.org/software/autoconf/manual/auto ...続きを読む
Solaris で POSIX に準拠している sh は /usr/xpg4/bin/sh になります。

shell のポータビリティについては、GNU Autoconf info マニュアルの "Portable Shell Programming" が参考になると思います。

http://www.gnu.org/software/autoconf/manual/autoconf.html#Portable-Shell
お礼コメント
entree

お礼率 66% (111/166)

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

ご指摘いただいていた文書は事前に確認していて、
/usr/xpg4/bin/shが POSIX に準拠していることまでは
確認できていたのですが、/usr/bin/sh が POSIX に
準拠していないという記述までは確認できなかったので、
ここで質問するに至りました。

現時点では関数部分を別シェルに切り出し、
グローバル変数を export するか、
local が使えないシェルで起動された場合は
local が使えるシェルに exec で切り替える
ことを考えています。
投稿日時 - 2010-02-21 13:31:18
  • 回答数4
このQ&Aのテーマ
このQ&Aで解決しましたか?

関連するQ&A

-PR-
-PR-
このQ&Aにこう思った!同じようなことあった!感想や体験を書こう
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ