2つの異なる方法でEmacsを開くスクリプト

2つの異なる方法でEmacsを開くスクリプト

基本的にEmacsを開く小さなスクリプトを書いてみました。

emacs -nw foo

ただ入力してください

emacs foo

ウィンドウにタイピングしたいとき

emacs foo &

私が書きたいスクリプトは次のとおりです。

#!/bin/bash

if [ -z $2 ]; then
    emacs -nw $1
else
    emacs $1 &
fi

私が経験している問題は、スクリプトを実行しようとしたときに何も起こらないことです。まるでEnterキーを押したのと同じです。

経験豊富な人がこのスクリプトを正しく作成する方法を提案できますか?

答え1

このスクリプトの問題は、どちらを呼び出すと(含まれていなくても)、引数が&1つだけ表示されることです。bashすでに&プロセスをバックグラウンドに置くために使用されています。fg起動して試してみると、emacs foo &最初のオプションと同様に、emacsにウィンドウがないことがわかります。

2番目のオプションは決して実行されず、実行しないでください&。必要なのは、スクリプトがバックグラウンドで実行されているかどうかをテストして決定を下すことです。プログラムやPythonでは、Cプログラムグループとターミナルフォアグラウンドプロセスグループが同じかどうかをテストしますが、 bashシェルでこれを行う方法がわかりません(Chris Downの答えはこれができることを示唆しています)。

あなたの呼び出しはこのスクリプトを呼び出すことを強く示唆しています。emacsこの場合、再帰を防ぐために「実際の」emacsへのフルパスを入力する必要があります。

Pythonスクリプトを使用してタスクを実行できる場合:

import os
import sys
import subprocess

STDOUT_FILENO=1
emacs_cmd = ['/usr/bin/emacs']

if os.getpgrp() == os.tcgetpgrp(STDOUT_FILENO):
    emacs_cmd.append('-nw')
emacs_cmd.extend(sys.argv[1:])
subprocess.call(emacs_cmd)

コマンドラインで複数のファイル名(およびその他のemacsオプション)を指定できます。

答え2

Anthonが言ったように、&これはコマンドの引数ではなく、シェル構文の一部です(プロセスの背景です)。以下は、現在のスクリプトが端末のフォアグラウンドプロセスグループ(またはバックグラウンドプロセスの場合はfalse)の一部であるかどうかをテストするスクリプトです。

#!/bin/bash

# If the STAT column does not end with a plus, this process is not part
# of the terminal's foreground process group (and is backgrounded).

case "$(ps -o stat= -p $$)" in
    *+) exec emacs "$@"  ;;
    *) exec emacs -nw "$@" ;;
esac

関連情報