bashスクリプトの実行後にターミナルを終了します


18

コマンドbashを使用して特定のファイル(主にpdfファイル)を開くスクリプトを作成しようとしていますgnome-open。また、pdfファイルを開いたら、端末を終了させます。

私はexitスクリプトの最後に追加しようとしましたが、それはターミナルを閉じません。私は自分の質問に対する答えをオンラインで検索しようとしましたが、適切な質問が見つかりませんでした。皆さんが助けてくれたら本当にありがたいです。

すべての端末ではなく、コマンドを実行した端末を強制終了するだけの回答が必要ですか?私が受け入れた以前の回答は、開いているすべてのターミナルウィンドウを強制終了します。今日までこれが事実だとは思いませんでした。


そもそも端末でスクリプトを実行していますか?厳密にコマンドラインから、そうするために端末を開く理由はありません。
ジェイコブVlijm

はい、端末からスクリプトを実行します。私は、端末とコマンドラインの間の差があった実現のdidnt
Rumesh

私は交換しgnome-openxdg-open私のスクリプトではなく、変更はありません。ターミナルはまだ開いたままです
ルメシュ

@ティムうわー、それは動作します=)+1
AB

@Timしかし、私の解決策も悪くはありませんでした。;)
AB

回答:


12

あなたのしている開口部1つのファイルだけならば、あなたはしていない、本当にスクリプトが一列に複数のコマンドを実行するための簡単な方法であることを意味するので、ここであなただけ(を含む2つのコマンドを実行する必要がある一方で、スクリプトを使用する必要がありますexit) 。

exitコマンドの後に、または一連のコマンドの後に実行する場合、&&演算子(前のコマンド/コマンドのチェーンが成功すると次のコマンドを実行します)を使用するか、または;演算子(前のコマンド/コマンドチェーンの成功と失敗の両方で次のコマンドを実行します)。

この場合、次のようになります。

gnome-open <path_to_pdf_file> && exit

* <path_to_pfd_file> = PDFファイルのパス

exitスクリプトの最後に置かれたbashスクリプトは、スクリプトが実行されるインスタンスを終了するだけで機能しません。これはbash、ターミナルの内部bashインスタンスとは別のインスタンスです。

とにかくスクリプトを使用する場合、最も簡単な方法は、次のようにスクリプトを呼び出すことです。

<path_to_script> && exit

または、スクリプトが次のようにターミナルの現在の作業ディレクトリにある場合:

./<script> && exit

本当にしたくない/できない場合は、スクリプトの最後に次の行を追加するのが2番目に簡単な方法です。

kill -9 $PPID

これSIGKILLにより、スクリプトの親プロセス(bashターミナルにリンクされたインスタンス)にシグナルが送信されます。1つのbashインスタンスのみがターミナルにリンクされている場合、そのインスタンスが削除されると、ターミナルは自動的に閉じます。複数のbashインスタンスがターミナルにリンクされている場合、そのインスタンスが削除されても、ターミナルは閉じられません。


2
SIGTERMシグナルは、プロセスの終了を要求するためにプロセスに送信されます。SIGKILLシグナルとは異なり、プロセスによってキャッチおよび解釈または無視されます。これにより、プロセスは適切な終了を実行してリソースを解放し、必要に応じて状態を保存できます。SIGINTはSIGTERMとほぼ同じです。
AB

@ABそうですね、SIGTERMここでは十分ではありません。
コス

返信いただきありがとうございます。私は病気ちょうどあなたがあなたの答えに与えた単一のコマンドを使用して推測する
Rumesh

kill $ PPIDはexitと同じです-何もしません。kill -9 $ PPIDは、親とともにすべての子ウィンドウを閉じます。
–SDsolar

5

このスクリプトは端末を終了し、シェルと自分自身を終了します。

すべてのプロセスを容赦なく殺します。ターミナルで複数のタブを開いている場合、これらも閉じられます。

問題は、複数の端末が開かれ、これらがの子プロセスであるgnome-terminal-server場合、すべての端末が強制終了されることです。

