3

私は非常に単純なスクリプトを実行したいと考えています。自分のコンピューターで svn などのプログラムの最新バージョンを見つけたいだけです。結果を mysvn などの変数にロードしたい

だから私はこのスクリプトを作ります:


#!/bin/sh

mysvn="foobar"
best_ver=0
which -a svn | while read p
do
    version=$("$p" --version | grep 'version ' | grep -oE '[0-9.]+' | head -1)
    if [[ "$version" > "$best_ver" ]]
    then
        best_ver=$version
        mysvn="$p"
    fi
    echo $mysvn
done

echo $mysvn

実際には非常に単純です...しかし、XPで実行されているバージョン2.7.10のrxvt(私の疑似Linux端末)では機能しません。最終的な出力文字列はfoobarです。

なぜ私がこの問題を抱えているのか誰か知っていますか?

過去数か月間、いくつかのスクリプトを書いてきましたが、そのような動作に遭遇したのは初めてです。

注:いくつかの変更を加えて、それを機能させる方法を知っています(メイン行を $() に入れるだけです)

4

2 に答える 2

2

これが発生する理由は、while ループがパイプラインの一部であり、(少なくとも bash では) パイプライン内のすべてのシェル コマンドが常にサブシェルで実行されるためです。ループ内で mysvn を設定すると、サブシェルで設定されます。ループが終了すると、サブシェルが終了し、この値は失われます。親シェルの mysvn の値は変更されません。BashFAQ #024この前の質問を参照してください。

bash での標準的な解決策は、パイプラインではなくプロセス置換を使用することです。

while
...
done < <(which -a svn)

ただし、これは bash のみの機能であり、これを機能させるにはシバンとして使用する必要があることに注意してください。#!/bin/bash

于 2012-07-06T15:26:47.133 に答える
0

Ubuntu の場合:

:~$ which -a svn | while read p
> do
>   version=$("$p" --version | grep 'version ' | grep -oE '[0-9.]+' | head -1)
>   echo $version
> done
.

だから、あなたのバージョンは.、あまり良くありません。

私はこれを試しましたが、それがあなたが探しているものだと思います:

:~$ which -a svn | while read p
> do
>   version=$("$p" --version | grep -oE '[0-9.]+' | head -1)
>   echo $version
> done
1.7.5
于 2012-07-06T14:54:07.627 に答える