ターミナルクローズに耐えるコマンドを実行するにはどうすればよいですか?


313

プロセスを開始して、それを忘れたい場合があります。次のようにコマンドラインから起動した場合:

redshift

ターミナルを閉じることができないか、プロセスが強制終了されます。プロセスを強制終了せずに端末を閉じることができるような方法でコマンドを実行できますか?


4
すべてのディストリビューションにデフォルトでインストールされるわけではありませんが、画面はあなたの友達です:en.wikipedia.org/wiki/GNU_Screen
Zayne S Halsall

同じ問題に直面している人にとって:入力yourExecutable &しても出力が画面に表示され続けCtrl+C、何も停止しないように見える場合でも、画面が出力でスクロールしていて何が表示されていなくても盲目的に入力disown;して押すだけEnterです入力中です。プロセスは無視され、プロセスが終了することなく端末を閉じることができます。
ナビゲーション

tmuxなどのスクリーンマルチプレクサを使用できます。ubuntuマシンでapt-getを介して利用できます
-Himanshu

回答:


311

次の2つのいずれかが機能します。

$ nohup redshift &

または

$ redshift &
$ disown

この仕組みの詳細については、次を参照してください。


5
2番目の(redshift & disown)はUbuntu 10.10で機能しました。すべてを1行に入れてうまく機能するようです。これをしてはいけない理由はありますか?
マシュー

4
@Matthew最初のものも正常に動作するはずです。2番目のようにバックグラウンドにならないだけです(nohup redshift &バックグラウンドにしたい場合があります)。通常、あなたと分離が1行の2番目を置くことは、結構です;redshift &; disown
マイケル・Mrozek

10
@Michael:;&は両方ともコマンド区切り文字であり、優先順位は同じです。唯一の違いは、同期実行と非同期実行です(それぞれ)。&;優先するだけで使用する必要はありません&(動作しますが、少し冗長です)。
クリスジョンセン

4
良い答えは、端末がデバッグ出力でスパム送信されないようにstdoutとstderrをリダイレクトすることをお勧めします
キム

12
また、redshift &!すぐに赤方偏移を否認します。

143

プログラムがすでに実行されている場合は、で一時停止し、次のようにCtrl-Zバックグラウンドに移動してbgから実行できますdisown

$ sleep 1000
^Z
[1]+  Stopped                 sleep 1000
$ bg
$ disown
$ exit

3
否認後、実行中のプロセスの標準出力を再度読み取るにはどうすればよいですか?
ネックウィ


1
なんらかの理由でこれはうまくいきませんでした(centos)
イアン

この手順の後、プロセスを強制終了する方法は?
パラクダルジ16年

2
@necktwi disownは、stdoutまたはstderrを切断しません。しかしnohupそうであるよう、ん>/dev/null(切断標準出力)、 2>/dev/null(標準誤差を切断)。それ(disown)はジョブ制御を切断します。
ctrl-alt-delor

45

良い答えは@StevenDによってすでに投稿されていますが、これでもう少し明確になるかもしれません。

ターミナルの終了時にプロセスが強制終了されるのは、開始するプロセスがターミナルの子プロセスだからです。ターミナルを閉じると、これらの子プロセスも強制終了されます。pstreeたとえばkate &、Konsoleで実行している場合、プロセスツリーを表示できます。

init-+
     ├─konsole─┬─bash─┬─kate───2*[{kate}]
     │         │      └─pstree
     │         └─2*[{konsole}]

作るためにkateから独立プロセスkonsoleあなたが終了したときにkonsole、使用してnohupこのように、コマンドで:

nohup kate &

を閉じるとkonsole、次のpstreeようになります。

init-+
     |-kate---2*[{kate}]

そしてkate生き残ります。:)

別の方法は、screen/ tmux/ を使用byobuすることです。これにより、端末に依存せずにシェルが実行され続けます。


Disownメソッドに問題がありました。これは現在私のために働いているので、賛成です。-f nohup.outを追跡して何が起こっているかを確認できますが、セッションが失敗する心配はありません。
イアン

27

ターミナルでこのようなプロセスを実行できます

setsid process

これにより、新しいセッションでプログラムが実行されます。説明したようにhttp://hanoo.org/index.php?article=run-program-in-new-session-linux


1
nohupに対するsetsidの利点は何ですか?
-itsbruce

1
1)について迷惑なメッセージを出力しませんnohup.out。2)シェルのジョブリストに残っていないため、の出力が乱雑になりませんjobs
ミケル

これは、lxterminalで実行され、pcmanfmを起動して終了する(pcmanfmの実行中に端末を閉じることができるsetsidで)スクリプトで機能する唯一のソリューションです。どうもありがとうございます!
デスグア

9

すべての提案はうまく機能しますが、私の代替手段はscreen、画面に仮想端末をセットアップするプログラムを使用することです。