この場合、スクリプトは独立した端末で起動する必要があります。例えば xterm

<your_command> & disown

PPPID=$(awk '{print $4}' "/proc/$PPID/stat")
kill $PPPID
  • PPID

    PPIDは親プロセスID、この場合はシェル(e.g. /bin/bash

  • PPPID

    PPPIDはPPIDの親プロセスIDです。この場合、ターミナルウィンドウです。

  • <your_command> & disown

    bashシェルでは、disown builtinコマンドを使用して、ジョブテーブルからジョブを削除したり、親シェルが受け取った場合(ユーザーがログアウトした場合)にSIGHUPシグナルが送信されないようにジョブをマークします。

  • awk '{print $4}' "/proc/$PPID/stat"

    ファイルの4番目の列の値を取得します/proc/$PPID/stat(たとえば、/proc/1/stat0を返します)


コマンド$$は端末のpidを取得すると思います...それは代替手段でしょうか?否認する方法も説明できますか?
ティム

このスクリプトはどのようにそれを行いますか?私はまだシェルスクリプトの初心者なので、これらのコマンドを本当に理解することはできません。あなたはそれが、端末を閉じた方法を説明してもらえ
Rumesh

1
@ティムいいえ、それはターミナルでシェルを返します:ps xa | grep $$=> 4381 pts/0 Ss 0:01 /usr/bin/zsh
AB

1
@RumeshSudhaharanスクリプトが開始されたターミナルウィンドウ全体を削除しますが、他のターミナルウィンドウは削除しません。
AB

3
以前に言った@ABは、これは現在のターミナルウィンドウのみを殺し、他のウィンドウは殺さないと言った。今日、2つのターミナルウィンドウを開いた状態でこのスクリプトを使用しましたが、スクリプトを実行すると両方が終了しました。
ルメシュ

4

を使用できます。exec ./your-script

GNOMEターミナルのようなターミナルエミュレータは、その内部で実行されている初期プロセス(通常はシェル)が終了すると終了します。

既にターミナルにいて、そのターミナルを終了する前にしたいことが、特定のスクリプト(またはプログラム)を実行することだけである場合、これは、その中で実行されているシェルがもう必要ないことを意味します。したがって、シェルのexecビルトインを使用して、シェルをコマンドで作成されたプロセスで置き換えることができます。

  • スクリプトの場合、それは別のシェルプロセスです。-なしでスクリプトを実行したときに2番目のシェルプロセスが作成されるのと同じですexec

構文は、たとえばです。exec commandexec ./your-script

exec: 例

たとえば、という名前のシェルスクリプトがありcount、実行可能とマークされ、現在のディレクトリにあるとします。を含む:

#!/usr/bin/env bash
for i in {5..1}; do echo $i; sleep 1; done

そして、ターミナルで、私は実行します:

exec ./count

これは、数字を印刷し5432、及び1、毎秒、その後、ターミナルウィンドウが閉じます。

ターミナルで最初に実行したプロセス以外からこれを実行する場合(たとえば、最初に実行してbash別のシェルインスタンスを起動した場合)、ターミナルを終了するのではなく、そのプロセスを作成したシェルに戻ります。(この警告は、exitベースの方法にも同様に適用されます。)

を使用できます。./your-script; exit

シェルに自分自身を新しいプロセスに置き換えるように指示したくない場合(を介してexec)、そのままにして、新しいプロセスが終了するとすぐに終了するように指示できます。

これを行うには、コマンドとexitコマンド;を1行で指定できるように区切って実行します。

構文はcommand; exit、たとえばです。./your-script; exit

command; exitcommand && exit

あなたは次のようにこのルックスに気づくことで提案方法コスさんheemaylの答えを。違いは次のとおりです。./your-script && exit

  • &&最初のコマンドがゼロの終了コードを返すことによって成功たことを報告した場合にのみ、2番目のコマンドを実行します。
  • ; 最初のコマンドが成功を報告したかどうかに関係なく、2番目のコマンドを実行します。

どちらを使用するかは、特定の状況によって異なります。コマンドが失敗した場合、呼び出しシェル(およびホスト端末)を起動したままにしますか?もしそうなら、使用してください&&。そうでない場合は、を使用します;

ありcommand || exit、呼び出し元のシェルにいる場合にのみ終了しており、command報告された不具合を


2

たとえば、スクリプトを実行する代わりに、ソースにすることができます

$ cat run.sh
exit;
$ ./run.sh #will not close
$ . ./run.sh # will close

1

個人的には、サブシェルでpdfまたは他のファイルを開くコマンドを実行し、ファイルを開くために遅延を置いてから終了します。基本的に、ここに私がテストしたものがあります(nohup gnome-open *.pdf &); sleep 2; exit

これのバリエーションは nohup gnome-open *.pdf && sleep 2 && exit


私の場合、nohupハングアップ信号を無視するのでnohup xdg-open some_program、私のために働いて、exit不必要でした。nohupメッセージをリダイレクトするnohup.outファイル:nohup: ignoring input and appending output to nohup.out
ニックをindiessance

0

最も簡単な解決策は次のとおりです。

xdg-open file.pdf && exit

nohupコマンドを無視SIGHUPするために他の同様のコマンドは必要ありませんが、その理由xdg-openは、pdfファイルを開くのに推奨されるアプリケーションである子プロセスの生成を終了することです。端末から開始された実際のプロセスは強制終了されるnohup必要がないため、必要ありません。

&&前のコマンドが成功した場合、次のコマンドが実行されることを示します。つまり、終了コード0$?=0)を返し、exit単にターミナルを閉じます。


