web-dev-qa-db-ja.com

引数付きのbashの問題

#!/bin/bash

dir=/home/john

name="kate"

if [ -d $dir ] && [ -n $name ]; then

    echo "The name exists and the folder $dir exists."

else

    echo "Fail"

fi

このコマンドを実行しただけで、まったく機能しませんでした。このコマンドは、両方のテストが成功した場合にのみtrueを返し、失敗した場合は失敗します。しかし、何も失敗しません。

どうして?

前もって感謝します。

3
J. Doe

これも試してみましょう。既存の答えは正しいですが、これはBashの質問なので、Bashismの使用を提案できますか?

#!/usr/bin/env bash

# Using $HOME so it should exist whenever someone tests this code
# btw: dir is not the best name here ... (shadows /bin/dir from coreutils)
dir=$HOME
name="kate"

if [[ -d $dir ]] && [[ -n $name ]]; then
    echo "The name exists and the folder $dir exists."
else
    echo "Fail"
fi

インライン解説をご覧いただけます。余分な空行も削除しました。

重要な点は、私が[[の代わりに[を使用していることです(および対応する]]の代わりに]を使用しています)。

参考のために、help [およびhelp [[の出力を参照することをお勧めします。つまり、[[は、正規表現のサポートも提供する拡張バージョンであり、他の多くのケースでよりスマートです。プレーンPOSIXシェルとの互換性を放棄することが許可されている場合は常に、[ expression ]の代わりにそれを使用することを習慣にしました。

これが正しく「バグ」(欠陥)と呼ばれるかどうかはわかりません。これはおそらく下位互換性によるものだと思います。しかし、想定される「バギー」動作が実際にPOSIX標準などで成文化されているかどうかは、100%確実ではありません。


さらなるポイントとして:

  1. ユーザーが存在するかどうかを確認する場合は、idまたはgetent passwd(使用可能で、必要に応じてより適切な方)を使用する必要があります。あなたcouldeval echo ~$nameを使用します($nameにユーザー名が含まれている場合)。いいえ、これは間違いではありません。 ~usernameは、そのユーザーのホームディレクトリに展開されますが、eval(またはプロンプトのタブ補完)を使用する場合のみです。
  2. ホームディレクトリなどの前提条件をハードコーディングするのではなく、getent passwdの出力に基づいて、特定のユーザー(名前)に関する調査結果をベースにすることをお勧めしますought/homeに含まれる...

しかし、それはちょうど私の2つの追加セントです...;)

2
0xC0000022L