ポータブルシェルプログラミングのリソース


65

ポータブルシェルプログラミングにはどのようなリソースがありますか?最終的な答えは、対象となるすべてのプラットフォームでテストすることですが、それはほとんど実用的ではありません。

POSIX /シングルUNIXの仕様が開始され、それはあなたが何を各実装のサポートのレベルがあり、また一般的なものを拡張存在でもないように指示します。各実装のドキュメントを読むことができますが、それは非常に時間がかかり、完全に正確ではありません。

理想的なフォーマットは、POSIX仕様のある種のコミュニティ注釈付きバージョンであり、各機能は異なる実装間のサポートレベルによって注釈付けされているように思われます。そのようなことはありますか?または、他の有用なリソースがありますか?

たとえば、Sven Mascheckのシェルポータビリティページがありますが、構文要素といくつかのビルトインについてのみであり、古いシェルのみをカバーしています。より包括的なリソースを探しています。


2
NB特定の実装の適合性文書を引用するためだけにここで答えないでください。これらのいずれかをお持ちの場合、対応するタグwikiが適しています。
ジル 'SO-悪であるのをやめる'

1
誰かがautoconfand Metaconfig(Perl、rn)の改訂履歴をマイニングし、すべてのトリックとその説明コメントを1か所で収集する必要があります。
ギコサウルス

@geekosaur:良い提案。autoconfの内部を一度も見たことがありませんが、自分のスクリプトを書く際にガイドとして使用できるものはありますか?もしそうなら、これは決定的なものではないにしても、私の質問に対する良い答えになるでしょう。
ジル 'SO-悪であるのをやめる'

5
どちらも簡単に見つけることができると確信していますが、このスレッドをフォローしている他の人のために、autoconfマニュアルの関連ページへのリンクがあります:gnu.org/software/hello/manual/autoconf/Portable- Shell.html
J.テイラー

回答:


32

autoconfマニュアルには、移植可能なシェルプログラミングに関するセクションがあり ます

これは特にPOSIXを対象とするものではありませんが、おそらくポータブルシェルコードを記述しようとする場合に行うべきこととすべきでないことの最も完全なコレクションです。


3
これは最高のリソースの1つであり、可能な限り多くのシェル間で移植可能なシェルコードを生成する必要があるM4でコードを記述しながら構築されました。
ティムポスト

6

dashposhに加えて、バシズムの検出に使用できる家宝ボーンシェルbournesh(またはbsh)があります。

Heirloomプロジェクトには、「The Heirloom Toolchest」も含まれています。これは、100を超える標準のUnixユーティリティのコレクションです(コマンドラインオプションを比較するための出発点として使用できます)。


2
BourneシェルはPOSIXシェルではないため、スクリプトをBourneシェルに移植可能にすることは、スクリプトの構文を標準POSIX sh言語からBourneシェルの構文の共通分母にダウングレードすることを意味します。古代のシステム(またはSolaris 10以前に移植可能であり、/ usr / xpg4 / binにある標準のshを使用する選択肢がない場合)を除き、意見に値しません。
ステファンシャゼル

5

この答えと同様に、スクリプトをposhで実行してみてください。

また、POSIXLY_CORRECT環境変数をtrue に設定することを忘れないでください。これにより、多くのプログラム(シェルだけでなく)がより厳密にPOSIX標準に準拠するようになります。


4

ダッシュを使用してスクリプトを記述することは、開始点かもしれません。


3
例えばOpenBSDの(他のシェル(例えばzshのの貧しい人々トラップ処理)の不備を知ること、そしてシェルユーティリティで、上記のすべて:ダッシュとのテストはkshの/ bashの機能上の不慮の依存を回避するための必要最低限ですが、私はそれよりも後だよfindまだ実装されていません-exec +)。
ジル 'SO-悪であるのをやめる'

FWIW、OpenBSD find-exec utility {} +最近のことです。
クサラナナンダ

2

少し拡張するにはcheckbashisms、Debian / Ubuntuのdevscriptsパッケージで試すことができます。

完全ではありませんが、既存の出発点であるという利点があります。たとえば、GNUとBSD /その他の違いに関するsed/ の古典的な不具合は見られませんfind

デフォルトでは、Debian + dash指向であり、-pフラグはあなたの場合に役立ちます。


2

今日、通常はシステム上でPOSIXシェルを見つけることができるため、一般的にはPOSIX言語でスクリプトを作成できることを意味します(モジュロがコンプライアンスバグに遭遇する)。

唯一の問題は/bin/sh、POSIXシェルではない場合があることです。また、この#!行を、実行可能ファイルとして動作するスクリプトにハードコーディングする必要があります。ユーザーに問題を調査してからスクリプトを起動するように依頼することはできません/path/to/posix/shell myscript

そのため、スクリプトでPOSIX機能を使用し、スクリプトがPOSIXシェルを自動的に検出するようにするのがコツです。その方法の1つは次のとおりです。

#!/bin/sh

# At this point, we may be running under some old shell
# we have to tread carefully.

# note how we use test rather than [ ] syntax and avoid
# depending on test with no argument producing a failure;
# i.e. "test $posix_shell".

if ! test x$posix_shell = x ; then
  # the three possible shell paths are just an example;
  # please extend as necessary.

  for shell in /usr/xpg4/bin/sh /bin/bash /usr/bin/bash ; do
    if test -x $shell ; then
       posix_shell=$shell
    fi
  done
  if test x$posix_shell = x ; then
    echo "no POSIX shell found"
    exit 1
    # or we could avoid bailing here and just fall back on /bin/sh:
    # echo "falling back on /bin/sh: cross your fingers that it works"
    # posix_shell=/bin/sh
  fi
  export posix_shell

  # plain "$@" is broken in ancient shells! 
  # I seem to recall ${@+"$@"}: not sure if that's the right trick.

  exec $posix_shell $0 ${@+"$@"}  # can we count on exec in legacy shells? 
fi

# phew, at this point in the script we have been re-executed and are
# being interpreted by some reasonably modern shell. We can use $(...)
# command substitution, and other features.

コード生成など、他のアプローチもあります。#なしでスクリプトファイルの本体を取る小さなスクリプトでスクリプトをブーストラップします。行を追加します。

最悪の事態は、1981年からBourneシェルで実行されるようにスクリプト全体を書き始めることです。これは、他のシェルをまったく持たないシステム用に記述する必要がある場合にのみ必要です。 。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.