2011-10-07 23 views
43

bashでバックグラウンドでプロセスを実行するのはかなり簡単です。印刷ジョブとプロセスIDを持たないバックグラウンドでbashコマンドを実行する

$ echo "Hello I'm a background task" & 
[1] 2076 
Hello I'm a background task 
[1]+ Done     echo "Hello I'm a background task" 

ただし、出力は冗長です。最初の行には、バックグラウンドタスクのジョブIDとプロセスIDが表示されます。次に、コマンドの出力があり、最後にジョブID、ステータス、およびジョブをトリガしたコマンドがあります。

最後にアンパサンドがない場合と同じように出力が表示されるようにバックグラウンドタスクを実行する出力を抑制する方法はありますか?すなわち:

$ echo "Hello I'm a background task" & 
Hello I'm a background task 

私が尋ねる理由は、私はそのコマンドの出力は何の意味を作るために中断しないこと、しなければならないので、タブ補完コマンドの一部としてバックグラウンド・プロセスを実行したいということです。

+0

私は、bash-completionスクリプトの中で何かに2>/dev/nullを追加することをお勧めします。 – sehe

答えて

48

完了に関連していない(これはexecの操作で、おそらく、おそらくです)、しかし、あなたはサブシェルでコールを置くことによって、その出力をSUPRESSことができます:@ shellterの答えのオフ

(echo "Hello I'm a background task" &) 
+2

ありがとう、間違いなく動作します。残念ながら、このようなスクリプトをbash-completion関数から実行すると、bashはサブプロセスが完了するまで待ってから完了結果を出すように見えます。これは残念なことに、バックグラウンドワーカーをbash-completionによって起動させることができないように見えるため、残念です。 –

+3

バックグラウンドジョブが終了するのを待ちたい場合は、これを使うことはできません。 – arekolek

10

サブシェルまたはプロセスグループ(つまり、{ ... })で囲む必要があります。

/home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null 
Hello I'm a background task 
/home/shellter $ 

IHTH

編集

@マークのdownvoteの指示に従い、私はこれはbashで正しく動作しないことを研究しています。これは、ksh93のように動作します。

今はビジーですが、これと@Tizordの答えにコメントした内容でこの回答を更新しますが、std-errをバックグラウンドからリダイレクトする方法は簡単にはわかりません仕事。

+1

中括弧を使用すると出力の最後の行が表示されます(なぜそれが見えないのか分かりません)。 –

+0

私はこれを正確にコピーしましたが、それは私にとってはうまくいかず、@AlexSpurlingのように出力が表示されます。多分私は他の人たちがそれを上回ってから間違ったことをやっているかもしれないが、私はそれに-1を与えなければならないのではないかと思う。 – Mark

+0

@マーク:私はこれを使っていくつかの簡単なテストを行っただけです。問題は、私のprimariyシェルとして 'ksh93 +'を使い続けていることです。このコードは、kshで約束されたとおりに動作します。 OPが 'bash'でタグ付けされているので、私はあなたのdvを理解しています。 @ Tyzoidの答えに対するbashテストの結果を参照してください。皆さんお元気で! – shellter

9

ビル、これは私のために働いていました:

[email protected]:~$ { echo "Hello I'm a background task" & disown; } 2>/dev/null; sleep .1; 
Hello I'm a background task 
[email protected]:~$ 

私はこの背後にある理由を知らないが、私は、プロセスIDを出力するから、bashのを防ぐ勘当古いポストから思い出しました。上記の回答に

+0

それはうまくいきますが、すべてのstderrを嚥下します。 – Mark

+0

@チュゾイド。私はあなたのソリューションをbashシェル(v 4.2.37)で試してみて、興味深い結果を得ました。 1.最後に ';'を追加するだけで同じ結果が得られます。 (寝ないで) 。 2.「次の」行に 'echo STDERR 2>&1'を追加すると' [1] + Done ... 'のことが現れたことに気付きました! 。 3.私の解決策(今述べたように)は 'ksh'で動作し、' echo STDERR 2>&1'は出力STDERRしか出力しません。さて、私たちのために生きて学びましょう。皆さんお元気で。 – shellter

5

ビル、あなたは標準エラー出力には、コマンドから通ってくることができるように必要がある場合:

f() { echo "Hello I'm a background task" >&2; } 
{ f 2>&3 &} 3>&2 2>/dev/null 
3

試してみてください。

[email protected]:~$ read < <(echo "Hello I'm a background task" & echo $!) 
[email protected]:~$ echo $REPLY 
28677 

そして、あなたが隠されている出力の両方PIDPIDは$ REPLY

+0

これは完璧です!ありがとうございました –

3

から返信できますが、これは古い投稿への返信で申し訳ありませんが、これは他のユーザーにとって便利であり、Googleでの最初の返信です。

私はこの方法(サブシェル)に問題があり、 '待機'を使用していました。

function a { 
    echo "I'm background task $1" 
    sleep 5 
} 

function b { 
    for i in {1..10}; do 
     a $i & 
    done 
    wait 
} 2>/dev/null 

とするとき、私はそれを実行します:

$ b 
I'm background task 1 
I'm background task 3 
I'm background task 2 
I'm background task 4 
I'm background task 6 
I'm background task 7 
I'm background task 5 
I'm background task 9 
I'm background task 8 
I'm background task 10 

をそして、私は私のプロンプトを取得する前に5秒の遅延がありますしかし、私は関数の中にそれを実行していたとして、私はこれを行うことができましたバック。

1

サブシェル解決策は機能しますが、バックグラウンドジョブを待つことができます(最後に「完了」メッセージは表示されません)。サブシェルからの$!は、現在の対話シェルでは「待機可能」ではありません。私のために働いた唯一の解決策は、私自身の待機機能を使用することでした。これは非常に簡単です。

myWait() { 
    while true; do 
    sleep 1; STOP=1 
    for p in $*; do 
     ps -p $p >/dev/null && STOP=0 && break 
    done 
    ((STOP==1)) && return 0 
    done 
} 

i=0 
((i++)); p[$i]=$(do_whatever1 & echo $!) 
((i++)); p[$i]=$(do_whatever2 & echo $!) 
.. 
myWait ${p[*]} 

簡単に十分です。

関連する問題