2

次のロジックを使用するスクリプトがあります。

if [ ! -z "$1" ]; then         # if any parameter is supplied
    ACTION=                    # clear $ACTION
else
    ACTION=echo                # otherwise, set it to 'echo'
fi

これはそのままで問題なく動作します。ただし、マニュアルの「シェルパラメータ拡張」セクションを読むと、bashこれは1つのステップで実行できるはずです。しかし、そのやり方に頭を悩ませることはできません。

私はもう試した:

ACTION=${1:-echo}              # ends up with $1 in $ACTION

ACTION=${1:+}
ACTION=${ACTION:-echo}         # ends up always 'echo'

そしてそれらをネストするいくつかの方法がありますが、私が知る限り、ネストは許可されていないようです。

私はすでに実用的な解決策を持っていることを認識していますが、これが可能かどうか本当に興味があります。三項演算子を使えば簡単なことですが、bashにあるとは思いません。

これが可能であれば、if / else構文を使用せずに、シェルパラメーター拡張機能の任意の組み合わせのみを使用して、このように見える2ステップのプロセスを実行するロジックを確認したいと思います。

ありがとうございました。


elderarthisの編集:

スクリプトの残りの部分は次のとおりです。

find . -name "*\?[NMSD]=[AD]" -exec ${ACTION} rm -f "{}" +

私は自分自身に対する健全性チェックをしたいACTION=echoので、引数を渡すと実際に削除が行われます($ {ACTION}を無効にすることで)。引数を渡さないとエコーが残ります。

そして私はTIMTOWTDIを知っています。シェルパラメータ拡張セクションの内容だけで実行できるかどうかを確認しています:-)


ミケルのための編集:

$ cat honk.sh
#!/bin/bash
ACTION=${1-echo}
echo $ACTION
$ ./honk.sh
echo
$ ./honk.sh foo
foo

最後はを持っている必要がACTION=''あるため、空白行/null値を返します。

4

2 に答える 2

6

4行未満でサブシェルなしで実行することを主張した場合は、次を使用すると思います。

ACTION=${1:+' '}
: ${ACTION:=echo}

これはわずかに不正行為をします-スクリプトに引数がある場合、空のアクションではなく空白のアクションを作成します。引数がない場合、2行目の前のACTIONは空です。2行目で、アクションが空の場合は、「echo」に設定します。拡張では、(正しく)$ ACTIONを引用しないため、空白の引数は渡されません。

テスター(xx.sh):

ACTION=${1:+' '}
: ${ACTION:=echo}

echo $ACTION rm -f a b c

テスト:

$ sh xx.sh 1
rm -f a b c
$ sh xx.sh
echo rm -f a b c
$ sh xx.sh ''
echo rm -f a b c
$ 

最後の行が正しくない場合は、プラスの前からコロンを削除します。


サブシェルが受け入れられる場合は、次の2つの単一行のいずれかが機能します。

ACTION=$([ -z "$1"     ] && echo echo)
ACTION=$([ -z "${1+X}" ] && echo echo)

最初のバージョンは、上記の最初のバージョンに対応します(空の最初の引数は存在しないものとして扱われます)。2つ目は、現在の空の引数を扱います。あなたは書くことができます:

ACTION=$([ -z "${1:+X}" ] && echo echo)

2番目との関係をより明確にするために-両方ではなく、どちらか一方のみを使用することを除いて。


私のコメントのマークダウン表記はシステムを混乱させたので(または私はそれを間違えたが十分に迅速に修正できなかった)、私の最後のコメント(わずかに修正された)は次のようになります:

表記${var:+' '}は、'$varが設定されていて空でない場合は、+'に続くものを使用することを意味します(この場合、これは単一の空白です)。表記${var+' '}は、'$varが設定されている場合、空であるかどうかに関係なく、+'に続くものを使用することを意味します。これらの他の拡張は類似しています:

  • ${var:=X}-すでに空でない値がない限り、に設定$varします。X
  • ${var:-X}-$var値が空でない場合に展開されX$var設定されていないか空の場合に展開されます

コロンを削除すると、テストの「空の」部分が削除されます。

于 2011-01-25T04:46:37.350 に答える
2
ACTION=${1:-echo}

正しい。

$1何かを変更する前に(たとえば、setコマンドの前に)、スクリプトの先頭近くにあることを確認してください。$1また、関数の最初のパラメーターであるため、関数内では機能しません。

また、$1が設定されているがnullであるかどうかを確認します。その場合は、呼び出し方法を修正するか、を使用しますACTION=${1-echo}(がないことに注意してください:)。


アップデート

ああ、それ以外の意味はあまり意味がなかったので、あなたは反対の意味を持っていたに違いないと思いました。

それはまだ奇妙に思えますが、私は精神的な運動として、多分あなたはこのようなものが欲しいと思います:

#!/bin/bash
shopt -s extglob
ACTION=$1
ACTION=${ACTION:-echo}
ACTION=${ACTION/!(echo)/}    # or maybe ACTION=${ACTION#!(echo)}
echo ACTION=$ACTION

それは完全に正しくありません:それは与えますACTION=o、しかし私はそれらの線に沿った何かがうまくいくはずだと思います。

echoまた、として合格$1するとエコーのままになりますが、悪いことではないと思います。

それもひどく醜いです、しかしあなたは質問をするときそれを知っていました。:-)

于 2011-01-25T03:46:21.677 に答える