で始めることを検討してください。Screenは、事実上すべてのLinuxおよびUnix派生製品にインストールできます。打撃+ 及び(小文字)は第二のセッションを開始します。これは、あなたが押すことで前後に最初のセッションの間で切り替えることができるようになる+ と打つことで以降のセッションを+にして。1つの端末で最大10個のセッションを使用できます。以前は仕事でセッションを開始し、家に帰り、仕事用のマシンにsshしてから呼び出します。これにより、そのリモートセッションに再接続されます。screen -S session_nameCtrlACCtrlA0CtrlA1screen -d -R session_name


screen -d -m command:すでに切り離さ画面内にそれを開始します ~# screen -d -m top ~# screen -ls There is a screen on: 10803..Server-station (Detached) 1 Socket in /root/.screen. ~# screen -x ....そして、あなたはにいる。
博士アレクサンダー

7

これをすべて行うシェル専用の方法は、stdinを閉じてコマンドをバックグラウンドにすることです。

command <&- & 

そうすると、シェルを終了しても終了しません。stdoutのリダイレクトは、実行するのに最適なオプションです。

欠点は、事後にこれを行うことができないことです。


私はubuntuで試しました。ターミナルを強制終了すると、起動したプロセスも閉じられます。なぜこれが事実であるかについてのアイデアはありますか?
アショクKoyi

7

次のスクリプトがあります。

  • バックグラウンドで任意のコマンドを実行する

  • 端末ウィンドウで殺されるのを止めます

  • 出力を抑制する

  • 終了ステータスを処理します

私はのために主に使用しgeditevinceinkscapeすべてが迷惑なの端子出力の多くを持っていることなど。コマンドがbefore TIMEOUTで終了する場合、nohupの終了ステータスはゼロではなく返されます。

#!/bin/bash

TIMEOUT=0.1

#use nohup to run the command, suppressing its output and allowing the terminal to be closed
#also send nohup's output to /dev/null, supressing nohup.out
#run nohup in the background so this script doesn't block
nohup "${@}" >/dev/null 2>&1 &
NOHUP_PID=$!

#kill this script after a short time, exiting with success status - command is still running
#this is needed as there is no timeout argument for `wait` below
MY_PID=$$
trap "exit 0" SIGINT SIGTERM
sleep $TIMEOUT && kill $MY_PID 2>/dev/null & #ignore "No such process" error if this exits normally

#if the command finishes before the above timeout, everything may be just fine or there could have been an error
wait $NOHUP_PID
NOHUP_STATUS=$?
#print an error if there was any. most commonly, there was a typo in the command
[ $NOHUP_STATUS != 0 ] && echo "Error ${@}"
#return the exit status of nohup, whatever it was
exit $NOHUP_STATUS

例...

>>> run true && echo success || echo fail
success
>>> run false && echo success || echo fail
Error false
fail
>>> run sleep 1000 && echo success || echo fail
success
>>> run notfound && echo success || echo fail
Error notfound
fail

7

私が好む:

(アプリケーション名 &)

例えば: linux@linux-desktop:~$ (chromium-browser &)

コマンドを入力するときは、必ず括弧を使用してください!


1
ターミナルを閉じるとプロセスが
強制終了さ

1
おそらく、かっこなしで回答で使用したプロンプトコマンドがあります。ターミナルを閉じるとプロセスが強制終了され、そうでない場合は発生しません。明確にするために、既に上記のソリューションを編集しました。
-daGo

私のために働く、tnx
noadev

私はなぜこれがより多くの賛成を得なかったのだろうかと思っています。nohuptty出力を防止し、実際に出力をファイルにリダイレクトしたかったので、それが防止されたので、これは私にとってより良い解決策です。
redanimalwar

4

ログアウトしてターミナルセッションを閉じるときにHUP信号を受信しないようにプロセス(PID)を設定できます。次のコマンドを使用します。

nohup -p PID

3

おそらくapolinskyによって提供される答えと同様に、私はのバリアントを使用しscreenます。バニラコマンドはこんな感じ

screen bash -c 'long_running_command_here; echo; read -p "ALL DONE:"'

Ctrl ACtrl D単純なケースでは、セッションを切断して再接続できますscreen -r。これは、便利なアクセスの準備ができsessionているというスクリプトに包まれていPATHます。

#!/bin/bash
#
if screen -ls | awk '$1 ~ /^[1-9][0-9]*\.'"$1"'/' >/dev/null
then
    echo "WARNING: session is already running (reattach with 'screen -r $1')" >&2
else
    exec screen -S "$1" bash -c "$@; echo; echo '--------------------'; read -p 'ALL DONE (Enter to exit):'"
    echo "ERROR: 'screen' is not installed on this system" >&2
fi
exit 1

これは、プログラムを切断したいことが事前にわかっている場合にのみ機能します。既に実行中のプログラムを切断することはできません。


2

以前に投稿された他の回答と同様に、reptyrのおかげで実行中のプロセスを転送して「スクリーン」を遡及的に使用し、ターミナルを閉じることができます。手順はこの投稿で説明されています。実行する手順は次のとおりです。

  1. プロセスを中断する
  2. バックグラウンドでプロセスを再開する
  3. プロセスを否認する
  4. スクリーンセッションを開始する
  5. プロセスのPIDを見つける
  6. reptyrを使用してプロセスを引き継ぐ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.