shまたはashのbash条件文を再構築するときに何を確認する必要がありますか?

shまたはashのbash条件文を再構築するときに何を確認する必要がありますか?

時には、システムでbashの高度な機能を使用することはできませんが、shまたはashよりもbashから条件を生成する方が簡単です。条件が一般的な「予期しない演算子」で中断されないように、再構築時に何を確認する必要がありますか? shまたはashでbash?

答え1

私は、標準やコマンドよりも((...))andを使用して条件文を定式化する方が簡単であることに同意しません。そしての問題よりはるかに深刻ないくつかの問題があります。[[...]][test[[ ... ]](( ... ))[

[失敗した場合予期しないオペレータエラーです。現在使っていないようです。シェルコマンドの代わりに正しく(通常は拡張子を引用することを忘れます[

正しく、持ち運びに便利な使い方は[/testを参考にするのが最善です。POSIX仕様

安全を確保するためのいくつかの基本的な規則は次のとおりです。

  • 引数からすべての単語拡張($var、、、)を引用します$(cmd)$((arithmetic))これは。[dash[[ ... ]](( ... ))

  • [その他の引数を4つ以上渡さないでください]。つまり、廃止された-oand演算子を使用せず、グループ化にorを-a使用しないでください。したがって、一般的に表現は次のようになります。()[

    • の単一パラメータです。しかし、私はnullでないことを確認していることを明示的にするバリアントを[ "$string" ]使用することを好みます。[ -n "$string" ]$string
    • 単項演算子(-f、、、...)と対応するオペランドは、オプションで否定のために-r前に来ることができます。-n!
    • 二項演算子(=、、-gt...)と対応するオペランド2つ(前にはオプション)!
    • 算術演算子のオペランドは、オプションの符号付き10進整数定数でなければなりません。 、これらのオペランドで先行および末尾のスペースを許可するdashのと同じですが、すべての実装がこれを行うわけではありません。bash[

ポータブル演算子のリストについては、POSIX標準を確認してください。標準にはいくつかの拡張もdashあります(-nt、、、、、、、…)。-ef-k-O<>

パターンマッチングのために代わりにcaseコンストラクタ()を使用してください。case $var in ($pattern)...if [[ $var = $pattern ]]...

拡張正規表現一致の場合は、次のものを使用できますawk

ere_match() { awk -- 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' "$1" "$2"; }
if ere_match "$string" "$regex"...

変える:

if [[ $string =~ $regex ]]...

AND / ORの場合は、ORシェル演算子(優先順位が同じ)を使用して複数の[呼び出しを連結し、コマンドグループを使用して別のコマンド(単に。&&||[

if
  [ "$mode" = "$mode1" ] || {
    [ -f "$file" ] && [ -r "$file" ]
  }
then...

変える:

if [[ $mode = "$mode1" || ( -f $file && -r $file ) ]]; then...

いくつかのbash's/ dash's/ zsh's/ ksh's/ yash's test/ 非 POSIX 演算子[の標準同等物:

  • -a file

答え2

スティーブン・チャジェラス厳密には、POSIX互換シェルと他のシェルの間の構文の違いと他のトラップを指摘する良い答えがあります。この答えは別のアプローチをとります。

bash人間として、またはPOSIX以外の拡張を含む他のシェル用にksh作成されたスクリプトをPOSIX構文のみを使用するスクリプトに安全に変換することは非常に困難です。誤って何かを見逃しやすく、スクリプトが失敗する可能性があります。あまり良くない時期ですね。

私がしばらく使ってきた素晴らしいオープンソースツールがあります。住宅検査。 shellcheckの役割は、シェルスクリプトのリンターとして機能することです。同様のshebangを指定する#!/usr/bin/env shか、この--shell shオプションを使用すると、shellcheckは指定されたシェルに無効な構文を自動的に警告します。

Shellcheckには、それぞれのリンティングエラーまたは警告がそれぞれのページに文書化されている非常に良いwikiがあります。

shellcheckをインストールすることを選択した場合は、以下から最新の安定版をインストールすることをお勧めします。GitHubのリリースページ私の経験によると、パッケージマネージャは以前のバージョンのシェルチェックを持っているので、パッケージマネージャを使用する代わりに。

答え3

避けるべき最も重要なことはと言いたいです[[ ... ]]。 2つの間の算術(( ... ))もおそらく機能しません。

変数が設定されていない場合にエラーを回避するには、変数を引用符で囲む習慣を持ちます"$var"

-eqすべての算術演算子または論理演算子は、orではなく-aor=などのダッシュを持つ単語です&&

また使用shellcheck.net文法検査に使用されます。#!/bin/shBourneシェルではありませんが、POSIXシェルを使用したいとshellcheckに通知してください。 Bourneシェルスクリプトをテストする方法も必要です。

関連情報