bash: how to discard unwanted stdin?
Hello :)
Often in bash we read lines from stdin in a loop and implicitly discard the remaining stdin by terminating the loop. Is it possible to discard it without terminating the loop? It could lead to smaller code. Here's an example which uses two loops and below is the same algorithm assuming unwanted stdin can be discarded Code:
found= Code:
found= |
Quote:
Code:
while read destination gateway _ Code:
while read -u 3 destination gateway _ |
Thanks konsolebox, the second method using unit/fd numbers is elegant :)
It works without the "exec"s in the process substitution subshells too, as in done 4< <(arp) instead of done 4< <(exec arp) EDIT: I'm only interested in the default gateway line from route output; once that is found the rest is irrelevant. |
Quote:
Quote:
Code:
while read LINE; do |
Quote:
Quote:
First the experimental/demonstration script: Code:
#! /bin/bash Code:
Outer: LINE is '1' Taking advantage of this feature, a better version of the get_default_gateway_MAC.sh script (better = simpler and does not need process substitution so more portable): Code:
found= |
Quote:
|
So try not to smack me about too much, but as opposed to the question asked about discarding stdin I thought I would just give an alternative for the script:
Code:
def=$(route | awk '/default/{print $2}') |
Quote:
|
Quote:
Is that alternative functionally equivalent, though? The intention is to get the default gateway's hardware address, not its IP address. Does it handle the case where there is no "default" in the routing table? Does it set $found to indicate the validity of the address? The default gateway's hardware address will be used by a netbook's boot script as a "good enough" way of identifying the LAN so it can do LAN-specific initialisation. Being boot script code, performance is significant so the sweet spot between coding complexity and the fork+exec count is more towards the coding side. Your alternative is tighter and easier to maintain than mine (natch!) but will take more resources to run, which matters when booting an Atom-based system! |
hmmmm ... I am guessing there must be a lot more to the code that I have not seen as my output is the same, except I have output the word found instead
of yes and not attached to a variable which I know you would have no trouble in doing. I would be curious, and I will premiss this by saying I am no guru, about using more resources in mine than yours. Are we saying that the use of awk is a bigger hit than the 2 while loops being iterated over? And in answer to your questions, again from the original script presented: Quote:
Quote:
Also I would point out that if your script hits a route with no 'default' it will exit and do nothing. Quote:
I guess my initial point was that maybe instead of discarding values we can maybe be smarter about what values we are getting? I hope I am being constructive as I always value your opinions :) and very happy to learn cheers grail |
Quote:
Code:
# Get the default gateway hardware address Code:
# Get the default gateway hardware address Quote:
fork+exec is "expensive" and bash runs fast when processing small (say < 5 kB) strings. To be sure (and to get a feel for where awk's faster processing of large amounts of text begins to outweigh the fork+exec cost) testing would be necessary. The ping would have to be removed (very slow compared to the rest of the code) and to be measurable the code would have to be put in a loop; in the case of this code I don't think there are any buffering effects that would affect the results (as there would be when doing file I/O). Quote:
Doing nothing when the routing table has no default route is intended -- this is a "convenience" facility so it's not worth analysing rc.inet1.conf to see if there should be a default route or re-running DHCP client as might be appropriate on a mission-critical, robust system. Quote:
Always a pleasure to debate with you; debate is a great way to learn different ways, to see other perspectives, to increase the breadth and depth of understanding and thus become better at what we do. Just so long as you remember that I'm always right! :D :D :D |
I was talking to a network guy here at work (i am still learning) and he has said that to the best of his knowledge the 'default' will never not be in the routing table
(just passing on what was said :) ) So to this end, this might help for later testing, this is the same with the changes: Code:
def=$(route | awk '/default/{print $2}') Quote:
|
Quote:
Code:
root@CW8:~# route Regards the case statement -- yes, more cases are envisaged. |
All times are GMT -5. The time now is 06:31 AM. |