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.
Hello forum friends, I have the following bash script (which works perfectly), the code is as follows:
Code:
#!/bin/bash
# Compile big TeX proyect
# Set work dir
DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Take name for proyect and create dir (mandato...)
echo Enter Name of proyect
read NAME
mkdir -p $DIR/backup/$NAME/{book,screen,legal,booklet}
echo "El Arbol de directorios para $NAME ha sido creado"
# First Option
# Compiling book (2 run)
for file in $DIR/source/book/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/book/ "$file" >/dev/null 2>&1 &&
pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/book/ "$file" >/dev/null 2>&1
done
echo "El Libro se ha creado con exito!"
# Second Option
# Compiling screen
for file in $DIR/source/screen/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/screen/ "$file" >/dev/null 2>&1
done
echo "Las Presentaciones se han creado con exito!"
# Third Option
# Compilando legal
for file in $DIR/source/legal/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/legal/ "$file" >/dev/null 2>&1
done
echo "El formato LEGAL se ha creado con exito!"
# Fourth Option
cp -R $DIR/source/facsimil/ /$DIR/backup/$NAME/
for file in $DIR/source/booklet/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/facsimil "$file" >/dev/null 2>&1
done
cd $DIR/backup/$NAME/facsimil &&
for file in *.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/booklet/ "$file" >/dev/null 2>&1
done
# Clean temp files and facsimil dir
rm -rf $DIR/backup/$NAME/facsimil/ &&
find $DIR/backup/$NAME/ -regextype posix-awk -regex "(.*.log|.*.toc|.*.xwm|.*.out|.*.aux)" -exec rm -rf {} \; &&
cd $DIR/backup/ &&
# Create back folder
tar -c --xz -f $NAME-$(date +%Y%m%d).tar.xz $NAME/
echo "El respaldo $NAME.tar.xz se ha creado con exito!"
# Move proyect
mv $DIR/backup/$NAME/ $DIR/store/
echo "The $NAME proyect its done"
exit 0
but, I would like to run it in parts, that is, add options to run.
My idea is to add the following
- book (create book)
- booklet (create booklet)
- screen (create screen)
- legal (make legal)
- all (all formats)
try to get married, but did not get what he wanted (I should clarify that I am not a programmer, and I believe it from google, this and other forums Linux users) if you help me with some example, or tell me I should improve on this script, would appreciate it.
regards
Pablo
If I may, I'd like to first make a formatting suggestion.
It looks like a well-written script, much cleaner than many I've seen. But it's not very readable. You really need to use a lot more whitespace. Indent all your sub-commands evenly, and separate logical sections with empty lines. In other words, visually separate blocks of code that go together.
Next, please clarify your request a bit more. You want to add some features, ok. But what is the actual problem you're having in doing so?
If you want to know how to add command "flags" (e.g. something like "-b bookname" ), the usual technique is to use getopts.
QUOTE ALL OF YOUR VARIABLE SUBSTITUTIONS. You should never leave the quotes off a parameter expansion unless you explicitly want the resulting string to be word-split by the shell (globbing patterns are also expanded). This is a vitally important concept in scripting, so train yourself to do it correctly now. You can learn about the exceptions later.
Also, since environment variables are generally all upper-case, it's good practice to keep your own user variables in lower-case or mixed-case to help differentiate them.
Last edited by David the H.; 08-16-2012 at 08:24 AM.
Reason: addon
#!/bin/bash
# Compile big TeX proyect
# Set work dir
DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo Ingrese el nombre del proyecto
read NAME
echo 'Ingresa los parámetros'
read par
case $par in
-b|book)
mkdir -p $DIR/backup/$NAME/book &&
echo "Creando libro para $NAME"
for file in $DIR/source/book/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/book/ "$file" >/dev/null 2>&1 &&
pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/book/ "$file" >/dev/null 2>&1
done
echo "Done!"
;;
-l|legal)
mkdir -p $DIR/backup/$NAME/legal &&
for file in $DIR/source/legal/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/legal/ "$file" >/dev/null 2>&1
done
echo "Done!"
;;
-f|facsimil)
mkdir -p $DIR/backup/$NAME/booklet
cp -R $DIR/source/facsimil/ /$DIR/backup/$NAME/ &&
for file in $DIR/source/booklet/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/facsimil "$file" >/dev/null 2>&1
done &&
cd $DIR/backup/$NAME/facsimil &&
for file in *.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/booklet/ "$file" >/dev/null 2>&1
done &&
rm -rf $DIR/backup/$NAME/facsimil/
;;
-s|screen)
mkdir -p $DIR/backup/$NAME/screen &&
for file in $DIR/source/screen/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/screen/ "$file" >/dev/null 2>&1
done
echo "Done!"
;;
*)
echo "The big TeX Proyect"
echo "Usage: $0 {book|legal|facsimil|screen}"
echo " book : Crea libro con marcas de agua."
echo " legal : Crea las guías en formato legal."
echo " screen : Crea las presentaciones en pdf."
echo " facsimil : Crea los facsímiles en pdf."
;;
esac
# Clean temp files
find $DIR/backup/$NAME/ -regextype posix-awk -regex "(.*.log|.*.toc|.*.xwm|.*.out|.*.aux)" -exec rm -rf {} \; &&
cd $DIR/backup/ &&
# Create backup folder
tar -c --xz -f $NAME-$(date +%Y%m%d).tar.xz $NAME/
echo "El respaldo del proyecto $NAME ha creado con exito!"
# Move proyect
mv $DIR/backup/$NAME/ $DIR/store/
echo "FINISH"
exit 0
but stay trapped to give more than one option to the script (-b -f -s -l and create the option - all).
Now I focus on the problem, I would like it to work well
Code:
sh script.sh name -p -l -s -f
where "-p,-l,-s,-f" may be present or not. If the structure is not "case" allows me to do this, I can only run "one option" and not 2 or 3 same time, will review the link you give me and comment later.
grateful
Pablo
Did you read David's post? He has suggested you look at getopts which will do exactly what you are looking for.
I would add that you have already given an interpreter inside the script, so to then run it with sh would seem pointless. Simply make it executable and run as you like.
In any case, we're on the right track; testing possible options with a case statement. The secret to the next step is to embed the whole thing inside a loop, allowing you to iterate over multiple inputs.
getopts simply provides a ready-built way to organize and parse such input options, particularly ones that can be followed by secondary arguments.
Thanks for comment, check the links above and let me try to adapt to my needs, I stay with this option, it is quite clear to read (looks like perl structure), now the new script its :
Code:
#!/bin/bash
# Compile big TeX proyect
# Set work dir (good idea)
DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Take proyect name from input
echo Ingrese el nombre del proyecto
read NAME
# Setting initial options
BOOK=1
LEGAL=0
SCREEN=0
FACSIMIL=0
# start script options
while [ $# -gt 0 ]; do
case $1 in
-h|-help|--help)
echo "The big TeX Proyect"
echo "Usage: $0 -option1 -option2 --option3 --option4"
echo " -b|book : Crea libro con marcas de agua."
echo " -l|legal : Crea las guías en formato legal."
echo " -s|screen : Crea las presentaciones en pdf."
echo " -f|facsimil : Crea los facsímiles en pdf."
echo " -h|-help : Muestra la ayuda y sale."
exit 0
;;
-b|book)
shift
BOOK=1
;;
-l|legal)
shift
LEGAL=1
;;
-f|facsimil)
shift
FACSIMIL=1
;;
-s|screen)
shift
SCREEN=1
;;
*)
echo "Parametro no admitido: $1. Use \"$0 -h\" for help."
exit 0
;;
esac
shift
done
# end options
# Compiling book
if [ $BOOK=0 ]; then
mkdir -p $DIR/backup/$NAME/book &&
echo "Creando libro para $NAME"
for file in $DIR/source/book/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/book/ "$file" >/dev/null 2>&1 &&
pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/book/ "$file" >/dev/null 2>&1
done
echo "BOOK Done!"
else
echo "BOOK FAIL!"
fi
# Compiling legal
if [ "$LEGAL"=1 ]; then
mkdir -p $DIR/backup/$NAME/legal &&
for file in $DIR/source/legal/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/legal/ "$file" >/dev/null 2>&1
done
echo "LEGAL Done!"
else
echo "LEGAL FAIL!"
fi
# Compiling screen
if [ "$FACSIMIL"=1 ]; then
mkdir -p $DIR/backup/$NAME/booklet
cp -R $DIR/source/facsimil/ /$DIR/backup/$NAME/ &&
for file in $DIR/source/booklet/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/facsimil "$file" >/dev/null 2>&1
done &&
cd $DIR/backup/$NAME/facsimil &&
for file in *.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/booklet/ "$file" >/dev/null 2>&1
done &&
rm -rf $DIR/backup/$NAME/facsimil/
echo "FACSIMIL Done!"
else
echo "FACSIMIL FAIL!"
fi
# Compiling screen
if [ "$SCREEN"=1 ]; then
mkdir -p $DIR/backup/$NAME/screen &&
for file in $DIR/source/screen/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/screen/ "$file" >/dev/null 2>&1
done
echo "SCREEN Done!"
else
echo "SCREEN FAIL!"
fi
# end compiling files
# Clean temp files
find $DIR/backup/$NAME/ -regextype posix-awk -regex "(.*.log|.*.toc|.*.xwm|.*.out|.*.aux)" -exec rm -rf {} \; &&
cd $DIR/backup/ &&
# Create backup folder
tar -c --xz -f $NAME-$(date +%Y%m%d).tar.xz $NAME/
echo "El respaldo del proyecto $NAME ha creado con exito!"
# Move proyect
mv $DIR/backup/$NAME/ $DIR/store/
echo "FINISH"
exit 0
It does not work as they desire, the idea is to run for options, so as it is generated all at once,
What should I change? Or this is not the best way to achieve what I want? my idea is "sh script.sh -option1-option2..." enter, asks the name of the project and runs whit options.
regards
Pablo
I am getting a little confused ... are you going to try the getopts suggestion?
Yes, I was trying more than one option but I think I found the solution (partial), this is the result of the script:
Code:
#!/bin/bash
# Compile big TeX proyect
# Set work dir (good idea)
# Using only case (not if ...then)
DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Take proyect name from input
echo Ingrese el nombre del proyecto
read NAME
# start script options
while [ $# -gt 0 ]; do
case $1 in
-h|-help|--help)
echo "The big TeX Proyect"
echo "Usage: $0 -b -l -f -s -h"
echo " -b|book : Crea libro con marcas de agua."
echo " -l|legal : Crea las guías en formato legal."
echo " -s|screen : Crea las presentaciones en pdf."
echo " -f|facsimil : Crea los facsímiles en pdf."
echo " -h|-help : Muestra la ayuda y sale."
exit 0
;;
-b|book)
#shift
BOOK=1
mkdir -p $DIR/backup/$NAME/book &&
echo "Creando book $NAME"
for file in $DIR/source/book/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/book/ "$file" >/dev/null 2>&1 &&
pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/book/ "$file" >/dev/null 2>&1
done
echo "BOOK Done!"
;;
-l|legal)
#shift
LEGAL=1
mkdir -p $DIR/backup/$NAME/legal &&
echo "Creando Legal $NAME"
for file in $DIR/source/legal/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/legal/ "$file" >/dev/null 2>&1
done
echo "LEGAL Done!"
;;
-f|facsimil)
#shift
FACSIMIL=1
mkdir -p $DIR/backup/$NAME/booklet &&
echo "Creando facsimil $NAME"
cp -R $DIR/source/facsimil/ /$DIR/backup/$NAME/ &&
for file in $DIR/source/booklet/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/facsimil "$file" >/dev/null 2>&1
done &&
cd $DIR/backup/$NAME/facsimil &&
for file in *.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/booklet/ "$file" >/dev/null 2>&1
done &&
rm -rf $DIR/backup/$NAME/facsimil/
echo "FACSIMIL Done!"
;;
-s|screen)
#shift
SCREEN=1
mkdir -p $DIR/backup/$NAME/screen &&
echo "Creando screen $NAME"
for file in $DIR/source/screen/*.tex
do pdflatex -interaction=batchmode -output-directory=$DIR/backup/$NAME/screen/ "$file" >/dev/null 2>&1
done
echo "SCREEN Done!"
;;
*)
echo "Parametro no admitido: $1. Use \"$0 -h\" for help."
exit 0
;;
esac
shift
done
# end compiling files
# Clean temp files
find $DIR/backup/$NAME/ -regextype posix-awk -regex "(.*.log|.*.toc|.*.xwm|.*.out|.*.aux)" -exec rm -rf {} \; &&
cd $DIR/backup/ &&
# Create backup folder
tar -c --xz -f $NAME-$(date +%Y%m%d).tar.xz $NAME/
echo "El respaldo del proyecto $NAME ha creado con exito!"
# Move proyect
mv $DIR/backup/$NAME/ $DIR/store/
echo "FINISH"
exit 0
works almost as i want, but if the script call whit no options, this show me an error (and i would like to show me the help), which is not the correct use of "shift" (but that is responsible for moving the parameters entered). if you have any comments (format and eliminate code, correct use of shift) is appreciated.
Saludos
Pablo
Last edited by pablgonz; 08-17-2012 at 06:19 AM.
Reason: spelleng
Well the simple solution to the no options problem would be to test for no options prior to running the script. This allows you to catch it but based on your current format would also
require you to duplicate the help section (perhaps a function would make this simpler)
You could reduce this to a single call to the help option if you also test for the -h and so on options are anywhere in $@, which is all options passed in
This is the forward end of the script, add the HELP function as, in one test to see if there was the directory with the name input, also has a test that shows if the help does not enter parameters. I only have two problems to solve:
1. Display "HELP" without having to enter NAME
2. Showing error when entering an option without "-", "--"
I think I could move up here with the links they gave me and the other post on the forum, but need help in this part of the most wise.
The Best
Pablo (Using fedora 17 and TeXLive2012)
The code:
Code:
#!/bin/bash
# Compile big TeX proyect 2012
# mycomp.sh
# Set work dir (good idea)
DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Help funtion
HELP(){
echo "The big TeX Proyect 2012"
echo "Uso:sh $0 -b -l -f -s -h"
echo " -b|book : Crea libro con marcas de agua."
echo " -l|legal : Crea las guías en formato legal."
echo " -s|screen : Crea las presentaciones en pdf."
echo " -f|facsimil : Crea los facsímiles en pdf."
echo " -h|-help : Muestra la ayuda y sale."
}
# end help funtion
# If no argument given, show HELP and exit
if [ $# -lt 1 ] ;then
HELP
exit 0
fi
# Declaring getopt options
if ! options=$(getopt -o blsfh -l book,legal,facsimil,screen,help -- "$@");then
# getopt will put out an error message
exit 0
fi
set --$options
# Take proyect name from input
echo Ingrese el nombre del proyecto
read NAME
if [ -d "$DIR/store/$NAME" ]; then
echo "Ya existe $NAME intente con otro nombre"
exit 0
fi
# start script options
while [ $# -gt 0 ]; do
# Case for param
case $1 in
-h|--help)
HELP
exit 0 ;;
# Crea el libro desde source
-b|--book)
mkdir -p $DIR/backup/$NAME/book &&
echo "Creando book $NAME"
for file in $DIR/source/book/*.tex
do pdflatex -output-directory=$DIR/backup/$NAME/book/ "$file" >/dev/null 2>&1 &&
pdflatex -output-directory=$DIR/backup/$NAME/book/ "$file" >/dev/null 2>&1
done
echo "BOOK Done!";;
# Crea las guias en formato 8.5x13 pulgadas
-l|--legal)
mkdir -p $DIR/backup/$NAME/legal &&
echo "Creando Legal $NAME"
for file in $DIR/source/legal/*.tex
do pdflatex -output-directory=$DIR/backup/$NAME/legal/ "$file" >/dev/null 2>&1
done
echo "LEGAL Done!";;
# Crea las guias tipo libro plegado 6.5x8.5 in
-f|--facsimil)
mkdir -p $DIR/backup/$NAME/booklet &&
echo "Creando facsimil $NAME"
cp -R $DIR/source/facsimil/ /$DIR/backup/$NAME/ &&
for file in $DIR/source/booklet/*.tex
do pdflatex -output-directory=$DIR/backup/$NAME/facsimil "$file" >/dev/null 2>&1
done &&
cd $DIR/backup/$NAME/facsimil &&
for file in *.tex
do pdflatex -output-directory=$DIR/backup/$NAME/booklet/ "$file" >/dev/null 2>&1
done &&
cd $DIR/
rm -rf $DIR/backup/$NAME/facsimil/
echo "FACSIMIL Done!";;
# Crea las presentaciones usando pdfscreen
-s|--screen)
mkdir -p $DIR/backup/$NAME/screen &&
echo "Creando screen $NAME"
for file in $DIR/source/screen/*.tex
do pdflatex -output-directory=$DIR/backup/$NAME/screen/ "$file" >/dev/null 2>&1
done
echo "SCREEN Done!";;
# variousssss
(--) shift; break;;
(-*) echo "$0: error - $1" 1>&2; exit 1;;
(*) break;;
esac
shift
done
# Clean temp files
find $DIR/backup/$NAME/ -regextype posix-awk -regex "(.*.log|.*.toc|.*.xwm|.*.out|.*.aux)" -exec rm -rf {} \; &&
cd $DIR/backup/ &&
# Create backup folder
tar -c --xz -f $NAME-$(date +%Y%m%d).tar.xz $NAME/
echo "El respaldo del proyecto $NAME ha creado con exito!"
# Move proyect to store
mv $DIR/backup/$NAME/ $DIR/store/
echo "FINISH"
exit 0
Simply place your "-h|--help" in the same test as no options
Quote:
2. Showing error when entering an option without "-", "--"
You may need to consider the complexity here. This would mean that you never pass an argument (not a switch) that will not be the name of a switch.
I am not saying it is not correct but it does mean you are limiting the user in an unusual way.
It also appears that you are using getopts in an unusual way. Again not wrong but the the general idea would be to call getopts in your loop and do
the processing in one go.
You may like to look up here documents for your HELP function.
Also, the case calls seem to have a large amount of repetition with slight changes which would normally point to creating some functions.
Simply place your "-h|--help" in the same test as no options
could give me an example of this (my attempts have not worked),as the "-h" is within "case" needs to go "NAME" first, which is not ideal.
Quote:
Originally Posted by grail
You may need to consider the complexity here. This would mean that you never pass an argument (not a switch) that will not be the name of a switch. I am not saying it is not correct but it does mean you are limiting the user in an unusual way.
It is built like this script, I have no experience in bash, perl is most common for me, but at this bash was the best option, the idea is to check error (and exit) if the parameter is not a valid option.
Quote:
Originally Posted by grail
It also appears that you are using getopts in an unusual way. Again not wrong but the the general idea would be to call getopts in your loop and do the processing in one go.
This is what I have in mind, the problem goes for $NAME, did not find how to include type "sh script.sh -b-f-l-s Name whit spaces and more ...", so I want to leave the function "HELP" before the "case" and verify that the parameters entered are valid, then income $NAME and run all.
Quote:
Originally Posted by grail
You may like to look up here documents for your HELP function. Also, the case calls seem to have a large amount of repetition with slight changes which would normally point to creating some functions.
I thought the truth, the functions are being as "sub run" but in this case it is better to leave it, for routing and call pdftex as I bring more of any inconvenience.
Grateful for your answer (and links)
Pablo
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.