[SOLVED] Looking for experience to make a script more efficient.
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.
Looking for experience to make a script more efficient.
I'm new to bash scripting. I wrote this script to attach url's to specified 6 digit numbers in a configuration text file. My original goal was to be able to be able to pull the url's and the 6 digit numbers from .csv files. that would allow me to make the script more versatile, not only for this particular project, but also for other projects in regards to the configuration file. This script works, and has served it's purpose, but it is not very pretty, and it's probably not very efficient. What can I do to improve it and possibly make it more versatile. I've thought about functions and arrays, but my skill set is still pretty limited. I'm not looking for someone to write it for me, just to point me in the right direction. Thanks in advance!
Biggest change I can see that would be beneficial is subroutines/functions, give it a try and if you're having problems come back here and let us know what they are and we'll give ya a hand.
Using a case-esac statement would save a lot of "elif"s and make it clearer that the only variable being tested was $LINE.
Code:
case $LINE in
215656 )
<commands>
;;
215506 | 215509 | 215575 )
<commands>
;;
...
esac
There's no need for the { and } in, for example [[ ${LINE} == 215074 ]]
It would be easier to read and debug if code within do-done and if-else-fi was indented so the "do"s lined up with the "done"s. Putting "then"s after the tests would make the code more compact and facilitate if-else-fi alignment
Code:
while true
do
read -r fplan
if [[ -f "$fplan" || -f ../"$fplan" ]]; then
echo "File exists"
break
else
echo "Try again"
fi
((cnt+=1))
if [[ $cnt -eq 5 ]]; then
echo "exceeded 5 tries. quitting. Do you know what you're doing?"
exit
fi
done
((cnt+=1)) could be ((cnt++)). Personally I use let cnt++, thinking it more legible.
A single echo can write several lines. Using single quotes makes it obvious that the string is to be printed verbatim, without any substitutions
Code:
echo '
Please wait while the task completes
Patience is a virture, posess it if you can
Seldom found in women, never in a man'
It's a good idea to check the output and return code of commands to ensure they worked and to stop processing if they did not. Error messages are conventionally written to stderr (this helps if you only want to check error messages). Combining both notions:
Code:
out="$( mv $PWD/complete "$fplan" 2>&1 )"
rc=$?
if [[ $rc -ne 0 || $buf ]]; then
echo "Problem moving file. Return code: $rc, stdout and stderr: '$out'" >&2
exit 1
fi
fellas, this is good stuff. I appreciate you getting back to me so quick. I've been reading through the advanced bash scripting guide. Case seems like a pretty handy command to have in the repertoire. From what I've been reading it seems pretty versatile. I'm not going to have an opportunity to try it until after the holiday, but I think what i'd like to do is write a function that would load a particular set of numbers into an array based on other criteria that is in the .csv file. This would require approx 15 separate functions, but would encompass all of the relevant numbers. I could then use a case statement to write them to the proper spot in the config file, count the 23 lines down and write the url. I think that this would also allow me to make the whole deal more useful. The config file that i am writing to is for a simulation game. Each line in the file corresponds to certain types of data in respect to any given entity. If I were to use variables for various data types, e.g. entity name, affiliation and whatnot, then the script would become a lot more useful and would save a lot of time during the build process. I apologize for this not so descriptive reply, I haven't quite thought it all out yet.
I do have a couple of questions though:
Code:
out="$( mv $PWD/complete "$fplan" 2>&1 )" ## would this replace the move command that is currently in the script?
rc=$?
if [[ $rc -ne 0 || $buf ]]; then ##is $buf a variable that is inherent to bash? from what i've learned so far the || means or. so what is $buf?
echo "Problem moving file. Return code: $rc, stdout and stderr: '$out'" >&2 #last question: what exactly is the 2>&1 and >$2 doing?
exit 1
fi
thanks again for the help and ideas. i'm having fun learning bash, and this community seems pretty great so far.
out="$( mv $PWD/complete "$fplan" 2>&1 )" ## would this replace the move command that is currently in the script?
# Yes
rc=$?
if [[ $rc -ne 0 || $buf ]]; then
##is $buf a variable that is inherent to bash?
# No
# what is $buf?
# The name is short for buffer, a usage based on Kernighan and Ritchie's work (good pedigree!), essentially meaning a temporary storage area.
# Only useful with buf="$( ...
# If you prefer $out to $buf, you could use if [[ $rc -ne 0 || $out ]]
# (empty strings are "true", others are false)
echo "Problem moving file. Return code: $rc, stdout and stderr: '$out'" >&2
#last question: what exactly is the 2>&1 and >$2 doing?
# 2>&1 says "send output for file descriptor 2 (stderr) to the same place as file descriptor 1 (stdout).
# The out="$( has already directed stdout to $out.
# a) >$2 says send stdout to stderr.
# b) In this case it sends echo's output to stderr.
# c) It is conventional and useful to write error messages to stderr.
exit 1
fi
Regards the 15 functions to (as best I understand it) write configuration files based on configuration files, it sounds excessive but have a go anyway (most of us learn best by doing) then post here and we'll see if it can be simplified. Glad you're enjoying the adventure
Last edited by catkin; 04-02-2010 at 12:29 PM.
Reason: Formatting and clarity
I understand. Is there a benefit to using $buf as compared to $out? or is it more of a preference type thing? Thanks for the explanation!
Purely personal preference; it's useful to have conventions for variable names (reduces need for personal memory, consistent usage makes scripts easier to understand ...) and $buf is what I use for short-lived "scratch" storage (inspired by aforementioned software giants). Usually its scope is made local to a function using the local builtin.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.