以两种不同方式打开 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 没有窗口,与第一个选项一样。

第二个选项永远不会被执行,并且它不应该有&.需要的是脚本测试它是否在后台运行并做出决定。在C程序或Python中我会测试程序组和终端前台进程组是否相同,但是 不知道如何在 bash shell 中做到这一点(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 所说,&不是命令的参数,它是 shell 语法的一部分(它是进程的后台)。这是一个脚本,可以测试当前脚本是否是终端前台进程组的一部分(如果是后台进程,则为 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

相关内容