xselは、コマンドラインからシステムクリップボードにアクセスできるプログラムです。コピーされたコンテンツの最後に改行がない場合、クリップボードのコンテンツの後に次のような警告が出力されます。
$ xsel -b
copied text
\ No newline at end of selection
以前は、この警告は標準エラーに出力されると思っていましたが、今日では、標準エラーが標準出力とマージされても警告が表示されないことがわかりました。xsel-b |& less
は、警告なしに、コピーされたテキストを印刷するだけです。なぜこのように動作するのですか?
これは、まだリリースされていないバージョンのxsel
でのxsel
の動作であることに注意してください。 この変更 によって2008年に導入されました。
Xの選択には、改行文字で終わらないテキストが含まれるのが一般的です。そのままダンプすると、終了していない行が表示されます。 bash
のような古いシェルでは、表示は次のようになります。
_bash-4.4$ xsel -b
xselbash-4.4$
_
(ここでは、xsel
を含むCLIPBOARD選択を使用しています)。次のプロンプトは、選択内容に追加されることになります。
zsh
やfish
のような最新のシェルは、最後のコマンドの出力が改行で終わっていないことを検出し、視覚的に表示することを回避します。
zsh
の場合:
_Prompt% xsel -p
xsel%
Prompt%
_
(xsel
の後のリバースビデオ_%
_は、改行が欠落していることを示しています)。
fish
の場合:
_Prompt ~> xsel -p
x⏎
Prompt ~>
_
これらの新しいxsel
は、視覚的な表示を提供します。
_bash-4.4$ xsel -b
xsel
\ No newline at end of selection
bash-4.4$
_
これは、xselが古いインタラクティブシェルのプロンプトで実行されている場合にのみ役立ちます。
特に、「改行なし」の表示は、次のように使用する場合は望ましくありません。
_selection=$(xsel -b)
_
(ここで、xsel
のstdoutはパイプです)または:
_xsel -b > selection.txt
_
(ここで、xsel
のstdoutは通常のファイルです)。
そのため、xsel
は、stdoutがttyデバイスに送信された場合にのみその指示を出力します。
さて、どこに表示されますか?まあ、意図はそのttyデバイスにそれを表示することです。 straceで実行すると、次のように表示されます。
_$ strace -e write ./xsel -b
write(1, "xsel", 4xsel) = 4
write(2, "\n\\ No newline at end of selectio"..., 34
\ No newline at end of selection
) = 34
+++ exited with 0 +++
_
これは確認します ソース :それはstderrに出力されます。そして、stdoutがターミナルではない場合:
_$ strace -e write ./xsel -b > /dev/null
write(1, "$ strace -e write ./xsel -b | ca"..., 104) = 104
+++ exited with 0 +++
_
全く出力されません。通知を端末に出力することが目的の場合、stderrに出力するのは少しばかげていると主張するかもしれません(stderrはたとえば_xsel -b 2> logfile
_のようにログファイルにリダイレクトできます)が、次のようになります。
xsel -b 2> /dev/null
_よりも効率的な_xsel -b | cat
_の端末で実行すると、その通知を無効にできます。isatty()
は、端末に接続されていないシリアルデバイスに対してtrueを返します。それはテストするのに十分簡単です:
xsel -b > xsel.out 2> xsel.err
メッセージは2つのファイルのいずれかにあります。 xsel.out
にある場合、メッセージは標準出力を介して送信されます。他のファイルにある場合は、標準エラーによるものです。それが隣にある場合は、非常に奇妙なことが起こっているので、カーネルと長く真剣に話し合う必要があります。