5

bash スクリプトの結果は、デバッグを使用して実行するかどうか (つまり を呼び出す) によって変わることがわかりましたset -x。より多くの出力が得られるという意味ではありませんが、プログラム自体の結果が異なるという意味です。

これは望ましい動作ではないと思います。これを修正する方法を教えていただければ幸いです。

以下の bash スクリプトは不自然な例です。問題を簡単に再現して明らかにできるように、調査中のスクリプトからロジックを減らしてみました。

#!/bin/bash

# Base function executes command (print working directory) stores the value in
# the destination and returns the status.
function get_cur_dir {
    local dest=$1
    local result

    result=$((pwd) 2>&1)
    status=$?

    eval $dest="\"$result\""
    return $status
}

# 2nd level function uses the base function to execute the command and store
# the result in the desired location. However if the base function fails it
# terminates the script. Yes, I know 'pwd' won't fail -- this is a contrived
# example to illustrate the types of problems I am seeing.
function get_cur_dir_nofail {
    local dest=$1
    local gcdnf_result
    local status

    get_cur_dir gcdnf_result
    status=$?
    if [ $status -ne 0 ]; then
        echo "ERROR: Command failure"
        exit 1
    fi

    eval dest="\"$gcdnf_result\""
}


# Cause blarg to be loaded with the current directory, use the results to
# create a flag_file name, and do logic with the flag_file name.
function main {
    get_cur_dir blarg

    echo "Current diregtory is:$blarg"

    local flag_file=/tmp/$blarg.flag

    echo -e ">>>>>>>> $flag_file"

    if [ "/tmp//root.flag" = "$flag_file" ]; then
        echo "Match"
    else
        echo "No Match"
    fi
}


main

.

.

なしで実行すると、set -x以下に示すように期待どおりに機能します。

Current diregtory is:/root
>>>>>>>> /tmp//root.flag
Match

.

.

ただし、デバッグ出力を -x で追加すると、以下に示すように機能しません: root@psbu-jrr-lnx:# bash -x /tmp/example.sh

+ main
+ get_cur_dir blarg
+ local dest=blarg
+ local result
+ result='++ pwd
/root'
+ status=0
+ eval 'blarg="++ pwd
/root"'
++ blarg='++ pwd
/root'
+ return 0
+ echo 'Current diregtory is:++ pwd
/root'
Current diregtory is:++ pwd
/root
+ local 'flag_file=/tmp/++ pwd
/root.flag'
+ echo -e '>>>>>>>> /tmp/++ pwd
/root.flag'
>>>>>>>> /tmp/++ pwd
/root.flag
+ '[' /tmp//root.flag = '/tmp/++ pwd
/root.flag' ']'
+ echo 'No Match'
No Match
root@psbu-jrr-lnx:#  
4

3 に答える 3

3

変化...

result=$((pwd) 2>&1)

...の中へ...

result=$(pwd 2>&1)

...pwdによって生成されたデバッグ情報をキャプチャせずに、 の出力をキャプチャできますset -x

于 2013-04-29T16:51:44.183 に答える
0

$PWD 変数が存在する理由は、スクリプトが別のプロセスを実行したり、その出力を解釈したりする必要がないようにするためです (この場合は、-x によって変更されています)。代わりに $PWD を使用してください。

于 2013-04-29T16:44:16.503 に答える