スクリプトの変数にタイムアウトコマンドを割り当てる

スクリプトの変数にタイムアウトコマンドを割り当てる

nvlcが実行される時間を設定しようとしています。実際には、1つのCaseステートメントに複数のnvlcコマンドがあるため、再生するストリームを選択できます。スクリプトをgitlabスニペットとして公開しました。ここ

期間を設定したい場合、または$durationが設定されていない場合、または0に設定されている場合は、「nvlc」(秒はs、分はm)の前に「timeout(duration)s」は追加されません。

read -p "What duration in MINUTES do you want the recording to run for? :  " duration
if [ -z ${duration+x} -o $duration = 0 ]; then t=""; else t='timeout '"$duration"'m'; fi

後で(行47など)nvlcは次のように呼び出されます。

"$t" nvlc stream-url

したがって、期間が設定されていないかゼロに設定されている場合、「$ t」は空白になりますが、期間の値が設定されている場合、期間変数はnvlcコマンドによって解釈されます。例: timeout 60m nvlc stream -url

さまざまなエラーが発生します。 t='timeout '"$duration"''s' を使用するときのエラーは次のとおりです。行47:タイムアウト5秒:コマンドが見つかりません。

t='timeout $durations' を使用するときのエラーは次のとおりです。 Line 47: timeout $durations: コマンドが見つかりません。

私がどこで間違っているかを指摘してもらえますか?

答え1

これにはいくつかの問題があります。 1つ目は$t二重引用符で拡張することです。

"$t" nvlc stream-url

変数参照を二重引用符で囲むことで、誤ったトークン化やワイルドカードの拡張を防ぐことができるので、ほぼ常に良い考えですが、この場合必要噴射。tに設定されている場合、二重引用符を使用すると、シェルは文字列全体を(コマンド名)と(対応する引数)に分割せずにコマンド名timeout 5sとして扱います。また、空の文字列に設定すると、コマンドから消えるだけでなく、実際には空の文字列をコマンド名で実行しようとします!この問題を解決するには、二重引用符を削除します。timeout5st

$t nvlc stream-url

(コマンドがより複雑な場合は、通常の変数の代わりに配列を使用する必要があります。BashFAQ#50:コマンドを変数に入れようとしていますが、複雑な場合は常に失敗します!)

2番目の問題は条件式です[ -z ${duration+x} -o $duration = 0 ]duration引用されているいいえこれは二重引用符で囲まれています。するduration空の文字列に設定すると消えてしまうため、内容全体が に展開されるため[ -z x -o = 0 ]無効です。ここにあなた必要二重引用符で囲みます。また、+x最初のテストからそれを削除するか、次に置き換えてください:+x+x変数が設定されている場合(空の文字列に設定されていても)、オプションはこれを「x」に拡張しますが、read2つだけです。いつも「x」に展開します。+x適切な二重引用符を削除して追加するだけです。

if [ -z "${duration}" -o "$duration" = 0 ]; then ...

最後に、引用はt='timeout '"$duration"'m'奇妙です。間違っているのではなく、複雑すぎるだけです。変数以外の部分を一重引用符で囲むことは重複し、内容全体を一重引用符で囲むと変数は拡張されません。内容全体を二重引用符で囲む方が簡単で明確です。

t="timeout ${duration}m"

(中括弧が必要なので、「m」(または一部のバージョンでは「s」)は変数名の一部とは見なされません。)

関連情報