IF テストでパス比較パラメータが多すぎます。

IF テストでパス比較パラメータが多すぎます。

次がtrueを返す必要がある場合は、実際に失敗し、bashシェルで実行されたときに引数が多すぎるというエラーが報告されます。私の考えは二重引用符を含むすべての指示に従いましたが、なぜそれが私の人生で失敗するのかわかりません...どのようなアイデアがありますか?

#!/usr/bin/bash
# These are the values in the environment
#echo ">"$PS_APP_HOME"<"  => >/app/psoft/app_85909<
#echo ">"PS_CUST_HOME"<"  => >/app/psoft/cust_85909<
#echo ">"$(pwd)"<"        => >/app/psoft/app_85909<

if [ "$(pwd)" != "$PS_APP_HOME" ] -o [ "$(pwd)" != "$PS_CUST_HOME" ]

答え1

[ "$(pwd)" != "$PS_APP_HOME" ] -o [ "$(pwd)" != "$PS_CUST_HOME" ]

[次のパラメーターを使用してコマンドを呼び出します。

  1. 出力pwd1、
  2. !=
  3. 変数の内容PS_APP_HOME
  4. ]
  5. -o
  6. [
  7. pwd他の呼び出しの出力
  8. !=
  9. 変数の内容PS_CUST_HOME
  10. ]

]最後のパラメータである必要があるため、最初のパラメータを見ると[混乱します。-o]

[-o廃止予定の演算子があります。またはしかし、これはとして使用するためのものです[ some-condition -o some-other-condition ]。ただし、信頼できないテスト式になる可能性があるため、使用しないでください。

ここではまたはそれも言えません。現在の作業ディレクトリは何か($PS_APP_HOME)とは異なるもの()にすることができないため、その$PS_CUSTOM_HOMEうちの少なくとも1つはtrueです。おそらくあなたが言うと思います。"$(pwd)" != "$PS_APP_HOME""$(pwd)" != "$PS_CUST_HOME"そして変えるまたは。だから:

  • 標準構文を使用してください。

    if [ "$PWD" != "$PS_APP_HOME" ] && [ "$PWD" != "$PS_CUST_HOME" ]; then
      echo current directory is neither the APP nor CUST home
    fi
    

    [(最初のコマンドが成功すると、2番目のコマンドを実行します。&& シェル[オペレータではありません)。

  • Kornに似た構文:

    if [[ $PWD != "$PS_APP_HOME" && $PWD != "$PS_CUST_HOME" ]]; then
      echo current directory is neither the APP nor CUST home
    fi
    

    または

    if [[ ! ($PWD = "$PS_APP_HOME" || $PWD = "$PS_CUST_HOME") ]]; then
      echo current directory is neither the APP nor CUST home
    fi
    

    [[...]]それ自体で特別な構造を持っているのです。条件式マイクロ言語コードには、&&(and)/ ||(or)、!(not)ブール演算子もあります。

以下を使用することもできますがcase

case $PWD in
  ("$PS_APP_HOME" | "$PS_CUST_HOME") ;;
  (*) echo current directory is neither the APP nor CUST home
esac

$PWD似ています$(pwd)が、他のプロセスをフォークしてその出力をパイピングする必要はなく、現在の作業ディレクトリへのパスが改行文字で終わっても動作しないことを除いて、より効率的です。 ²

上記の二重引用符は重要なので、必ず必要な場所にのみ入れました(設定された/演算子の引数で分割+グローブを防ぎ、[変数の値がパターンや引数で処理されるのを防ぐため)。!==[[...]]caseみんな引用された拡張は害を与えません。

語彙比較を実行することに加えて、ksh / bash / zsh[[....]]とほとんどの[実装([組み込みbashサポート演算子を含む)-efは、2つのファイルが同じであることを確認します(シンボリックチェック後)=

if [[ ! (. -ef $PS_APP_HOME || . -ef $PS_CUST_HOME) ]]; then
  echo current directory is neither the APP nor CUST home
fi

またはsh(ほとんどsh)の場合:

if [ ! . -ef "$PS_APP_HOME" ] && [ ! . -ef "$PS_CUST_HOME" ]; then
  echo current directory is neither the APP nor CUST home
fi

また、ここでは現在の作業ディレクトリを.参照または参照することが$PWD保証されます。$(pwd)

そのようにして、$PWDそれが/opt/appまたは/some/link/to/appであるか、またはそれ$PS_APP_HOME/opt/./appあれば、それはまだ有効です。/opt/foo/../app/opt//app


¹末尾の改行を削除するため、現在の作業ディレクトリではない可能性があります。

²一部のシェルでは、$PWD現在の作業ディレクトリの名前が変更された場合に古い情報が提供される場合があります。しかし、これはいくつかのシェルでも同じです。 //pwd値を出力し$PWDて更新のみします。cdpushdpopd

答え2

if [ "$(pwd)" != "$PS_APP_HOME" ] -o [ "$(pwd)" != "$PS_CUST_HOME" ]

これは構文上正しくないため、報告されたエラーが発生します。

これをテストとして実行するには、次の手順を実行します。

if [ "$(pwd)" != "$PS_APP_HOME" -o "$(pwd)" != "$PS_CUST_HOME" ]

あるいは、式を完全に分離してbash論理ORを処理したい場合:

if [ "$(pwd)" != "$PS_APP_HOME" ] || [ "$(pwd)" != "$PS_CUST_HOME" ]

関連情報