受信者に応じて動作が異なるlsコマンド


12

のようなコマンドlsはどのようにその標準出力が何であるかを知っていますか?

lsターゲットstdoutが何であるかによって動作が異なるようです。たとえば、私が行う場合:

ls /home/matt/tmp 

結果は次のとおりです。

a.txt b.txt c.txt

しかし私がするなら

ls /home/matt/tmp | cat

結果は次のとおりです(つまり、結果ごとの改行):

a.txt
b.txt
c.txt

プロセスには、標準出力用のファイル記述子1が渡されますか?結果のフォーマット方法をどのように決定しますか?ファイル記述子は情報を明らかにしますか?


関連unix.stackexchange.com/q/157285/4671unix.stackexchange.com/q/63108/4671、おそらく他の人。話題になったようです。これは、これらのいずれかのだましである可能性があります。
Faheem Mitha、2015

回答:


22

lsプログラムが使用するisatty()FD 1がttyまたは何か他のもの(パイプ、ファイル、等...)であるかどうかを知ります。からman 3 isatty

int isatty(int fd);

DESCRIPTION かどうか機能検査端子に参照するオープンファイルディスクリプタであります
isatty()fd


更新:ls.c coreutilsから1538行目(gitリビジョン43a987e1):

  if (isatty (STDOUT_FILENO))
    {
      format = many_per_line;
      /* See description of qmark_funny_chars, above.  */
      qmark_funny_chars = true;
    }

many_per_line自己記述的でなければなりません。)


8

正確な答えではなく例示です。バッシュスクリプトでは、と同様の効果を得ることができますtest/ [[さん-t

-t FD True if FD is opened on a terminal.

次のように使用します。

bash-4.2$ where() { [[ -t 1 ]] && echo 'my output goes to TTY' || echo 'my output is redirected'; }

bash-4.2$ where
my output goes to TTY

bash-4.2$ where | cat
my output is redirected

bash-4.2$ where > test.file
bash-4.2$ cat test.file
my output is redirected

6

OpenBSD ls(1) マニュアルから:

デフォルトでは、lsは1行に1つのエントリを標準出力にリストします。例外は、端末、または-C、-m、または-xオプションが指定されている場合です。

じゃあ後で:

-1(数字の「1」)。出力を強制的に1行に1エントリにします。これは、出力が端末ではない場合のデフォルトです。

[...]

-C複数列出力を強制します。これは、出力先が端末の場合のデフォルトです。


1

コマンドlsを使用して疑似端末で実行し、scriptの出力lsを別のコマンドにパイプして、stdoutストリームにそのようなパイプがなかったかのように、つまりstdoutが端末(tty)であるかのように同じ出力形式を取得できます。

isatty()StéphaneGimenezによってすでに指摘されている基本的なメカニズムについては、ls.cを参照してください。

ls -G /
ls -G / | cat
script -q /dev/null ls -G / | sed $'s/\r$//g' | cat

# tty | cat
# script -q /dev/null tty | cat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.