Issue
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.
Solution
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
Answered By - Lars Fischer Answer Checked By - Marie Seifert (WPSolving Admin)