두 가지 다른 방법으로 Emacs를 여는 스크립트

두 가지 다른 방법으로 Emacs를 여는 스크립트

기본적으로 Emacs를 여는 작은 스크립트를 작성해 보았습니다.

emacs -nw foo

그냥 입력하세요

emacs foo

창에 타이핑을 하고 싶을 때

emacs foo &

내가 작성하려는 스크립트는 다음과 같습니다.

#!/bin/bash

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

내가 겪고 있는 문제는 스크립트를 실행하려고 할 때 아무 일도 일어나지 않는다는 것입니다. 마치 Enter 키를 누른 것과 같습니다.

경험이 있는 사람이 이 스크립트를 올바르게 만드는 방법을 제안해 줄 수 있습니까?

답변1

이 스크립트의 문제점은 어느 쪽이든(포함하거나 포함하지 않고) 호출하면 &인수가 하나만 표시된다는 것입니다. bash이미 &프로세스를 백그라운드에 두는 데 사용되었습니다. fg시작한 후 시도해 보면 emacs foo &첫 번째 옵션과 마찬가지로 emacs에 창이 없는 것을 볼 수 있습니다.

두 번째 옵션은 절대 실행되지 않으며 실행되어서는 안 됩니다 &. 필요한 것은 스크립트가 백그라운드에서 실행 중인지 테스트하고 결정을 내리는 것입니다. 프로그램이나 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

관련 정보