シェルを起動したときにプログラムが実行中かどうかを判断し、まだ実行されていない場合はそのプログラムを起動するにはどうすればよいでしょうか?

シェルを起動したときにプログラムが実行中かどうかを判断し、まだ実行されていない場合はそのプログラムを起動するにはどうすればよいでしょうか?

シェル (私の場合は bash や zsh) を起動するときに、プログラムがすでに実行されているかどうかを確認し、プログラムがまだ実行されていない場合はそれを起動するために、.zshrc や .bashrc にどの行を追加する必要がありますか?

例: 新しい zsh シェルを起動します。top がまだ実行されていない場合は、top を起動してシェルを引き継ぐようにします。top が別のウィンドウですでに実行されている場合は、.zshrc の読み込みを続行して、ターミナルを開くようにします。

6-16 アップデート:

if ! pgrep -U $USER top >/dev/null; then
exec top
fi

上記のスクリプトは私の要求を満たしています。-q フラグは私のシステムではオプションではないため機能しません。そのため、PID を /dev/null にパイプする必要がありました。mveroone、Kusalananda、Thomas Dickey に感謝します。

元の質問の範囲外ですが、機能の追加についていくつか質問があります。パスワードを入力しなくても root になれるシングル ユーザー システムにいるとします。必要な場合、root として top を自動実行するにはどうすればよいでしょうか。

6-18 ルートとしてコマンドを渡すという機能拡張の問題は解決しました。私はこれを使っていくつかの

皆様の丁寧なご返信に感謝いたします。

答え1

次のように使用しますpgrep

if ! pgrep -u $USER top >/dev/null 2>&1; then
    exec top
fi

説明:

  • コマンドが実行中であることが確認された場合、ユーティリティpgrepは終了コード 0 で終了します。したがって、テストを否定します。
  • また、 を使って現在のユーザーのみに制限し-u $USER、何らかの理由で他のユーザーのプロセスを取得しないようにします。$USERは標準のシェル変数です。何らかの理由でそれが定義されていない場合は、$LOGNAME代わりに を使用してみてください。それが失敗した場合は、 を使用してください$( id -n -u )(ただし、その時点で何が起こっているのか自問する必要があります。$LOGNAMEまた標準のシェル変数)。
  • からの出力は必要ないpgrepので、標準出力とエラー ストリームを にリダイレクトします/dev/null

top(または何か)が実行されていないことが判明した場合は、 execOP の質問に従って、シェルを置き換えます。

これは、すべての互換シェルで動作するはずですsh

編集: pgrepBSD システム (OS X、OpenBSD、...) の実装には、-q出力をすべて破棄するオプションがありますが、pgrepLinux の にはこのフラグがないようです。BSD システムでは、 への少々見苦しいリダイレクトではなく、こちらを使用してください/dev/null

答え2

プログラムが常にシェルから起動され、完全な制御権を持っている場合(つまり、サードパーティのプログラム内にハードコードされていない場合)、またはのようなロックメカニズムを使用できますlockfileflockたとえば、

flock -n /tmp/top -c top

.bashrc/にすると、.zshrcシェルの最初のインスタンスのみがコマンドを実行するようになりますtop(それを強制終了しない限り、別のインスタンスが開始されます)。

シェルの初期化時だけでなく、手動でもコマンドを開始できるように関数を作成することもできます。

mytop () { flock -n /tmp/$0 -c top; }

mytopそして、いつでも好きなときに走ってください。

答え3

それがpgrep正しい方法であることには同意しますが、落とし穴がいくつかあります。-qの出力をリダイレクトしてpgrepそれを排除できるため、 オプションを使用する必要はありません。

pgrep -U $USER top >/dev/null || exec top

落とし穴は、これが標準ユーティリティではないという事実にあります。したがって、移植性がない可能性があることを念頭に置く必要があります。役立つマニュアル ページ リンクをいくつか示します。

環境USER変数はより確立されていますが、シェルのPOSIXのリストには含まれていないようです(2.5.3 シェル変数)。むしろ、USER使用されていることが知られている多くの変数のうちの1つであると指摘しています(8.1 環境変数の定義)。

これはtop次のように実行されますあなた自身もちろんです。$USERを に変更しroot、(推奨)またはのtopいずれかを使用して実行することができます。どちらも POSIX には存在しません(sudosuリストを見る)。後者(su)はUnix系システムではどこでも利用可能ですが、sudo一般的にはこちらが好まれます。つまり、

pgrep -U root top >/dev/null || exec sudo top

パスワードを必要としないように設定していない限りsudo、シェルの起動時にパスワードの入力を求められますtop

答え4

次のようなスニペットを .zshrc (またはその他) に追加します。

pgrep -u $USER プログラム名
それから
    プログラム名を実行
フィ

警告 :このコードはテストしていません。ルートまたはサーバー上の唯一のユーザーでは使用しないでください。失敗した場合に回復できることを確認してください。

関連情報