ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have written a bash script to perform a traceroute for more than 500 IPs and I will be performing further operations on a output I am receiving.
The only issue I am facing here is, if the IP is not reachable it keep on giving me * * * and I need to eliminate those by some means.
Instead I am looking a way by which as soon as "*" encounters it should kill or jump to the next IP and start the traceroute again.
Traceroute has some options for skipping or working-around those hops which produce the "* * *" output. The man-page for traceroute explains why those "* * *" occur, and what to do about it.
root@reactor: traceroute -I -N 1 204.235.208.17
traceroute to 204.235.208.17 (204.235.208.17), 30 hops max, 60 byte packets
1 2.153.118.216.cpe.seasidehighspeed.com (216.118.153.2) 30.442 ms 29.193 ms 30.033 ms
2 204.235.208.17 (204.235.208.17) 59.900 ms 39.678 ms 35.001 ms
root@reactor:
If instead, you want your traceroute to output the results (including the asterisks) to screen or file, and use some `sed` or something to filter the asterisks from the output, then show us the script and we may be able to suggest a method of filtering them out.
Hope that helps!
EDIT: But, if this doesn't quite resolve the issue the way you like (as in, if you really want to just quit that IP upon encountering one asterisk, and move to the next IP), some scripting may be necessary if traceroute doesn't have built-in functionality for quitting upon getting some asterisks; check the man page, and if that doesn't help, then show us your code and we can try to work something into it to do what you need.
Last edited by GrapefruiTgirl; 07-21-2010 at 06:21 AM.
Absolutely...my traceroute doesn't provide any such option which could strip off * and any way my requirement is pretty different.
as you identified it correctly I need to cut or break the sequence as soon as it encounters single "*" and jump to next IP.
Here are my codes and please suggest if you have any bright plan
Unfortunately, it does not look like there's a way to do this using traceroute alone. Since traceroute doesn't appear to have an option to abort on occurrence of a "*", you are probably doing the best way you can do it already, using grep to filter out the "*" results. The way I see it, traceroute has to actually complete the entire operation before YOU can decide that there are asterisks and then toss the result.
I've come up with a rather brutal way of killing traceroute while it's running, if an asterisk is found in a line of output:
Code:
#!/bin/bash
LIST="204.235.208.17
"
for IP in $LIST; do
# $count is for debugging only:
count=0
traceroute -I -z 5 -w 2 $IP | while read line; do
# next line for debugging only:
count=$((count+1)); echo "count: $count"
if [ "$(echo "$line" | grep '*')" ]; then
killall traceroute || :
break
else
echo $line | awk '{print $2}' | grep -v '.domain.com' | grep -v '*' | grep -v 'traceroute to'
fi
done
done
As you can see, I did not test it with your real list of IP addresses, so stick your real IP's in there and see if this works for you. When I tested it on a single IP, it appears to work as you desire. If it "sort of" works, but not quite right, show us what is not working right and I'll try to adjust it.
Basically what it does, is feed the output of traceroute line by line into a while/do loop, which examines each line as it comes; if an "*" is present, traceroute is forcefully killed, the loop while loop exits, and the next IP is chosen and the process starts again.
EDIT: NOTE that a whole line must be received by the while/do loop before that line can be examined; this means that if I line of output from traceroute will contain three "*", then the killing will happen after all three * are generated, because the line is not complete until all three are there. So, it means that the killing will happen after one line containing *, which is better than waiting for the entire traceroute (and line after line of *) completes. If you want to abort sooner again, you'd probably want to add "-q 1" option to the traceroute command, which tells it to only to one query instead of three (hence one asterisk maximum instead of three) but this might also decrease the effectiveness of the traceroute.
Hope this helps.
Last edited by GrapefruiTgirl; 07-21-2010 at 07:55 AM.
Reason: Adjusted silly code mistake.
You mean to kill a script? CTRL-C or CTRL-Z are the standard key-codes for killing a running script. You *might* be able to use the `set` bash built-in function to define a different code, but I'm not sure about this as I don't use it much. The bash manpage should have a pretty detailed description of what you can do with `set`, but I don't know if you can do exactly this with it.
If CTRL-C or CTRL-Z work for you, will that do? Or must you use some other key combination?
EDIT: P.S. you may also be able to use the `read` bash builtin with "-t 0" within your loop, to see if a key has been pressed recently, and if it's the "stop" key (whatever key you want to stop the script) then exit. I don't think `read` works well with CTRL codes though, and haven't tested this.
Last edited by GrapefruiTgirl; 07-21-2010 at 08:50 AM.
Oh no, this is not what I wanted to convey. basically I need to have user enter something in file and want them to keep entering unless they press certain key sequence which would come out of that file and file will be saved. I can use the same file later for other operations.
E.g.
Please Enter all the IP addresses. Press CTRL+F once you are finish
OK, well what I do when I need that sort of functionality, is just call an external text editor from my script. You could for example do from you script:
Code:
kwrite /some/path/to/some/file
And at this point, kwrite pops open and the user types stuff and saves it, and upon exiting kwrite, the script continues.
If you don't like that idea, you could just use bash's `read` command in a loop, reading line by line of text entered by the user and echoing the text to a file as they enter it. To terminate the operation, check to see if the line entered is something like "EOF", and if it is, move on to the next part of the script; if it isn't an "EOF" run the loop again and read more entered text. This method isn't much of an editor (it isn't an editor at all) and doesn't allow for corrections-on-the-fly if the user enters an error and hits ENTER, but it's simple. You could ask each time they hit ENTER if the line they typed is correct; if it is, save it and continue; if it is not, get them to enter it again.
hmm...that's an good idea but not the exact way I was looking for.
I have pasted the exact output below. Please do let me know if you are aware of any such method by which I can achieve it.
You can add GUI Clients using any of the following formats:
1. IP address.
2. Machine name.
3. "Any" - Any IP without restriction.
4. IP/Netmask - A range of addresses, for example 192.168.10.0/255.255.255.0
5. A range of addresses - for example 192.168.10.8-192.168.10.16
6. Wild cards (IP only) - for example 192.168.10.*
Enter GUI Client(Press CTRL+D To Exit): 10.1.1.1
10.1.1.5
10.1.1.6
10.1.1.9
<CTRL+D> Pressed ---> Its hidden though
I am not aware of a method to grab a CTRL-D as the end signal. There may well be a way, but I don't know it or have forgotten it .
Rather than use the `read` + "EOF" method I gave, you could use `read` and simply have the text session exit upon getting a blank line: "Add GUI Clients .. blah blah .. Press ENTER on a blank line when done"
PS - To facilitate fixing errors as they are entered, I recommend the external text editor method.
Last edited by GrapefruiTgirl; 07-21-2010 at 09:44 AM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.