0

I am using the function below to increment an outside script. The main purpose of this is just to return some data from ifconfig and ping test outputs. I am trying to set them inside the same function using variables, just to do some other "pipes" and concactenate them again with other information. But I got this behavior. Basically, what I am trying to do is:

    > for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f 3 | cut -d: -f2) ; do ping -c1 $i | grep packet | a=`echo $i-$(cut -d,
    -f3)` | echo $a; done  
4  
4  
4  
4

As you can see, it returns the number 4 for each iteration.

If I just remove the variable attribution, I get the output I was expecting to set in variable 'a' at first place:

> for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f 3 | cut -d: -f2) ; do ping -c1 $i | grep packet | echo $i-$(cut -d, -f3); done
10.0.2.15- 0% packet loss
192.168.0.2- 0% packet loss
10.0.2.100- 0% packet loss
127.0.0.1- 0% packet loss
  • Why am I getting number 4 as output in first function code execution?
  • How can I set a variable inside the same function and echo it again after some pipelines? Is that possible?

Best regards !

4
  • 1
    Can you show the output of ifconfig ? that pipeline is really not needed.
    – Jetchisel
    Commented Mar 10, 2020 at 4:10
  • @Jetchisel it is just a regular ifconfig output. I am doing that | grep to get just the address related part.
    – JohnC
    Commented Mar 10, 2020 at 11:51
  • what system/os is that regular ifconfig output then?
    – Jetchisel
    Commented Mar 10, 2020 at 11:54
  • This is an example. I am just cutting the address part that I am interest to: eth1 Link encap:Ethernet HWaddr 00:00:00:00:00:00 inet addr:192.168.0.2 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr:ff:ff:ff:ff:ff/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:750 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 b) TX bytes:45168 (44.1 KiB)
    – JohnC
    Commented Mar 10, 2020 at 13:29

2 Answers 2

2
 for i in $(...) ; do ... | a=`...` | echo $a; done

Why am I getting number 4 as output in first function code execution?

Because a=`...` and echo $a are executed in different subshells / subprocesses. a=1; a=3 | echo $a will print 1 in any shell. There's no way to pass a variable from a subshell to its parent.

How can I set a variable inside the same function and echo it again after some pipelines? Is that possible?

No. Unless you set it in the main script, before the pipeline.

3
  • Very good explanation. I tried something: # a=1;a=2;a=3 | echo $a (outputs 2). So, It got second 'a' value in the output, and not the first one. @pizdelect
    – JohnC
    Commented Mar 10, 2020 at 13:23
  • The ; has lower precedence than |. You're not fooling the parser by huddling the assignments close together -- the parser will still group it as a=1; a=2; { a=3 | echo $a; }, not as { a=1; a=2; a=3; } | echo $a. Just like 4+4 / 2 is 6 not 4
    – user313992
    Commented Mar 11, 2020 at 16:43
  • Got your point ! It should be considered precedence order in command execution by Bash
    – JohnC
    Commented Mar 12, 2020 at 15:14
0

If you restructure the last part of the pipeline using sed I think you can get what you want. The sed script matches the whole standard input and replaces it with the value of $i followed by - and the third field of your ping output (from stdin). For example,

$ for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f3 | cut -d: -f2); do \
    ping -c1 $i | grep packet | cut -d, -f3 | sed "s/\(.*\)/$i - \\1/"; \
done
123.145.167.189 -  0% packet loss
127.0.0.1 -  0% packet loss
2
  • Hello. I am able to print it, just cutting the variable attribution. What I was trying to do, in fact, was save that to a variable so I could concactenate with other values a few pipelines after, to make all of that working in a single function...
    – JohnC
    Commented Mar 10, 2020 at 13:26
  • @JohnC in that case you might want to turn this into a shell script and use temporary files (see mktemp) to save pieces of data that you want in each part of the pipeline for use at the end.
    – celadon
    Commented Mar 11, 2020 at 3:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .