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.
Bad coders make a mess out of the most structured language elements. Deeply nested loops and if statements can become nicely wound spaghetti, but still spaghetti.
Goto's certainly serve a purpose... if used with care.
Ever tried to write a function which has to be left immediately in multiple conditions, but with the execution of some statements, like closing a file or releasing a mutex? Without goto?
Well, Linus doesn't seem to agree entirely with you.
Goto is always considered bad style these days, when we have safer constructs like while, for, if-else, etc.
The problem is with the compiler or interpreter that generates code out of these constructs... they tend to generate too much redundant code. While GOTOs are considered fine at the assembly level, they are not encouraged when using higher-level languages...and these include shell scripts!! Shell interpreters are written in a higher-level language anyway...
If you think bash or csh (or other shells) aren't good enough for you, write another one that compiles (or interpretes) while-, or for-loop constructs that generates the least assembly (or binary) code.
This is probably the best way of using GOTOs, by writing a compiler (or assembler, interpreter, etc.) in assembly. There's a super elegant solution of using JMPs for 80x86.
Well, Linus doesn't seem to agree entirely with you.
I have a problem.
I have built a script which goes through many 'if' tests. About twenty of them. Some of them, about 12, exit, if they meet certain conditions.
The problem is that if the script just exits, it leaves the system in bad condition: devices mounted to wrong directories etc.
The script should run about ten lines of code while exiting.
How to do this without GOTO ?
In good old days before purist programmers condemned it, we used GOTO to make this easy in Basic and Fortran.
Use a 'trap' to run a cleanup routine before exiting:
Code:
## User cancelled at a 'sensitive' spot, so scold them!
trap_int() {
echo
echo $RED"*** OUCH!!! ***"$NORMAL
emergency_restore
exit
}
# emergency_restore
emergency_restore() {
echo "Please don't interrupt during installation!"
# do whatever fixups (unmounts, etc) here:
}
# set a trap like this in your code before running 'sensitive' code:
trap trap_int 2
# The above just traps -INT, but you can specify multiple signals to trap
As far as I know, you can't 'revoke' a trap, so if you only need it at certain places and not in others, you can use another 'dummy' trap which does nothing in order to cancel the one above.
Use a 'trap' to run a cleanup routine before exiting:...
Thank you. This 'trap' didn't help this time, but it cave me an idea.
Now I'm using a function 'quit', where I can write all the cleanup I need.
Using one variable to tell, if the calling test has gone err or is the system exiting normally.
The whole script is too large to be copied here, I'll publish it on my site, when it is more mature. Here is small pieces of it to show how:
This script calls the main script:
Code:
#-- Calling script--
MAKER=/home/bin/backup/make_snapshot.sh;
# Call the main script:
$MAKER;
if (( $? )); then {
$ECHO "make_snapshot.sh script has been run" >>$ERROR_FILE;
$CAT $ERROR_FILE | $SENDMAIL $RECEIVER;
} fi;
This script makes most of the work:
Code:
#--Piece from the beginning of the script--
#------- VARIABLES -----------
# Set ERR=1 for default:
ERR=1;
#------- FUNCTIONS -----------
function quit {
$UMOUNT $MOUNT_DEVICE;
if (( $? )); then {
$ECHO "(1) ERROR: UNmounting $SNAPSHOT_RW" >>$ERROR_FILE;;
# ERR=1; Not needed, default
} fi;
exit $ERR;
}
#------- The MILL ----------
# make sure we're running as root
if (( `$ID -u` != 0 )); then {
$ECHO "(2) ERROR: Must be root. Exiting." >>$ERROR_FILE;;
# ERR=1; Not needed, default
quit;
} fi;
# ERR is '1' by default, change it to '0' when everything is OK:
ERR=0; quit;
# That's all, folks !
Some might wonder, why the scripts live in /home/bin/Backup rather than /usr/bin or some 'normal' directory.
This is because I have a habit to have three HD:s in my servers: one for the system, another for the /home and the third, the largest for the /BACKUP. I move /root, /var/www to /home and so it is MUCH easier to update system, make backups and recover broken systems. It is enough to backup /home and /etc.
It is very near I could make the whole system disk RO.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.