私は Fedora 20 と Gnome3 classic を使っていて、CTRL/ALT/Fn ターミナル ウィンドウを使用しようとしています。emacs でファイルを編集したいときは、次のスクリプトを使用して、Hints ファイルが自動的に表示され、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
。
このエラーを生成したスクリプトを投稿していないため (投稿したスクリプトの 4 行目にコメントがあります) 、なぜエラーが発生するのかはわかりませんt: Permission denied
。ただし、現在のディレクトリに一時ファイルを作成しています。これはどのような状況でも悪い考えであり、現在のディレクトリへの書き込み権限がない場合はおそらく機能しません。
一時ファイルを作成する必要がある場合は、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
にパイプするだけでwc
、 awk ステップは何も役に立ちません。
if [ "$(ps aux | grep EmacsHints | wc -l)" = 2 ]; then …
さらに、テストは信頼性に欠けます。EmacsHints
ファイルが開いているときに、ps
が 1 行の を返す場合もあれば、 2 行の を返す場合もあります。これは、およびプロセスEmacsHints
のタイミングに依存します。独自のテストを作成する代わりに (動作しません)、この目的専用のツールを使用します。ps
grep
pidof
またはpgrep
。
#!/bin/sh
if pgrep -f 'EmacsHints\.txt' >/dev/null; then …
ほら!もっとシンプルに、そして実際に機能します。
まあ、それはたいてい動作します。コマンドラインで指定せずに Emacs でファイルを開くとEmacsHints
、これは検出されません。もっと良い解決策を提案したいのですが、何を達成しようとしているのかわかりません。常にEmacsHints
Emacs でファイルを開きたい場合は、 から開いてください.emacs
。
Emacs の起動は少々遅いですが、多くのユーザー (私を含む) は、ログイン時に実行され、その後は終了しないように設定しています。emacs --daemon
から実行します.profile
。既存の Emacs インスタンスでファイルを開くには、 を呼び出しますemacsclient
。
「標準入力は tty ではない」という点については、Emacs をバックグラウンドで実行できるのは、GUI ウィンドウを開いている場合のみです。Emacs をターミナルで実行している場合は、フォアグラウンドで実行する必要があります。そうしないと、ターミナルにアクセスできません。X でのみ Emacs をバックグラウンドで実行したい場合は、次の手順に従ってください。
if [ -n "$DISPLAY" ]; then
emacs "$1" &
else
emacs "$1"
fi
ちなみに、シェル スクリプトでは、変数とコマンドの置換を常に二重引用符で囲みます: "$1"
、、など。置換が二重引用符で囲まれていない場合、値は文字列としてではなく、glob パターンのリストとして解釈されます。この問題は、通常、スペースを含むファイル名で失敗するスクリプト"$foo"
で"$(somecommand)"
発生します。それが何を意味するのか理解できない場合は、二重引用符を使用してください。
または、 を使用することもできますemacsclient
。
答え2
このメッセージに関して:
emx: line 4: t: permission denied
1 つ目は、コマンドが次のことを伝えているということです。
ps aux | grep EmacsHints > t
t
実行時にそのディレクトリにファイルを書き込む権限がありません。完全なパスを指定する方がよいので、/tmp/t
次のように使用することをお勧めします。
ps aux | grep EmacsHints > /tmp/t
もう一つのメッセージ:
emacs: standard input is not a tty
スクリプトが emacs を表示するための TTY にアクセスできないことを示しています。 または などのツールをemacs
このvim
ように実行するには、多くの場合、STDIN と STDOUT にアクセスできるように TTY デバイスにアクセスする必要があります。
どうしても必要な場合、または STDIN/STDOUT がなくても構わない場合は、次のようにスクリプト内に新しいものを作成できます。
emacs < $(tty) > $(tty)
これに対処する方法は他にもあります。次のタイトルの SO Q&A を参照してください。シェル スクリプトからエディターを起動するにはどうすればよいですか?。