It calls the isatty() libc function on its stdout file descriptor to determine whether the output goes to a terminal or not.

Internally, isatty() attempts to use one of the ioctl() calls that are specific to tty devices – most likely ioctl(TCGETS) (which retrieves the generic tty settings that the stty command shows); if it succeeds, then the file is a tty device.

$ python
>>> sys.stdout.isatty()
True

This affects both whether ls will columnate its output by default, and whether it will use colors by default, and some other things such as whether file names will be quoted.

If stdout is indeed a terminal, then ls uses another tty-specific ioctl(TIOCGWINSZ) to retrieve its dimensions (which on modern systems have been stored there by the terminal emulator) to find out how many columns it can fit. The stty size command also gets those; try running it under strace.

Full-screen programs additionally react to the SIGWINCH signal which the kernel sends every time the terminal emulator updates the dimensions of the tty, as an indication that they need to redraw everything in the new size.

Answer from grawity on Stack Exchange
🌐
LinuxQuestions.org
linuxquestions.org › questions › linux-newbie-8 › ls-output-interpretation-907297-print
LinuxQuestions.org - [SOLVED] ls output interpretation
October 9, 2011 - - - ls output interpretation (https://www.linuxquestions.org/questions/linux-newbie-8/ls-output-interpretation-907297/)
Top answer
1 of 2
31

It calls the isatty() libc function on its stdout file descriptor to determine whether the output goes to a terminal or not.

Internally, isatty() attempts to use one of the ioctl() calls that are specific to tty devices – most likely ioctl(TCGETS) (which retrieves the generic tty settings that the stty command shows); if it succeeds, then the file is a tty device.

$ python
>>> sys.stdout.isatty()
True

This affects both whether ls will columnate its output by default, and whether it will use colors by default, and some other things such as whether file names will be quoted.

If stdout is indeed a terminal, then ls uses another tty-specific ioctl(TIOCGWINSZ) to retrieve its dimensions (which on modern systems have been stored there by the terminal emulator) to find out how many columns it can fit. The stty size command also gets those; try running it under strace.

Full-screen programs additionally react to the SIGWINCH signal which the kernel sends every time the terminal emulator updates the dimensions of the tty, as an indication that they need to redraw everything in the new size.

2 of 2
10

For a less technical explanation, observe what happens when you try these two commands:

$ ls
update.sh   web.config   MyApp.runtimeconfig.json

$ ls | cat
update.sh
web.config
MyApp.runtimeconfig.json

Piping through cat "does nothing", except that ls "notices" that it's output is being piped somewhere. So it changes its behavior accordingly.

Once you understand what ls is outputting, it's straightforward what happens when it passes through head -n1.

🌐
Oracle
forums.oracle.com › ords › apexds › post › ls-command-7232
ls command
June 11, 2019 - Hi, what do show the numbers in second column of the out put please: Thanks.
Top answer
1 of 3
8

It's because * doesn't match files starting with a . by default. Consider the following directory:

$ ls -la 
total 8404
drwxrwxrwx   2 terdon terdon 8105984 Dec 31 13:14 .
drwxr-xr-x 153 terdon terdon  491520 Dec 30 22:32 ..
-rw-r--r--   1 terdon terdon       0 Dec 31 13:14 .dotfile
-rw-r--r--   1 terdon terdon       0 Dec 31 13:14 file1
-rw-r--r--   1 terdon terdon       0 Dec 31 13:14 file2
-rw-r--r--   1 terdon terdon       0 Dec 31 13:14 file3.

Let's see what each of the globs you used expands to:

$ echo .*
. .. .dotfile

$ echo *.
file3.

$ echo *
file1 file2 file3.

As you can see, the * does not include files or directories starting with . so both ./ and ../ are ignored. The same thing happens with your ls example. In bash, you can change this with the dotglob parameter, which will cause * to expand to dotfiles as well (but not to . or .., those are still ignored):

$ shopt -s dotglob
$ echo *
.dotfile

Other shells behave differently. For example zsh also ignores the . and .. when using .*:

% echo .*
.dotfile
2 of 3
5

The rule for filename expansion have a special case for . as the first character in a filename: it must be explicitly matched (i.e. the pattern must contain a starting ., or . after a /). Otherwise these files are not candidates.

This is why your first version does pick up filenames that start with ., but the second doesn't. * doesn't match . as the first character of a filename.

POSIX Shell Command Language describes it as:

If a filename begins with a period ( '.' ), the period shall be explicitly matched by using a period as the first character of the pattern or immediately following a slash character. The leading period shall not be matched by:

  • The asterisk or question-mark special characters
  • A bracket expression containing a non-matching list, such as "[!a]", a range expression, such as "[%-0]", or a character class expression, such as "[[:punct:]]"

It is unspecified whether an explicit period in a bracket expression matching list, such as "[.abc]", can match a leading period in a filename.

Your shell might have options to change this behavior. Bash has this for instance (Filename expansion):

When a pattern is used for filename expansion, the character ‘.’ at the start of a filename or immediately following a slash must be matched explicitly, unless the shell option dotglob is set. When matching a file name, the slash character must always be matched explicitly. In other cases, the ‘.’ character is not treated specially.


Note that these are not regular expressions. .* as a regex would match anything at all (including nothing). *. would be ill-formed.

🌐
LXer
lxer.com › module › newswire › view › 341532 › index.html
LXer: Understanding the ls Command with a Long Listing Format Output and Permission Bits
DaniWeb Linux Community An exciting professional discussion group about software development, php, shell scripting, networking, ruby, and more.
Top answer
1 of 5
1

You've changed your script to use Model=Report and ${Model} and you've said you have typeset -u Model in your script. The -u option to the typeset command (instead of declare — they're synonyms) means "convert the strings assigned to all upper-case".

-u When the variable is assigned a value, all lower-case characters are converted to upper-case. The lower-case attribute is disabled.

That explains the upper-case REPORT in the variable expansion. You can demonstrate by writing:

Model=Report
echo "Model=[${Model}]"

It would echo Model=[REPORT] because of the typeset -u Model.

  • Don't use the -u option if you don't want it.

You should probably fix your glob expression too:

file={Model}_execution_*${DATE}*.pdf)

Using $(…) instead of backticks is generally a good idea.

And, as a general point, learn how to Debug a Bash Script and always provide an MCVE (How to create a Minimal, Complete, and Verifiable Example?) so that we can see what your problem is more easily.

2 of 5
0

Some things to look at:

  • type is usually a reserved word, though it won't break your script, I suggest you to change that variable name to something else.
  • You are missing an $ before {DATE}, and you have an extra _ after it. If the date is the last part of the name, then there's no point in having an * at the end either. The file definition should be:

file=`ls ${type}_execution_*${DATE}.pdf`

Try debugging your code by parts: instead of doing an ls, do an echo of each variable, see what comes out, and trace the problem back to its origin.

As @DevSolar pointed out you may have problems parsing the output of ls.

🌐
Caltechlibrary
caltechlibrary.github.io › shell-novice › reference
The Unix Shell: Summary of Basic Commands
November 9, 2018 - A description that specifies the location of a file or directory within a file system. See also: absolute path, relative path. ... A connection from the output of one program to the input of another.
Top answer
1 of 1
4

What you see is what you get, really. Everything that was printed after running ls was printed by the 'ls' command itself – there was no intermediate return value that had to be reformatted.

Shell commands aren't exactly like functions in programming languages – they cannot return anything but a single integer: the "exit status". Most shells allow inspecting this value through the $? variable. (The convention is to return 0 on success; 1 or greater on failure.)

So literally all output you're seeing is produced not through a return value, but by writing ordinary text to the special files called "stdout" and "stderr" during the execution of the command (the former is meant for regular output, the latter for notices and error messages).

Of course, inside the 'ls' program you would find calls to libc functions such as readdir() which returns a struct dirent, or stat() which returns a struct stat. However, none of those are returned to the outside world.

So can you use the output of 'ls'? In a sense yes, in fact much of the traditional "Unix" user interface is built upon the idea using one program's output as another program's input – that's what the | pipe operator is for. However, keep in mind that the 'ls' output is specifically formatted for human consumption and is not easily machine-parseable. In other words, you shouldn't use the output of 'ls' in scripts even if you can.

(Piping works best when the initial program was actually written to produce somewhat structured output. For this reason, many tools can actually be run with options to output either pretty formatted text or machine-parseable text. Compare lsblk vs lsblk --raw vs lsblk --json.)


There are exceptions – there have been shells which attempt to support flexible return types, but PowerShell is the only widely known example. PowerShell cmdlets can return arbitrary .NET Runtime types.

Find elsewhere
🌐
MathWorks
mathworks.com › matlab › programming › files and folders › file operations
ls - List folder contents - MATLAB
Microsoft® Windows® platforms – list is an m-by-n character array of names. m is the number of names and n is the number of characters in the longest name. MATLAB® pads names shorter than n characters with space characters. To further modify the results of the ls command on UNIX platforms, you can add any flags that the operating system supports. For example, ls -c displays files by timestamp and ls -d displays only directories. For more information, see the UNIX ls documentation. Use the dir command to return file attributes for each file and folder in the output argument.
🌐
High Performance Computing
hpc.ncsu.edu › Documents › unixtut › unix1.html
Linux Tutorial One
When you first login, your current working directory is your home directory. Your home directory has the same name as your user-name, for example, unityid, and it is where your personal files and subdirectories are saved. ... The ls command lists the contents of your current working directory.
🌐
Medium
medium.com › @bigjoshcodes › a-beginners-guide-to-understanding-what-happens-when-you-type-ls-c-in-bash-4a8642414b6
A beginner’s guide to understanding what happens when you type ls *.c in bash. | by Josh Jimenez | Medium
June 19, 2018 - This command is short for “List”. When using this command you are pulling up a list of all the files in the working directory. If we were to input this command to the command line by itself we should expect to see something like this: ... ...
🌐
Red Hat
redhat.com › en › blog › 11-linux-command
11 Linux commands I can’t live without
November 20, 2025 - This command lets you change file ... used command is ls. This command helps you list directories and see permissions, the owner of files/directories, groups, file sizes, and dates modified....
Top answer
1 of 3
2

It's the number of (by default, 1K) blocks. From the description of -ls in the texinfo documentation (info find -n 'Print File Information'):

 -- Action: -ls
     True; list the current file in 'ls -dils' format on the standard
     output.  The output looks like this:

          204744   17 -rw-r--r--   1 djm      staff       17337 Nov  2  1992 ./lwall-quotes

     The fields are:

       1. The inode number of the file.  *Note Hard Links::, for how to
          find files based on their inode number.

       2. the number of blocks in the file.  The block counts are of 1K
          blocks, unless the environment variable 'POSIXLY_CORRECT' is
          set, in which case 512-byte blocks are used.  *Note Size::,
          for how to find files based on their size.

       3. The file's type and file mode bits.  The type is shown as a
          dash for a regular file; for other file types, a letter like
          for '-type' is used (*note Type::).  The file mode bits are
          read, write, and execute/search for the file's owner, its
          group, and other users, respectively; a dash means the
          permission is not granted.  *Note File Permissions::, for more
          details about file permissions.  *Note Mode Bits::, for how to
          find files based on their file mode bits.

        ...
2 of 3
1

It seems to me that the second column in the output of

find -ls

is the drive space occupied in kibibytes, corresponding [at least for files] to the output of du (default matching du -k). For directories it is the drive space occupied for the directory structure itself (not including the data in the files in the directory, but the addresses to the files, so the number increases, when there are many files in the directory).

Please notice that in current Ubuntu systems, the minimum drive space allocated to a file is 4 kibibytes.

🌐
ComputerNetworkingNotes
computernetworkingnotes.com › linux-tutorials › the-output-of-the-ls-l-command-explained.html
The output of the ls -l Command Explained
July 8, 2025 - The ls command with the l option provides detailed information about the contents stored in the specified directory. The detailed information includes name, location, permission, owner, created and modified date, size, and type of the content.
Top answer
1 of 3
69

The option '-l' tells the command to use a long list format. It gives back several columns wich correspond to:

  • Permissions
  • Number of hardlinks
  • File owner
  • File group
  • File size
  • Modification time
  • Filename

The first letter in the permissions column show the file's type. A 'd' means a directory and a '-' means a normal file (there are other characters, but those are the basic ones). The next nine characters are divided into 3 groups, each one a permission. Each letter in a group correspond to the read, write and execute permission, and each group correspond to the owner of the file, the group of the file and then for everyone else.

  • [ File type ][ Owner permissions ][ Group permissions ][ Everyone permissions ]

The characters can be one of four options:

  • r = read permission
  • w = write permission
  • x = execute permission
  • - = no permission

Finally, the "+" at the end means some extended permissions.

2 of 3
13

If you type the command

$ man ls

You’ll get the documentation for ls, which says in part:

The Long Format
If the -l option is given, the following information is displayed for each file: file mode, number of links, owner name, group name, number of bytes in the file, abbreviated month, day-of-month file was last modified, hour file last modified, minute file last modified, and the pathname. In addition, for each directory whose contents are displayed, the total number of 512-byte blocks used by the files in the directory is displayed on a line by itself, immediately before the information for the files in the directory. If the file or directory has extended attributes, the permissions field printed by the -l option is followed by a '@' character. Otherwise, if the file or directory has extended security information (such as an access control list), the permissions field printed by the -l option is followed by a '+' character.

The man command is short for “manual”, and the articles it shows are called “man pages”; try running man manpages to learn even more about them.

🌐
Red Hat
redhat.com › en › blog › ls-command-options
Sysadmin tools: 11 ways to use the ls command in Linux
November 20, 2025 - The -lh flag is the same long list format command as above, however, the file size is displayed in a human-readable format. Notice the difference between the file size outputs in the previous two screens. ... This option, like the standard ls command, lists all non-hidden files and directories.
🌐
Medium
medium.com › @akintolamayode1 › understanding-ls-l-c-command-in-linux-4f9891679fd5
Understanding “ls -l *.c” command in Linux | by Akintola Mayode | Medium
August 25, 2021 - The output from ls -l summarizes all the most important information about the file on one line. If the specified pathname is a directory, ls displays information on every file in that directory (one file per line).
🌐
GeeksforGeeks
geeksforgeeks.org › linux-unix › ls-command-in-linux
Listing Files and Directories in Linux - GeeksforGeeks
January 9, 2026 - In the below output directories get displayed in blue, soft links get displayed in green, and ordinary files get displayed in default color. ... When you list files using the ls -l command in Linux, it shows the last modified time of each file.