私は彼が出口が...働いていなかったと述べたと思う
ティム・

@Tim:おそらくOPは彼/彼女が入れたのか、私にはその非常に不明瞭な質問から、正しい方法、それを使用していませんでしたexit終わりと仕事をしませんでした...
heemayl

1
@Tim OPがexitスクリプト内に配置されるためbash、親bashインスタンス(ターミナルにリンクされているインスタンス)ではなく、スクリプトが実行されているインスタンスを終了する効果があるため、役に立たず、代わりにターミナルが閉じられます
コス

1
とにかくxdg-open、バックグラウンドで既に実行され、ターミナルからリンクされていないので、nohupここでは必要ありません。さらにxdg-open、スクリプト内でOPが複数回実行され、複数のファイルをバッチオープンxdg-openして、スクリプト内で最初のxdg-open発生で終了するには
コス

@kos:いいえ、私が実行していない午前xdg-open私が持っていた場合でも、backgrにnohup異なるためであるとあなたが親端末を殺す時に殺される元の端末からthere..anyバックグラウンド・プロセスでなければなりません。.. nohupがないようにすることですit..as私は対話的に再びターミナルを使用する必要はありません、また、それぞれを実行することによって防ぐことができ、あなたの第二のポイントbg..onにプロセスを置く必要はありませんxdg-open && exitサブシェルでは...
heemayl

0

タイトルの質問に明示的に回答するには、

「bashスクリプトの実行後にターミナルを終了する」

ターミナルでスクリプトのみを実行します

スクリプトの詳細を見ることなく、シェルを起動せずに、オプション-e--command)を使用して端末内でスクリプトを直接実行できます。シェルの代わりに使用されます。

gnome-terminal -e ./script.sh

スクリプトに引数を提供する場合は、オプション-x--execute)を使用します。これにより、コマンドラインの残り全体がコマンドおよび引数として使用されます。

gnome-terminal -x ./script.sh foo bar

スクリプトが終了した場合、ユーザーの入力を待つことで何かを保持できる対話型シェルはありません。

ターミナルは、実行中のコマンドが終了した直後に終了します。次のように、sleepシェルなしで4秒後に終了します。

gnome-terminal -x sleep 4

もちろん、スクリプトは別のシェルインスタンスを使用しているため、シェルスクリプトを使用することもできます。

また、明示的なスクリプトでシェルを実行できます-インタラクティブではありません:

gnome-terminal -x bash -c "echo 'Hello!'; sleep 4"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.