skip to Main Content

When I run cat directly I get nice formatted text exactly as in the file.

$ cat hostnamectl.output
   Static hostname: linuxtb3
         Icon name: computer-vm
           Chassis: vm
        Machine ID: 76073c1aa8cf48ed900c39d1992fbb73
           Boot ID: 24db61d58fd5491bbf82a4bb743e5b72
    Virtualization: kvm
  Operating System: CentOS Linux 7 (Core)
       CPE OS Name: cpe:/o:centos:centos:7
            Kernel: Linux 3.10.0-957.21.3.el7.x86_64
      Architecture: x86-64

When I run it after echo all formatting is lost.

$ echo `cat hostnamectl.output`
Static hostname: linuxtb3 Icon name: computer-vm Chassis: vm Machine ID: 76073c1aa8cf48ed900c39d1992fbb73 Boot ID: 24db61d58fd5491bbf82a4bb743e5b72 Virtualization: kvm Operating System: CentOS Linux 7 (Core) CPE OS Name: cpe:/o:centos:centos:7 Kernel: Linux 3.10.0-957.21.3.el7.x86_64 Architecture: x86-64

What is the reason for such behavior?

2

Answers


  1. When you run:

    echo `cat xxx`
    

    You actually calling:

    echo line1word1 line1word2 n line2word1 line1word2 n line3word1 line3word2
    

    Which is essentially the same as:

    echo line1word1 line1word2 line2word1 line1word2 line3word1 line3word2
    

    This how bash handle args, so you get:

    line1word1 line1word2 line2word1 line1word2 line3word1 line3word2
    

    BTW, you can use:

    echo "`cat xxx`"
    

    where the cat xxx part will be passed to echo as a single string arg1, so you will get expected output

    Login or Signup to reply.
  2. From Greg’s Bash Guide:

    2. Quoting

    Word Splitting is the demon inside Bash that is out to get unsuspecting newcomers or even veterans who let down their guard. …The best way to protect yourself from this beast is to quote all your strings. Quotes keep your strings in one piece and prevent Word Splitting from tearing them open.

    Here’s another example to show you just how badly you can break things if you neglect to quote when necessary:

    $ echo "$(ls -al)"
    total 8
    drwxr-xr-x   4 lhunath users 1 2007-06-28 13:13 "."/
    drwxr-xr-x 102 lhunath users 9 2007-06-28 13:13 ".."/
    -rw-r--r--   1 lhunath users 0 2007-06-28 13:13 "a"
    -rw-r--r--   1 lhunath users 0 2007-06-28 13:13 "b"
    -rw-r--r--   1 lhunath users 0 2007-06-28 13:13 "c"
    drwxr-xr-x   2 lhunath users 1 2007-06-28 13:13 "d"/
    drwxr-xr-x   2 lhunath users 1 2007-06-28 13:13 "e"/
    $ echo $(ls -al)
    total 8 drwxr-xr-x 4 lhunath users 1 2007-06-28 13:13 "."/ drwxr-xr-x 102 lhunath users 9 2007-06-28 13:13 ".."/ -rw-r--r-- 1 lhunath users 0 2007-06-28 13:13 "a" -rw-r--r-- 1 lhunath users 0 2007-06-28 13:13 "b" -rw-r--r-- 1 lhunath users 0 2007-06-28 13:13 "c" drwxr-xr-x 2 lhunath users 1 2007-06-28 13:13 "d"/ drwxr-xr-x 2 lhunath users 1 2007-06-28 13:13 "e"/
    

    Just like in the ls -al example, double quotes will fix your problem:

    $ echo "`cat hostnamectl.output`"
    

    It is, however, an anti-pattern to capture a command’s output with backticks and then immediately echo the captured output. You should simply call the command directly and skip the extra steps:

    $ cat hostnamectl.output
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search