登录时启动 Emacs 时出现“emacs: 标准输入不是 tty”

Har*_*ton 5 shell emacs

我有 Fedora 20 和 Gnome3 classic,我正在尝试使用 CTRL/ALT/Fn 终端窗口。当我想使用 emacs 编辑文件时,我使用以下脚本,以便自动显示我的提示文件,并且 emacs 作为后台作业运行。这在 Gnome 桌面应用程序的非登录终端中工作正常,但在登录终端中我收到错误消息:(通过在 CTL/ALT/F2 窗口中使用“&> e”重定向获得)

    home/Harry/bin/emx: line 4: t: Permission denied  
    +---------------------------------------------------+  
    | EmacsHints.txt found and displayed                |  
    | Usage: ./emx <filename> ..                        |  
    |   .. Opens EmacsHints.txt and <filename> in emacs |  
    +---------------------------------------------------+
    emacs: standard input is not a tty
Run Code Online (Sandbox Code Playgroud)

请有人解释一下这些,并告诉我如何避免它们并在登录和非登录终端中成功使用 emx 脚本(无疑已修改)?

我的 emx 脚本的修订版本,包括我的笔记和调试内容:

#!/bin/sh
emxhn="EmacsHints.txt"
emxhf="/home/Harry/emacs/$emxhn"
ps aux | grep $emxhn > t
T=`wc -l t` # no spaces allowed between T and = and value
# echo $T
wc -l t > t1
T=`awk '$1' t1`
# echo $T

echo "+---------------------------------------------------+"

# In the test "" needed round $T else it is split into two commands ..
# .. so are the spaces after [ and before ]
# could be if ( [...] ) then or if [...] ; then 
if [ "$T" = "2 t" ]; then 
#  echo "+----------------------------------------------+"
 echo "| $emxhn already present"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  "|"
else
 emacs $emxhf &
 echo "| $emxhn found and displayed"\ \ \ \ \ \ \ \ \ \ \ \ \ \ \  "|"
fi

if [ "$#" = "1" ]; then
 emacs $1 &
else
 echo "| Usage: ./emx <filename> .." \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  "|"
 echo "|" \   ".. Opens $emxhn and <filename> in emacs" "|"
fi

  echo "+---------------------------------------------------+"
Run Code Online (Sandbox Code Playgroud)

是的,我明白了,我陷入了 XY 陷阱,在我应该问 Y 的时候问 X,所以这里是 Y

我经常使用 emacs,但不是一直使用,而且我还有一个提示文件,在其中我记录了如何完成我遇到的任务,并且我喜欢在使用 emacs 时提供这些提示。我尝试自动执行此操作,以便每当我启动 emacs 时,如果提示尚不存在,则也会打开该文件。该脚本是我尝试这样做的,当我在我的 Gnome3 经典风格 GUI 中从非登录终端运行 emacs 时,它一直没问题。使用 CTL/ALT/F2 在登录终端中尝试它会给出引用的错误消息。

我多年来一直使用并喜爱 Unix 和 Fedora Linux,但显然还有很多东西需要学习。

Gil*_*il' 4

下面,我分析一下你的脚本。但完成此操作后,我认为您应该问的问题的答案是:

\n\n
    \n
  • emacs --daemon你的.profile. 这将创建一个 Emacs 的后台实例。
  • \n
  • 运行emacsclient FILENAME以在 Emacs 中打开文件。这将创建一个新窗口(X11 窗口或使用当前终端的窗口)。
  • \n
  • EmacsHints文件加载到 Emacs 启动文件中:(find-file "/home/Harry/emacs/EmacsHints.txt").emacs.
  • \n
\n\n
\n\n

我们无法确定您为什么会收到t: Permission denied,因为您没有发布生成此错误的脚本(您发布的脚本在第 4 行有注释)。但是您正在当前目录中创建一个临时文件;在所有情况下这都是一个坏主意,并且当您没有写入当前目录的权限时可能不起作用。

\n\n

如果需要创建临时文件,请使用mktemp. 然而,在这里,临时文件是不必要的复杂化:使用命令替换将命令的输出存储到变量中。

\n\n
#!/bin/sh\nps_lines=$(ps aux | grep EmacsHints)\nline_count=$(echo "$ps_lines" | wc -l)\nT=$(echo "$line_count" | awk \'$1\')\nif [ "$T" = "2" ]; then \xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n\n

所有这些又都非常复杂 \xe2\x80\x94\xc2\xa0 只是将输出通过管道传输grepwc,并且 awk 步骤没有做任何有用的事情。

\n\n
if [ "$(ps aux | grep EmacsHints | wc -l)" = 2 ]; then \xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n\n

此外,您的测试是不可靠的:当EmacsHints文件打开时,有时ps会返回一行包含,有时会返回两行:这取决于和进程EmacsHints的时间。不要构建自己的(这不起作用),而是使用专用于此目的的工具:或。psgreppidofpgrep

\n\n
#!/bin/sh\nif pgrep -f \'EmacsHints\\.txt\' >/dev/null; then \xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n\n

瞧\xc3\xa0!更简单,而且确实有效。

\n\n

嗯,它大部分都有效。如果您EmacsHints在 Emacs 中打开该文件而不在命令行中指定它,则不会检测到该文件。我会提供更好的解决方案,但我不明白你想要完成什么。如果您始终希望EmacsHints在 Emacs 中打开该文件,请从.emacs.

\n\n

Emacs 启动有点慢,但许多用户(包括我)将其设置为在登录时运行,然后永远不会退出。从emacs --daemon你的.profile. 要在现有 Emacs 实例中打开文件,请调用emacsclient.

\n\n

关于 \xe2\x80\x9c 标准输入不是 tty\xe2\x80\x9d,只有当 Emacs 打开 GUI 窗口时,你才能在后台运行 Emacs。如果您在终端中运行 Emacs,它必须位于前台,否则它无法访问终端。如果您只想在 X 中在后台运行 Emacs:

\n\n
if [ -n "$DISPLAY" ]; then\n  emacs "$1" &\nelse\n  emacs "$1"\nfi\n
Run Code Online (Sandbox Code Playgroud)\n\n

顺便说一句,在 shell 脚本中,始终在变量和命令替换两边加上双引号:"$1""$foo""$(somecommand)"等。当替换不在双引号内时,该值不会解释为字符串,而是解释为全局模式列表。此问题通常表现为脚本在包含空格的文件名上失败。如果您不明白这一切意味着什么,只需使用双引号即可。

\n\n

或者你可以只使用emacsclient.

\n