web-dev-qa-db-ja.com

移植可能なシェルプログラミングのリソース

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

POSIX /単一UNIX仕様 は始まりですが、各実装のサポートレベルや、一般的な拡張機能については説明していません。各実装のドキュメントを読むことができますが、これは非常に時間がかかり、完全に正確ではありません。

理想的なフォーマットは、POSIX仕様のコミュニティアノテーション付きバージョンのようなものであり、さまざまな実装間のサポートレベルによって各機能がアノテーションされているように思えます。そんなことありますか?または、他に役立つリソースはありますか?

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

Autoconfマニュアルには ポータブルシェルプログラミング に関するセクションがあります。

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

32
Riccardo Murri

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

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

5
Philomath

ダッシュ を使用してスクリプトを作成することから始めます。

4
glenn jackman

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

完璧ではありませんが、既存の出発点であるという利点があります。たとえば、GNU vs BSD /その他の違いに関するsed/findの古典的なグリッチは表示されません。

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

2
shellholic

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

唯一の問題は、/bin/shがPOSIXシェルではない場合があることです。そして、#!行を、Nice実行可能ファイルとして動作するスクリプトにハードコードする必要があります。ユーザーに問題を調査してから/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.

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

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

2
Kaz