1

I am writing a bash script which shows me all tcp connections which are important for me. For that I use netstat -atp. It looks like this:

num_haproxy_443_established=$(netstat -atp | grep ESTABLISHED | grep :https | grep haproxy | wc -l)
printf "\n show ESTABLISHED connections port 443 \n"
printf " %s" $num_haproxy_443_established

In the bash script I have some of these calls and now I would like to optimize it and call netstat -atp only once and reuse the results. I tried:

netstat_res=$(netstat -atp)

num_haproxy_443_timewait=$("$netstat_res" | grep TIME_WAIT | grep :https | grep haproxy | wc -l)
printf " %s" $num_haproxy_443_timewait

After executing the script I always get 0: command not found as error message. How can I use a variable inside $(...) ?

Thanks!

5
  • Because I don't want to create a file every time it runs. Commented Jun 20, 2017 at 9:10
  • 1
    Fair enough, but you not piping the contents of netstat_res to grep by $(echo "$netstat_res" | grep TIME_WAIT | grep :https | grep haproxy | wc -l) Commented Jun 20, 2017 at 9:11
  • If you set your variable to netstat_res="netstat -atp" it would work but then you'd call netstat every time (not sure why you would want to re-use its results anyway) Commented Jun 20, 2017 at 9:12
  • Sometimes I want to monitor the load on a loadbalancer. Therefore I would run this script every second for about 30 seconds or so. When there are 1000 or more connections I don't want to run netstat 8 times or more but only once. Commented Jun 20, 2017 at 9:16
  • I think an awk with print is probably going to be a cleaner solution or answer. Similar to what @anubhava proposed. Commented Jun 20, 2017 at 9:25

3 Answers 3

1

If you have something like A="foo" then $("$A") will be resolved to call the program foo in the subshell.

So you just have to echo the content of the variable and then grep from it:

num_haproxy_443_timewait=$(echo "$netstat_res" | grep TIME_WAIT ...)
Sign up to request clarification or add additional context in comments.

Comments

1

You can use shell array to store your netstat command:

# your netstat command
netstat_res=(netstat -atp)

# then execute it as
num_haproxy_443_timewait=$("${netstat_res[@]}" |
awk '/TIME_WAIT/ && /:TIME_WAIT/ && /haproxy/{++n} END{print n}')

echo $num_haproxy_443_timewait

Also note how you can avoid multiple grep calls by a single awk call.

Related BASH FAQ: I'm trying to put a command in a variable, but the complex cases always fail!

3 Comments

no arrays needed for this... the newlines will be preserved in the bash variable.. only echo "$netstat_res" is needed
ok I see your point but caching netstat results and reusing might give wrong results depending upon life of the cache.
To make netstat run faster I suggest using netstat -atnp
0

At your case, $netstat_res is the result but not the COMMAND, if you want to save the result and use it not only once, save the result to the file is the better way, such as:

    netstat -atp > /tmp/netstat_status.txt
    num_haproxy_443_timewait=$(cat /tmp/netstat_status.txt | grep TIME_WAIT | grep :https | grep haproxy | wc -l)
    printf " %s" $num_haproxy_443_timewait

3 Comments

Yes, $netstat_res is the result. I want to use the result as input for the next commands like grep. I don't want to save the result as a file because that's unnecessary disk usage.
@Hamburml Oh I see, but "echo $netstat_res" will lose the "\n" separtor, how to fix it?
But it works with echo, see stackoverflow.com/a/44648712/3069477

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.