2

私のプログラムでは、関数から値を返そうとしていますが、戻り値は文字列です。返された値をエコーすると、すべてが正常に機能します(少なくとも一部)が、返されない場合は関数を呼び出すことさえありません....以下のコードを検討してください....

#!/bin/bash

function get_last_name() {
    echo "Get Last Name"
    ipath=$1

    IFS='/'
    set $ipath
    for item
            do
                    last=$item
            done

    echo $last
}

main() {
    path='/var/lib/iscsi/ifaces/iface0'
    current=$(get_last_name "$path")
    echo -n "Current="
    echo $current
}


main

このような出力が得られます

OUTPUT
     Current=Get Last Name iface0

echo $current にコメントすると、"Get Last Name" も表示されず、関数を呼び出していないという結論に達します。私が犯している間違いを教えてください。しかし、私が確信していることの 1 つは、bash が私が今まで見た中で最も醜い言語であることです........

4

1 に答える 1

7

関数にはbashの戻り値はありません。あなたが書くとき

current=$(get_last_name "$path")

に戻り値を割り当てていませんcurrentget_last_name(コマンドを使用して記述された)の標準出力をキャプチャし、echoに割り当てていcurrentます。そのため、「名前を取得」は表示されません。そのテキストは端末には届きませんが、に保存されcurrentます。


詳細な説明

最初に見ていきましょうget_last_name(説明を簡単にするためにいくつかのわずかな変更を加えて):

function get_last_name () {
    ipath=$1

    local IFS='/'
    set $ipath
    for item
    do
        last=$item
    done

    echo "Get Last Name"
    echo $last
}

変更がの本文に限定されるようlocalに前にコマンドを追加し、2つのステートメントの類似性を強調するために、最初のコマンドを最後に移動しました。が呼び出されると、単一の引数(ファイルパスを含む文字列)が処理され、「GetLastName」とファイルパスの最後のコンポーネントの2つの文字列がエコーされます。コマンドラインからこの関数を実行すると、次のように表示されます。IFSget_last_nameechoechoget_last_name

$ get_last_name /foo/bar/baz
Get Last Name
baz

関数の終了コードは、最後に実行されたコマンドの終了コード(この場合は)になりecho $lastます。書き込みが成功する限り、これは0になります(ほぼ確実に成功します)。

次に、 :mainを呼び出す関数を見てみましょう。get_last_name

main() {
    path='/var/lib/iscsi/ifaces/iface0'
    current=$(get_last_name "$path")
    echo -n "Current="
    echo $current
}

と同様にget_last_namemain戻り値はありません。の終了コードである終了コードを生成しますecho $currentget_last_nameこの関数は、コマンド置換()内で呼び出すことから始まります。これにより$(...)、からのすべての標準出力がキャプチャget_last_nameされ、文字列として扱われます。

余談

次の違いに注意してください。

current=$(get_last_name "$path")

の値currentをの累積標準出力に設定しますget_last_name。(特に、出力の改行はスペースに置き換えられますが、空白の処理方法の完全な説明は別の日のトピックです)。これは戻り値とは何の関係もありません。終了コード(クローゼットbashは「値を返す」必要があります)は単一の整数であることを忘れないでください。

current=get_last_name "$path"

も呼び出さないでしょうget_last_name。「$path」をコマンドの名前として解釈し、実行しようとします。そのコマンドcurrentの環境には、文字列値「get_last_name」の変数が含まれます。

重要なのはget_last_name、変数に割り当てることができるものは何も「返さない」ということです。終了コードがあり、標準出力に書き込むことができます。この$(...)構成を使用すると、その出力を文字列としてキャプチャし、それを(とりわけ)変数に割り当てることができます。

戻るmain

の値がcurrentによって生成された出力に設定されるとget_last_name、最後の2つのechoステートメントを実行して、標準出力に再度書き込みます。最初のステートメントは改行なしで「Current=」を書き込むため、次のechoステートメントは最初のステートメントと同じ行にテキストを生成します。2つ目は、の値をエコーするだけですcurrent

echoの最後をコメントアウトしたときmain、実行を停止しませんでしたget_last_name(すでに実行されていました)。むしろ、端末ではなくcurrentの出力が配置された変数の内容を出力しなかっただけです。get_last_name

于 2012-07-13T19:10:11.523 に答える