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 would like to get the line number of my shell script in my error log file. I can get the error message in my log file but how can I get the line number where that command which gave error is located.
For Eg. I have a file called test.sh as follow:
Code:
#!/bin/bash
#Declaring Global Variable
mount /dev/hdd /tmp/mnt 2>/tmp/errorLog.txt
exit 1
Now when I run this script I do get the error message:
mount: you must specify the filesystem type
in my errorLog.txt file, but how can I get the line number of the command (in this case 'mount' command) which throws error. For Example, here the mount command in my test.sh script is located at '3'. How can I get this number '3' in my errorLog.txt file.
Typically I wouldn't suggest doing it just because it adds a little overhead to your run. The best way to determine which line gave the errors is just by doing a locate for the error text in your script.
But if you REALLY want to do it you could just add a counter in the file:
CNT=1 - First line of file
Then after every line you could add "CNT=`exprt $CNT + 2`
You do 2 because the above command itself would be a new line.
Then in your error message text you can add "at line $CNT"
It would make your code look rather ugly but it would work.
Bash has a special variable LINENO that tells you the line in the script. But you only want to print it when something goes wrong. The operator || kind of does this:
Code:
#!/bin/bash
#Declaring Global Variable
mount /dev/hdd /tmp/mnt 2>/tmp/errorLog.txt || echo Line $LINENO >> /tmp/errorLog.txt
exit 1
The line number will be printed on a separate line, after the error message.
Note that any further redirection of the style ">/tmp/errorLog.txt" will rewind and truncate the log. You'd lose all previous content, even if no output is written. So if you are going to extend the script, you may wish to use ">>" (append) instead of ">".
Thank you guys for the useful information. I will try the methods suggested in my script file. Also what does the operator '||' is called? Also what does it do exactly?
LQ Rules!!!
Kushal
Last edited by kushalkoolwal; 10-17-2005 at 12:01 PM.
The control operators && and ││ denote AND lists and OR lists, respec-
tively. An AND list has the form
command1 && command2
command2 is executed if, and only if, command1 returns an exit status
of zero.
An OR list has the form
command1 ││ command2
command2 is executed if and only if command1 returns a non-zero exit
status. The return status of AND and OR lists is the exit status of
the last command executed in the list.
Thank you once again. Also I had couple of questions as an extension to my query. I have quite a few similar statements like:
IDE_1_INF="$(cat /proc/ide/$IDE_1/media) $(cat /proc/ide/$IDE_1/model)"
in my script.
Can I apply your technique even to statements like above? Or do you think that it won;t make any sense to use the technique in statements like this. Even if not, then also please let me know how can I apply your technique to statement like the one above. I think it should be:
IDE_INF="$(cat /proc/ide/$IDE_1/media 2>>/tmp/errorLog.txt || echo Line $LINENO >> /tmp/errorLog.txt) $(cat /proc/ide/$IDE_1/model 2>>/tmp/errorLog.txt || echo Line $LINENO >> /tmp/errorLog.txt)"
Also, by your method I get the error message first and then the Line number. Can I somehow reverse it? i..e first I can get the Line number and then the error messsage?
I don't know a simple way to put the line number first. You want to write it conditionally, only when an error happens, and then the message is already written, right?
Of course you could redirect stderr to a temporary file, then check the status, and if it is nonzero write the line number to the error log, followed by the temporary file. (Using echo -n for the line number will even let you put them on the same line.) But this will really make your script hard to read. You may consider creating a bash function for the error handling.
For the specific command line in your question, you could write:
Code:
IDE_1_INF=`cat /proc/ide/$IDE_1/m* 2>>/tmp/errLog` || echo line $LINENO >> /tmp/errLog
The wild card m* will expand to media and model, in this order. The `...` is the same as $(...), and it will put a space instead of the newline in the middle. If the wildcard seems too unsafe, you could use /proc/ide/$IDE_1/{media,model} instead.
Sorry, I don't know bash. Just glanced at the man page because your question intrigued me.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.