返された結果を確認する最善の方法は何ですか?

返された結果を確認する最善の方法は何ですか?

フォルダが存在することを確認するシェルスクリプトに関数が設定されています。そうでない場合は、フォルダを作成しようとし、フォルダを作成できない場合(たとえば、ユーザーに正しい権限がない場合)1を返し、それを確認します。 「return」ですが、returnが1なので、「if」が機能しない理由を理解できません。

パスワード:

#!/bin/bash
# Main folders
INPUT="input"
OUTPUT="output"

# Functions

function checkFolderExist(){
    if [ -d $1 ]
    then
        # 0 = true
        # Change to 0, only for tests.
        return 1
    else
        mkdir $1
        result=$?
        if [ result==0 ]
        then
            # 0 = true
            return 0
        else
            # 1 = false
            return 1
        fi
    fi
}


CHECKINPUT=$(checkFolderExist $INPUT)
echo $?
CHECKOUTPUT=$(checkFolderExist $OUTPUT)
echo $?

# If folders does not exist, exit the script
if [[ "$CHECKINPUT" = 1 || "$CHECKOUTPUT" = 1 ]]; then
    echo "[+] Error. Folder does not exist. Check user permissions."
    exit 1
fi

答え1

以下はいくつかの点です。

  • あなた珍しい$?同じ終了ステータスを複数回参照する必要がある場合を除き、すべての項目を明示的に確認するか、変数に保存する必要があります。
  • 関数の終了状態は、関数で実行された最後のコマンドの状態なので、明示的な終了はreturnほとんど必要ありません(明示的な戻りがある場合はほとんどありません)。少なくとも)。
  • ディレクトリが存在することを確認する関数は、ディレクトリを作成しないでください。より良い電話create_dir_if_needed
  • にエラーがあります[ result==0 ]。文字列はresult==0長さがゼロ以外の文字列です。この方法で文字列をテストすると返されます。本物文字列の長さがゼロでない場合、テストは常に真です。あなたが望むものはおそらくでしょう[ "$result" -eq 0 ]
  • どのような状況であるかわからない限り、変数の拡張とコマンドの置換には常に二重引用符を使用する必要があります。これは必須ではありません。

次の点を考慮してください。

create_dir_if_needed () {
    mkdir -p -- "$1"
}

これにより終了ステータスが返されますmkdir -p -- "$1"。このコマンドは、指定されたディレクトリ(および中間ディレクトリ)がまだ存在しない場合に生成します。mkdirコマンドがディレクトリの作成に失敗すると、ゼロ以外の終了状態で終了し、これは関数の終了状態になります。mkdir -pディレクトリがすでに存在する場合は失敗しません。

次のように使用できます。

if ! create_dir_if_needed "$dirpath"; then
    printf 'Failed to create directory "%s"\n' "$dirpath" >&2
    exit 1
fi

あるいは機能が簡単なので、取り除いて言ってもいいです。

if ! mkdir -p -- "$dirpath"; then
    printf 'Failed to create directory "%s"\n' "$dirpath" >&2
    exit 1
fi

この関数のバリアントは、指定されたディレクトリパスに対して欠落している親ディレクトリが作成されないようにするためになしをcreate_dir_if_needed使用します。mkdir-p

create_dir_if_needed () {
    if [ -d "$1" ]; then
        return
    fi

    mkdir -- "$1"
}

または、

create_dir_if_needed () {
    [ -d "$1" ] || mkdir -- "$1"
}

この関数を呼び出すと返されます。本物(ゼロ)ディレクトリがすでに存在するか、呼び出しがmkdir成功した場合。明示的な値を持たないステートメントは、return最後に実行されたステートメントの終了ステータスを返します。この場合、肯定的なテスト結果を返します[ -d "$1" ]

答え2

Bashは戻り値の一般的なプログラミング言語とは異なります。

ここで混乱します。出力checkFolderExistから返品ステータスcheckFolderExistから。

関数echoには何もないため、CHECKINPUT変数とCHECKOUTPUT変数は空ですprintf

本当に機能を保存したい場合返品ステータス後で使用するには、次の手順を実行する必要があります。

checkFolderExist "${INPUT}"
CHECKINPUT=$?

checkFolderExist "${OUTPUT}"
CHECKOUTPUT=$?

それに加えて、とにかく次のアドバイスに従ってください。コサロナンダの答え問題を解決するためのより良い技術を案内します。

答え3

関数の出力と戻り値を混同しています。エラーを確認できるように、最小限の実際の例を示します。

リターン:

myfunc() {
  return 1
}

myfunc
ret=$?
[ $ret -eq 0 ] && echo OK

または標準出力に書き込み、出力を確認します。

myfunc() {
  echo '1'
}

ret="$(myfunc)"
[ "$ret" = '0' ] && echo OK

また、私は変数の整数と文字列を区別することを好みますがret、出力が数字にすぎないことを知っていれば、より明確にするために実際には必要ありません。また、条件文が続く場合は戻り値を変数にキャプチャする必要はありません。

これが必要な最初の項目なので使用できません$()。 2 つの項目を混ぜ合わせると、最初の例のように値を返し、2 番目の例のように出力を確認します。

関連情報