0

I have got this perfectly working command:

netstat -tuplean | awk '{NR>1; if( $6 ~ /ESTABLISHED/ ) print "\033[0;31m" $5  "   \033[01;31m"$6;if ($6 ~ /_WAIT/ ) print "\033[0;34m"$5  "   \033[01;32m"$6}'

I cannot wrap it into a watch command. Here is what I tried:

  1. escape all single quotes (')

    watch 'netstat -tuplean | awk '\''{NR>1; if( $6 ~ /ESTABLISHED/ ) print "\033[0;31m" $5  "   \033[01;31m"$6
      if ($6 ~ /_WAIT/ ) print "\033[0;34m"$5  "   \033[01;32m"$6}'\'''
    
    

    output:

    ^[0;31m34.210.39.83:443   ^[01;31mESTABLISHED
    ^[0;31m34.107.221.82:80   ^[01;31mESTABLISHED
    ^[0;31m34.107.221.82:80   ^[01;31mESTABLISHED
    ^[0;34m34.117.59.81:80   ^[01;32mTIME_WAIT
    ^[0;34m34.117.59.81:80   ^[01;32mTIME_WAIT
    ^[0;31m192.168.0.1:67   ^[01;31mESTABLISHED
    
  2. escape both single and double quotes (' and ")

    watch 'netstat -tuplean | awk '\''{NR>1; if( $6 ~ /ESTABLISHED/ ) print '\'"\033[0;31m'\'" $5  "   \033[01;31m'\'"$6
      if ($6 ~ /_WAIT/ ) print '\'"\033[0;34m'\'"$5  '\'"   \033[01;32m'\'"$6}'\'''
    

    output:

     bash: syntax error near unexpected token `print'
    
  3. export the command and then call it back this way:

     while : do ...<cmd>...; sleep 2;done
     watch -n 3 -x bash -c "$cmd" 
    

    it does not work neither because the same pb occurs when defining the variable.

  4. I tried to make a script using while : do ...<cmd>...; sleep 2;done

    it does not work because it looks like the sleep delay is not taken into account so the output comes out so fast there is no way to read something.

4

You did not share the complete code you used in your loop-based attempts, so here are a few options you have to avoid handling multiple levels of quoting, freely based on a slightly modified AWK script.

You may save your code as an executable file:

#!/bin/bash

netstat -tuplean | awk '
  $6 ~ /ESTABLISHED/ { print "\033[0;31m" $5  "   \033[01;31m"$6 }
  $6 ~ /_WAIT/ { print "\033[0;34m"$5  "   \033[01;32m"$6 }
  $6 ~ /TIME_WAIT/ { print "\033[0;34m"$5  "   \033[01;32m"$6 }
  END { printf("%s","\033(B\033[m") }      # Turn fancy formatting off'

and make watch run it, noting that, as pointed out in the answer you already have, you also need the --color option:

watch -n 3 --color ./my_script

Alternatively, you may use an infinite loop — I am unable to guess why, in your case, "the sleep delay is not taken into account"; this seems to work as expected:

while :
do
  clear
  netstat -tuplean | awk '
    $6 ~ /ESTABLISHED/ { print "\033[0;31m" $5  "   \033[01;31m"$6 }
    $6 ~ /_WAIT/ { print "\033[0;34m"$5  "   \033[01;32m"$6 }
    $6 ~ /TIME_WAIT/ { print "\033[0;34m"$5  "   \033[01;32m"$6 }
    END { printf("%s","\033(B\033[m") }     # Turn fancy formatting off'
  sleep 3
done

To save your script in a variable and run it as bash -c "$cmd", you may combine command substitution and a here-document. If the label of a here-document is quoted (here, 'EOT'), its content is not expanded:

cmd=$(cat <<'EOT'
netstat -tuplean | awk '
  $6 ~ /ESTABLISHED/ { print "\033[0;31m" $5  "   \033[01;31m"$6 }
  $6 ~ /_WAIT/ { print "\033[0;34m"$5  "   \033[01;32m"$6 }
  $6 ~ /TIME_WAIT/ { print "\033[0;34m"$5  "   \033[01;32m"$6 }
  END { printf("%s","\033(B\033[m") }      # Turn fancy formatting off'
EOT
)
1
  • 2
    +1. writing this as a stand-alone script is a good way to avoid quoting issues due to the conflicting quoting requirements of watch and shell and the awk script.
    – cas
    Aug 13 '21 at 14:18
3

The command where you enclosed everything in single-quotes and properly escaped the old single-quotes is almost good. It prints "garbage" because you didn't use watch --color. Run this:

watch --color 'netstat -tuplean | awk '\''{NR>1; if( $6 ~ /ESTABLISHED/ ) print "\033[0;31m" $5  "   \033[01;31m"$6
  if ($6 ~ /_WAIT/ ) print "\033[0;34m"$5  "   \033[01;32m"$6
  if ($6 ~ /TIME_WAIT/ ) print "\033[0;34m"$5  "   \033[01;32m"$6}'\'

(Note the final '' in your original code is a single-quoted empty string concatenated with what's before. It changes nothing. My code omitted this useless '' completely.)

From man 1 watch:

-c, --color
Interpret ANSI color and style sequences.

1
  • .@Kamil: good point to you. Regarding the final ( ' ' ), I try to keep the logic: ( ' \ ' ' ) corresponding to the end of awk snippet and one last ( ' ) corresponding to close the watch command.
    – achille
    Aug 13 '21 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.