我有 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
請有人解釋一下這些,並告訴我如何避免它們並在登入和非登入終端機中成功使用 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 "+---------------------------------------------------+"
是的,我明白了,我陷入了 XY 陷阱,在我應該問 Y 的時候問 X,所以這裡是 Y
我經常使用 emacs,但不是一直使用,而且我還有一個提示文件,在其中我記錄瞭如何完成我遇到的任務,並且我喜歡在使用 emacs 時提供這些提示。我嘗試自動執行此操作,以便每當我啟動 emacs 時,如果提示尚不存在,則也會開啟該檔案。該腳本是我嘗試這樣做的,當我在我的 Gnome3 經典風格 GUI 中從非登入終端運行 emacs 時,它一直沒問題。使用 CTL/ALT/F2 在登入終端中嘗試它會給出引用的錯誤訊息。
我多年來一直使用並喜愛 Unix 和 Fedora Linux,但顯然還有很多東西要學習。
答案1
下面,我分析一下你的腳本。但這樣做之後,我認為答案是你應該問的問題是:
- 從
emacs --daemon
你的.profile
.這將建立一個 Emacs 的後台實例。 - 運行
emacsclient FILENAME
以在 Emacs 中開啟檔案。這將建立一個新視窗(X11 視窗或使用目前終端的視窗)。 - 將檔案載入
EmacsHints
到 Emacs 啟動檔案:(find-file "/home/Harry/emacs/EmacsHints.txt")
將.emacs
.
我們無法確定您為什麼會收到t: Permission denied
,因為您沒有發布產生此錯誤的腳本(您發布的腳本在第 4 行有註釋)。但是您正在當前目錄中建立一個臨時檔案;在所有情況下這都是一個壞主意,並且當您沒有寫入當前目錄的權限時可能不起作用。
如果需要建立臨時文件,請使用mktemp
。然而,在這裡,臨時檔案是不必要的複雜化:使用命令替換將命令的輸出儲存到變數中。
#!/bin/sh
ps_lines=$(ps aux | grep EmacsHints)
line_count=$(echo "$ps_lines" | wc -l)
T=$(echo "$line_count" | awk '$1')
if [ "$T" = "2" ]; then …
所有這些都非常複雜——只需將grep
into的輸出通過管道傳輸wc
,而 awk 步驟沒有做任何有用的事情。
if [ "$(ps aux | grep EmacsHints | wc -l)" = 2 ]; then …
此外,您的測試是不可靠的:當檔案EmacsHints
開啟時,有時ps
會傳回一行包含,有時會傳回兩行:這取決於和進程EmacsHints
的時間。不要建立自己的(這不起作用),而是使用專門用於此目的的工具:ps
grep
pidof
或者pgrep
。
#!/bin/sh
if pgrep -f 'EmacsHints\.txt' >/dev/null; then …
瞧!更簡單,而且確實有效。
嗯,它大多作品。如果您EmacsHints
在 Emacs 中開啟該檔案而不在命令列中指定它,則不會偵測到該檔案。我會提供更好的解決方案,但我不明白你想要完成什麼。如果您始終希望EmacsHints
在 Emacs 中開啟該文件,請從.emacs
.
Emacs 啟動有點慢,但許多用戶(包括我)將其設定為在登入時運行,然後永遠不會退出。從emacs --daemon
你的.profile
.若要在現有 Emacs 實例中開啟文件,請呼叫emacsclient
.
關於“標準輸入不是 tty”,只有在開啟 GUI 視窗時,您才能在背景執行 Emacs。如果您在終端機中執行 Emacs,它必須位於前台,否則無法存取終端。如果您只想在 X 中在背景執行 Emacs:
if [ -n "$DISPLAY" ]; then
emacs "$1" &
else
emacs "$1"
fi
順便說一句,在 shell 腳本中,始終在變數和命令替換周圍放置雙引號:"$1"
、"$foo"
、"$(somecommand)"
等。此問題通常表現為腳本在包含空格的檔案名稱上失敗。如果您不明白這一切意味著什麼,只需使用雙引號即可。
或者你可以只使用emacsclient
.
答案2
關於此消息:
emx: line 4: t: permission denied
第一個是告訴你你的命令:
ps aux | grep EmacsHints > t
沒有權限將檔案寫入t
執行時所在的任何目錄。最好指定完整路徑,我建議/tmp/t
像這樣使用:
ps aux | grep EmacsHints > /tmp/t
另一則訊息:
emacs: standard input is not a tty
告訴您該腳本無法存取 TTY 來顯示 emacs。為了以這種方式運行諸如emacs
或 之類的工具vim
,您通常需要存取 TTY 設備,以便可以存取其 STDIN 和 STDOUT。
如果您絕望或不關心缺少 STDIN/STDOUT,您可以在腳本中建立一個新的,如下所示:
emacs < $(tty) > $(tty)
還有其他方法可以解決這個問題,請參閱標題為這樣的問答:如何從 shell 腳本啟動編輯器?。