web-dev-qa-db-ja.com

bashでは、リターンコードを設定する方法は?

Whileループに入るように、戻り値を1回設定したい:

#!/bin/bash
while [ $? -eq 1 ]
do
#do something until it returns 0    
done

これを機能させるには、最初に$? = 1を設定する必要がありますが、それは機能しません。

25
JohnnyFromBF
#!/bin/bash

RC=1

while [ $RC -eq 1 ]
do

  #do something until it returns 0    

  RC=$?
done
11
Eugen Rieck

サブシェルで引数を指定してexitを実行することにより、任意の終了コードを設定できます。

$ (exit 42); echo "$?"
42

だからあなたができる:

(exit 1)    # or some other value > 0 or use false as others have suggested
while (($?))
do
    # do something until it returns 0    
done

または、 do whileループをエミュレート

while 
    # do some stuff
    # do some more stuff
    # do something until it returns 0    
do
    continue  # just let the body of the while be a no-op
done

これらのどちらも、ループが少なくとも1回実行されることを保証します。

完全を期すために、exitおよびreturnはそれぞれ、整数(正、負、またはゼロ)であるオプションの引数を受け入れます。シェル(またはスクリプトまたはサブシェル*)はexitを使用して終了し、関数はreturnを使用して終了します。

例:

$ (exit -2); echo "$?"
254
$ foo () { return 2000; }; foo; echo $?
208

*これは、パイプによって作成されるサブシェルにも当てはまります(ジョブ制御が無効でlastpipeが有効な場合を除く):

$ echo foo | while read -r s; do echo "$s"; exit 333; done; echo "$?"
77

breakを使用してループを終了することをお勧めしますが、その引数は、リターンコードではなく、ループのレベル数をブレークアウトするためのものです。

set +mset +o monitor、またはshopt -u -o monitorを使用してジョブ制御を無効にします。 lastpipeを有効にするには、shopt -s laspipeを実行します。これらの両方を行う場合、前の例のexitは、whileループandを含むシェルを引き起こしますtobothexitと最後のechoは実行されません。

107

falseは常に終了コード1を返します。

#!/bin/bash
false
while [ $? -eq 1 ]
do
#do something until it returns 0    
done
17
chepner

一部の回答は、コードの書き換えに依存しています。場合によっては、制御できない外部コードである可能性があります。

この特定の質問については、$を設定するだけで十分ですか? 1に設定しますが、$を設定する必要がある場合は?任意の値に-唯一の有用な答えは、デニスウィリアムソンのものからです。

新しい子を生成しない(より簡潔でもある)もう少し効率的なアプローチは次のとおりです。

function false() { echo "$$"; return ${1:-1}; }
false 42

注:エコー部分は、現在のプロセスで実行されることを確認するためだけにあります。

6
chukko

whileループに入る前に、失敗することが保証されているコマンドを実行することで、これを暗黙的に行うことができると思います。

正規のそのようなコマンドは、もちろん、false

4
unwind

単純な関数よりも軽いものは見つかりませんでした:

function set_return() { return ${1:-0}; }

(...)または[...]またはfalseなどの他のすべてのソリューションには、外部プロセス呼び出しが含まれる場合があります。

1
Andry

古い質問ですが、もっと良い答えがあります:

#!/bin/bash
until
    #do something until it returns success
do
    :;
done

何かが成功するまでループしている場合は、untilセクションでそれを行います。 do/doneセクションに配置する必要があると考えていたuntilセクションに、まったく同じコードを配置できます。 do/doneセクションにコードを記述し、その結果をwhileまたはuntilに戻す必要はありません。

1
don provan

このようなものはあなたが探しているものでしょうか?

#!/bin/bash
TEMPVAR=1
while [ $TEMPVAR -eq 1 ]
do
  #do something until it returns 0
  #construct the logic which will cause TEMPVAR to be set 0 then check for it in the 
  #if statement 

  if [ yourcodehere ]; then
     $TEMPVAR=0
  fi
done
1
David K

untilを使用して、#do something until it returns 0は、1または0以外のものを返します。

#!/bin/bash

false
until [ $? -eq 0 ]
do
#do something until it returns 0    
done
0
Steven Kearnes