ls - grep - wc, newlines, and conditional formats
I finally sorted out a minor nuisance that I've noticed periodically over the years. The output of 'ls' seemed to magically work like how I expected when grep'ing or wc'ing the output, but when viewing the output, it shouldn't have worked:
user $ ls f1 f2 f3 # Formatted on a single line user $ ls | grep f1 f1 # As if "f1" was on a line by itself user $ ls | wc -l 3 # wc observes 3 lines, when it should be one
I apparently have (had, hopefully) a blind spot for the source of this problem, because I assumed it was some nuance of my terminal, or maybe parsing. I assumed that what comes out of a standard unix command is not conditional to where it's being sent; which in this case is completely wrong. The answer is clear from the source for gnu coreutils ls (http://git.savannah.gnu.org/):
if (isatty (STDOUT_FILENO)) { format = many_per_line; /* See description of qmark_funny_chars, above. */ qmark_funny_chars = true; } else { format = one_per_line; qmark_funny_chars = false; }
'ls' checks to see if standard out is going to a tty via isatty(), and formats one way, but formats a single entry per line otherwise. A simple c program illustrates this possibility:
#include <unistd.h> #include <stdio.h> int main(){ if( isatty(1) == 1){ printf("Output for tty\n"); } else{ printf("Output\nnot\nfor\ntty\n"); } return 0; }
The results of running said program depend on whether standard out goes to a tty, or not:
user $ ./a.out Output for tty user $ ./a.out | cat Output not for tty
-
November 2015
- Nov 21, 2015 Xen, network-bridge, peth, and VLANs
-
October 2015
- Oct 11, 2015 ls - grep - wc, newlines, and conditional formats
-
July 2015
- Jul 18, 2015 Openstack OverLimit errors during nova boot
-
April 2015
- Apr 18, 2015 Updating user-data for existing Openstack VMs
-
September 2014
- Sep 14, 2014 Tracing DHCP through linux bridges in kvm
-
June 2014
- Jun 14, 2014 Permutations of a binary search tree of height x