ls コマンドの動作は受信者によって異なります。

ls コマンドの動作は受信者によって異なります。

このようなコマンドは、標準出力がls何であるかをどうやって知ることができますか?

lsターゲット標準出力によって動作が異なるようです。たとえば、これを行うと:

ls /home/matt/tmp 

結果:

a.txt b.txt c.txt

しかし、もし私がそうするなら

ls /home/matt/tmp | cat

結果は次のとおりです(つまり、各結果は新しい行を置き換えます)。

a.txt
b.txt
c.txt

プロセスには、stdoutのファイル記述子1が渡されます。そうですか?結果の書式設定方法はどのように決定されますか?ファイル記述子は情報を漏洩していますか?

答え1

このプログラムは、fd 1がttyか他のもの(パイプ、ファイルなど...)であるかを判断するlsために使用されます。isatty()からman 3 isatty

int isatty(int fd);

説明
このisatty()関数は、fd開かれたファイル記述子が端末を参照するかどうかをテストします。


修正する:coreutilsの行1538 ls.c(gitリビジョン43a987e1):

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

many_per_line自己説明が必要です。)

答え2

正確な答えではありませんが、例です。 Bashスクリプトでは、test/ achievを使用して同様の[[効果を得ることができます-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

答え3

OpenBSDからls(1) 手動:

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

それから後で:

-1(数字「1」。)出力は1行に1つの項目に強制されます。出力が端末に進まないときのデフォルト値です。

[...]

-C は複数列出力を強制します。これは端末に出力するときのデフォルト値です。

答え4

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

isatty()Stéphane Gimenezがすでに指摘している基本的なメカニズムについては、以下を参照してください。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

関連情報