skip to Main Content

Because of a specific requirement scenario, I wanted to write a Shell script to monitor the DNS used by my Linux host.
Here’s how I wrote it:

#! /usr/bin/bash

NETWORKING_DNS=$(nmcli dev show |grep DNS|awk '{print $2}')
echo "Current DNS: "
echo "$NETWORKING_DNS"

No problems so far, it outputs something like this:

xxx@xxx ~:$ bash script.sh
Current DNS:
1.1.1.1
1.0.0.1

Because I have other information to output, I wanted it to display it on one line, so I changed it to the following:

echo "Current DNS: $NETWORKING_DNS"

But when I was executing this script, something strange happened and its output became like this:

xxx@xxx ~:$ bash script.sh
Current DNS: 1.1.1.1
1.0.0.1

Why??

I thought it would output like this:

Current DNS: 1.1.1.1 1.0.0.1

I don’t know why this is happening.
I’ve tried a number of things, such as using the -n option:

echo -n "Current DNS: $NETWORKING_DNS"

Or

printf "Current DNS: %s" "$NETWORKING_DNS"

None of them achieve the result I want.

Can anyone tell me why this is? (It’s an "unimportant" question, but I’m kind of curious.)

My linux host info:

xxx@xxx ~:$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

xxx@xxx ~:$ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

echo -n "Current DNS: $NETWORKING_DNS"

or

echo -ne "Current DNS: $NETWORKING_DNS"

or

printf "Current DNS: %s" "$NETWORKING_DNS"

It doesn’t works.

2

Answers


  1. why this is happening

    Variable contains 1.1.1.1 followed by a newline character followed by 1.0.0.1.

    The newline character when printed starts a new line. Advances cursor position to the next empty line, optionally shifting terminal output one line up, depending on the terminal, and moves cursor position to column 0.

    The variable contains a newline character, it will be printed when variable content is printed, no matter the method.

    Tip: you can debug variables with declare -p NETWORKING_DNS. Unquoted variable expansions undergo word splitting (and filename expansion), which joins words split by spaces – so you might echo $NETWORKING_DNS. Research ASCII, shell quoting, word splitting expansion, filename expansion. Check your scripts with shellcheck. To replace newline with a space, you can use tr 'n' ' ' or paste -sd ' ', see man tr and man paste.

    Login or Signup to reply.
  2. As mentioned in the other answers, the root cause is that there is a newline inside your NETWORKING_DNS.

    You set up the content of that variable by processing it with AWK (print $2). There are several options that influence the output of AWK. (You can read the documentation of AWK for the details.) But the summary is: AWK is doing the print $2-action for every record it gets from the pipe. AWK separates the output of each action by printing the OutputRecordSeparator (or ORS).

    The ORS is by default a newline, but you can tweak it to something different, e.g. replace your line in your script with:

    NETWORKING_DNS=$(nmcli dev show |grep DNS|awk -v ORS=" " '{print $2}')
    

    to change the ORS to space.

    How it works:

    • the invocation of awk sets the ORS variable to space instead of the default newline using the -v option
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search