checkbashisms: "type"に何の問題がありますか?

checkbashisms: "type"に何の問題がありますか?
#!/bin/sh

foo() {
   echo "in foo"
}

type foo

checkbashisms.plきっと嫌いなのにtypeなぜ?

$ checkbashisms.pl foo.sh
possible bashism in foo.sh line 7(type):
type foo

POSIXではありませんか?ただし、すべての汎用シェルはこれをサポートしています(例:、、、、bash;でも;サポートしていない可能性があります)。この警告を抑制する方法はありませんか?zshdashbusybox shmkshkshcsh

答え1

typeはいPOSIXの一部ただし、X / Open Systems Interface Option(XSI)の一部です。マニュアルcheckbashismsページ明示的に

この文脈では、bashism の定義は「POSIX サポートを必要としないシェル機能」とほぼ同じです。これは、POSIXのオプションの部分(XSIやユーザーの移植性など)がいくつかの問題を受け入れることができることを意味します。

typeオプションの機能なので表示されます。

checkbashismsスクリプトから特定の警告を削除する以外に、で特定の警告を無効にする方法がわかりません。

答え2

検討command -v fooまたはcommand -V foo交換してくださいtype foo。より安定して組み込まれる可能性が高いと聞きました。

$PATH実行可能ファイル、組み込み機能、関数、エイリアスについてテストしましょう。

#!/bin/sh

foo() {
   echo "in foo"
}
alias bar=foo

for cmd in sed command foo bar; do
  type "$cmd"
  command -V "$cmd"
  command -v "$cmd"
done

出力(使用スプリント0.5.11):

sed is /usr/bin/sed
sed is a tracked alias for /usr/bin/sed
/usr/bin/sed
command is a shell builtin
command is a shell builtin
command
foo is a shell function
foo is a shell function
foo
bar is an alias for foo
bar is an alias for foo
alias bar='foo'

(注:sedエイリアスではありません!多分これはダッシュを意味するかもしれません。ハッシュコマンド位置テーブル? )

Bashで実行すると、Bashが非対話型スクリプトでエイリアスを有効にしないtypeため、エラーが発生します。command -VBashはまた、与えられた複数行に完全な関数定義を表示します。command -Vこれは解析するのが本当に難しいです。

POSIX定義されたcommandオプションように:

-pPATHのデフォルト値を使用してコマンド検索が実行されるため、すべての標準ユーティリティを見つけることができます。

-vシェルが現在のシェルの実行環境で使用するパス名またはコマンドを表す文字列を標準出力に書き込みます。シェル実行環境)、command_nameを呼び出しますが、command_nameは呼び出しません。

  • ユーティリティ、汎用組み込みユーティリティ、文字を含むcommand_names、およびPATH変数を使用して見つかった実装定義関数(例:命令の検索と実行)は絶対パス名で作成する必要があります。
  • シェル機能、特別な組み込みユーティリティ、PATH検索に関連しない一般的な組み込みユーティリティ、シェル予約語などは、名前の通り簡単に作成する必要があります。
  • エイリアスは、エイリアス定義を表すコマンドラインで作成する必要があります。
  • それ以外の場合、出力は作成されず、終了ステータスに名前が見つからないことを反映する必要があります。

-V現在のシェル実行環境で command_name オペランドに指定された名前を解釈する方法をシェルに指示する文字列を標準出力に書き込みます。シェル実行環境)、しかしcommand_nameは呼び出されません。この文字列の形式は指定されていませんが、次のカテゴリのうちcommand_nameが属するカテゴリを表し、説明されている情報を含める必要があります。

  • ユーティリティ、汎用組み込みユーティリティ、PATH変数を使用して見つかった実装定義関数(例:命令の検索と実行)として識別し、文字列に絶対パス名を含める必要があります。
  • 他のシェル機能は機能として識別する必要があります。
  • エイリアスはエイリアスとして識別し、その定義を文字列に含める必要があります。
  • 特別な組み込みユーティリティは特別な組み込みユーティリティとして識別する必要があります。
  • PATH検索に関連しない一般的な組み込みユーティリティーは、一般的な組み込みユーティリティーとして識別する必要があります。 (「正規」という用語を使用する必要はありません。)
  • シェル予約語は予約語として表示する必要があります。

シェルスクリプトを作成するときに定義された出力がある3つのうち唯一のものなので、orのcommand -v代わりに使用することをお勧めします。その後、ほとんどのスクリプトは、コマンドが存在するかどうかを確認すると、出力を完全に無視する自動ヘルパー関数を介してそれを呼び出します。typecommand -V

we_have() { command -v "$1" >/dev/null 2>&1; }

if we_have obscure-command; then
  osbcure-command …
fi

答え3

このコマンドは1984年以降は含まれていtypeません。bashismUNIX

ただし、基本的な互換性のみを提供する小規模な組み込みプラットフォームを使用している場合は、このtypeコマンドが存在しない可能性があります。POSIX

独自に -platform を呼び出すプラットフォームを使用している場合、サポートするには -platform が必要なので、UNIXこのtypeコマンドは必須です。UNIXみんなXSI規格に記載されているいわゆる改善POSIX

小規模の組み込みシステムでもサポートする必要がある準類似のコマンドを探している場合は、次のことをお勧めします。

command -V foo

代わりに。大文字の-Vオプションはcommand類似しているが必ずしも同じではない出力を印刷しますtype

また、注:標準はcommand -Vfromまたはfromの出力形式を定義しません。typePOSIX

関連情報