我尝试编写一个小脚本,默认情况下会使用以下命令打开 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