2

So I have a script that seeks whether my service vmxd.service exists, and checks its current state loaded,running,active...

I use the following script for that case:

systemctl --all --type service | awk -v pat="$SERVICE" '$0 ~ pat {print $0}'

● vmxd.service                                          loaded    failed   failed  Juniper vMX Router

Bear in mind that $SERVICE="vmxd.service"

The problem is that in some servers, that [●] is not present, so I deducted that by printing the first word {print $1} it would make the trick of grabbing the name.

When I checked my script on another host, now instead of printing vmxd.service as it was the first character on the string, it is now printing [●] and totally breaks my script.

Here is an Output of my Script showing the [●]:

[...] 
The service file: vmxd.service has been found under /etc/systemd/system/
Check if WorkingDirectory path is correct............................[OK]
Check if service exist...............................................[Found]
Check if ● is loaded...............................................[No]
Check if ● is active...............................................[No]
Enabling service....................................................../init.sh: line 189: command not found
Reloading Service....................................................[No]
Check if 'vmxd.service' has started successfully.....................[Started]

Is there a workaround for this issue? Is there a way to, if [●] is detected ignore without altering the {print $1}. By printing $1 it should say vmxd.service regardless

Normally the output on the servers where my script works are like:

  vmxd.service                                          loaded    active   exited  Juniper vMX Router

without the [●].

Note: I have no much idea what that dot actually means, but regardless I just need to ignore that character from my variable running the command

anubhava
  • 761,203
  • 64
  • 569
  • 643
nickcrv06
  • 127
  • 11
  • 3
    Simply adding the `--plain` option will cause the output to omit the `'●'` characters.... – David C. Rankin Dec 19 '21 at 07:15
  • 1
    Aside from the problem asked about, `$0 ~ pat` is doing a partial-line regexp match while what's really needed is a full-word string match. As written it'd print any line containing `improvmxdoserviceplan` when looking for `vmxd.service`. See [how-do-i-find-the-text-that-matches-a-pattern](https://stackoverflow.com/questions/65621325/how-do-i-find-the-text-that-matches-a-pattern) for why not to think in terms of matching a "pattern" and how to make your matching more robust. – Ed Morton Dec 19 '21 at 12:23

2 Answers2

3

You can remove all non-ascii characters from awk output:

systemctl --all --type service |
awk -v pat="$SERVICE" '$0 ~ pat {sub(/[^\x01-\x7f]+/, ""); print}'

Change from your script is this call:

sub(/[^\x01-\x7f]+/, "")

Regex pattern [^\x01-\x7f]+ matches 1+ of any character that is NOT in the ASCII range of x01-x7F (1-127) and removes them by replacing it with an empty string.

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    You are a genius! It worked, would it be possible, if you have time, to explain to me why this script works? How can it remove all non-ascii characters? If you can break down the script I would really appreciate it! Thank you so much for your support! – nickcrv06 Dec 19 '21 at 06:05
  • You're welcome. I have added an explanation in my answer. – anubhava Dec 19 '21 at 06:43
  • 2
    `systemctl --all --type service --plain` will also do it `:)` – David C. Rankin Dec 19 '21 at 07:16
  • 1
    @DavidC.Rankin: Thanks, great to know that. Being a mac user I was unaware of that. – anubhava Dec 19 '21 at 07:23
  • 2
    I recalled that for some reason unknown from way back from when systemd was replacing SysV init on Archlinux (2013?). I had to double-check the man page, but it works with the unit selection commands. `awk` is just as capable as you have written. – David C. Rankin Dec 19 '21 at 07:34
1

Is there a workaround for this issue? Is there a way to, if [●] is detected ignore without altering the {print $1}. By printing $1 it should say vmxd.service regardless

You might inform GNU AWK to treat only letters digits and dots using FPAT variable consider following simple example, let file.txt content be

● vmxd.service                                          loaded    failed   failed  Juniper vMX Router
vmxd.service                                          loaded    active   exited  Juniper vMX Router

then

awk 'BEGIN{FPAT="[0-9A-Za-z.]+"}{print $1}' file.txt

output

vmxd.service
vmxd.service

(tested in GNU Awk 5.0.1)

Daweo
  • 31,313
  • 3
  • 12
  • 25