移植可能なシェルプログラミングに使用できるリソースは何ですか?最終的な答えは、すべてのターゲットプラットフォームでテストすることですが、これはほとんど実用的ではありません。
これPOSIX/シングルUNIX仕様それは始まりですが、各実装のサポートレベルや一般的な拡張が何であるかを教えてくれません。各実装のドキュメントを読むことができますが、時間がかかり、完全に正確ではありません。
私の考えでは、理想的な形式は、一種のコミュニティ注釈付きのPOSIX仕様バージョンになります。ここで、各機能は、様々な実装におけるサポートレベルに応じてコメントを追加する。そんなことありますか?それとも他の有用なリソースがありますか?
例えば、Sven Mascheckのシェル移植性ページただし、構文要素と一部の組み込み関数のみが含まれ、古いシェルのみを扱います。私はより包括的な資料を探しています。
答え1
autoconf マニュアルには次のセクションがあります。 ポータブルシェルプログラミング。
ただし、これはPOSIXに固有のものではありませんが、おそらく移植可能なシェルコードを書こうとするときにやるべきことと、やるべきことの最も完全なコレクションです。
答え2
答え3
答え4
今日では、通常はシステム上の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シェルで実行される完全なスクリプトの作成を始めることです。これは、実際に他のシェルがないシステム用のコードを書く必要がある場合にのみ必要です。