Code: Select all
myprogram --test
Code: Select all
myprogram --test
See fourth Bruce's post here: http://www.murga-linux.com/puppy/viewto ... 1&start=30.suttiwit123 wrote:How do I make a bash file with parameters on it like:Code: Select all
myprogram --test
Code: Select all
#!/bin/bash
if [ "$1" = "--test" ] ; then
echo one command
echo second command
fi
Code: Select all
j=0
for i in `seq 1 $#` ; do
j=$((j+1))
PARAM=`echo "$*" | cut -f $i -d ' '`
echo '$'$j' ='"$PARAM"
PARAM[$j]="$PARAM"
echo ${PARAM[$j]}
done
for i in $(seq 1 $j) ; do
case ${PARAM[$i]} in
--test) do_test_function ;;
--help) do_help_function ;;
*) do_help_function ;;
esac
done
My code will work as presented. Any questions about it and I'll explain.suttiwit123 wrote:Thanks for all your posts, I will try and see if it works.
This is a very straightforward question posed by suttiwit123. It is a beginner's level question. I have heart for teaching beginners. I have demonstrated my heart for this subject in hundreds of posts.suttiwit123 wrote:How do I make a bash file with parameters on it like::?:Code: Select all
myprogram --test
Code: Select all
# This is a comment
# Make a variable called "j" that is just the text "0"
# Although it looks like a number in other places it can be used
# as just a string
j=0
# This is not the best way to code this but it works as an example
# The "$#" thing returns the number of "words" as parameters on
# the command line
# "seq 1 5" returns the numbers 1 2 3 4 5
# "for i in 1 2 3 4 5" loops 5 times with "i" being each value
for i in `seq 1 $#` ; do
# The next line looks incorrect
# j=$(( $j + 1 )) is what I would do
# "$j" just inserts the text that is currently in "j" "0" the first time
# "$(( 0 + 1 ))" does integer math resulting in "1" as a string
#
j=$((j+1))
# This next bit is very dreadful but here goes
# "$*" is just the list of all the parameters as a string
# echoing it through "|" means it goes to the routine called "cut"
# cut takes a "-f1" argument to mean the first field in the input
# the "-d ' '" makes the fields divided by spaces
PARAM=`echo "$*" | cut -f $i -d ' '`
# This line just composes a message to print
echo '$'$j' ='"$PARAM"
# This makes an array called "PARAM" with each element a string
PARAM[$j]="$PARAM"
# This is how you can get elements from an array variable.
# For most cases ${XXX} and $XXX work the same but for
# arrays you need to use the "{}" to keep bash from trying to find
# the non-array version.
# echo "$PARAM[1]" will result in "[1]" because "$PARAM"
# is not found
echo ${PARAM[$j]}
# End this loop
done
# The rest should not be sort of obvious now
for i in $(seq 1 $j) ; do
case ${PARAM[$i]} in
--test) do_test_function ;;
--help) do_help_function ;;
*) do_help_function ;;
esac
done
Code: Select all
#!/bin/bash
help_function() {
echo "this is the help function"
}
test_function() {
echo "this is the test function"
}
case $1 in
--test) test_function ;;
*) help_function ;;
esac
Code: Select all
#!/bin/bash
#
# mybashprg v1.0
# This is just an example of retrieving command line parameters.
# usage: mybashprg -pn picture_name.png -t 10 [-od output_dir] -test ...
# If you want to set your command line up with this type
# of format, this method of reading the parameters works
# pretty slick.
#
# Using the "for" and the "case" statements as follows
# lets you enter the parameters in any order.
# -------------------------------------------------------
# This checks to make sure that at least one command line
# parameter is passed.
# "$#" is the number of command line parameters entered.
if [ $# = 0 ] ; then
echo "-------------------------------------------"
echo " No options / parameters passed "
echo "-------------------------------------------"
exit 1
fi
# -------------------------------------------------------
# Read command line parameters.
#
# The "for arg" will step through each parameter
# on the command line.
#
# The "shift" causes the current $1 to be dropped
# from the arg list, and the remaining parameters
# shifted to the front of the list. So the old $2
# becomes $1; and so forth.
#
# When there is a "match" in the case statement,
# the block of code following the match is executed.
# The double semi-colons ";;" marks the end of
# the block of code.
#
# By pre-setting variables, they have a default value
# in case they aren't assigned on the command line.
display_time=10
output_dir="~/mysaveDir"
crossfade=10
# -------------------------------------------------------
for arg
do
case "$arg" in
-pn) shift; picture_name="$1" ; shift ;;
-od) shift; output_dir="$1" ; shift ;;
-t) shift; display_time="$1" ; shift ;;
-ed) shift; effect_delay="$1" ; shift ;;
-b) shift; background="$1" ; shift ;;
-s) shift; subtitle="$1" ; shift ;;
-a) shift; audio_file="$1" ; shift ;;
-c) shift; crossfade="$1" ; shift ;;
-et) shift; effect_type="$1" ; shift ;;
-test) echo "I no take stinking test" ; exit 1;;
esac
done
# Here the "block of code" is simply assigning values to
# variable names. But any number of bash commands or
# function calls could be included in the block of code.
#
# -------------------------------------------------------
# Examples of the case statement are usually written like this:
case $arg in
A)
echo "You passed A"
;;
[0-9])
echo "You passed a number"
;;
Gas)
ls -la
du
cat *.txt
find / -type d -name Gas -print
;;
esac
# Depending on your needs, I think the first example of the
# case statement is easier to decipher and maintain.
Code: Select all
for arg
do
case "$arg" in
-pn) shift; picture_name="$1" ; shift ;;
-od) shift; output_dir="$1" ; shift ;;
-t) shift; display_time="$1" ; shift ;;
*) X=`echo "$1" | grep -oe "-pn" -oe "-od" -oe "-t"`
[ "$X" ] || exit ;;
esac
done
I think its a good template as a way of demonstrating how to pass certain types of arguments. And you made some good catches and an important point.jpeps wrote:Adding a default "*)" for unmatched args exits to prevent shifting errors:
Code: Select all
for arg do case "$arg" in -pn) shift; picture_name="$1" ; shift ;; -od) shift; output_dir="$1" ; shift ;; -t) shift; display_time="$1" ; shift ;; *) X=`echo "$1" | grep -oe "-pn" -oe "-od" -oe "-t"` [ "$X" ] || exit ;; esac done
Hi Bruce,Bruce B wrote:
I also think you overlooked something. Maybe in copy and paste. I'm stuck figuring out how line one works.
Code: Select all
#!/bin/sh
for arg
do
case "$arg" in
-pn) shift; echo "picture_name="$1"" ; shift ;;
-od) shift; echo "output_dir="$1"" ; shift ;;
-t) shift; echo "display_time="$1"" ; shift ;;
*) X=`echo "$1" | grep -oe "-pn" -oe "-od" -oe "-t"`
[ "$X" ] || exit ;;
esac
done
Code: Select all
/mnt/sda2/Desktop $ ./testit -pn SomeName -od /mnt/sda2 -t 8:30PM
picture_name=SomeName
output_dir=/mnt/sda2
display_time=8:30PM
/mnt/sda2/Desktop $ ./testit -pn SomeName UNMATCHED -od/mnt/sda2 -t 8:30PM
picture_name=SomeName
Code: Select all
display_time=10
output_dir="~/mysaveDir"
crossfade=10
Code: Select all
# Run the parameter through cut and use the -b1 to take just byte 1
FIRST=`echo "$1" | cut -b1`
# If it starts with a "-" then do as normal
if [[ "$FIRST" == "-" ]] ; then
case
...
esac
else
# Without a "-" is assumed to be the file to mung
FILENAME=$1
shift
fi
Code: Select all
# Check if each option has a parameter passed with it.
# (ie check for even number of parameters on cmd line)
#
if [ $(( $# % 2 )) != 0 ] ; then
echo ; echo
echo "-----------------------------------------------"
echo "Check your command line. Option(s) specified "
echo "without matching parameter(s) (or vice-versa ;^)"
echo "-----------------------------------------------"
echo $0 $*
echo "-------------------"
exit
fi
These checks aren't bulletproof. But what they don't catch$# Is the number of command line arguments.
% This does division and returns the remainder. (Sometimes called modulo)
In this case, divide by 2. If the remainder
isn't zero, it's not an even number.
$(( )) Evaluate the enclosed expression and use it here.
!= Not equal to.
echo $0 $* This prints out the command and parameters you entered.
$0 Is the command name, in this case the name of the bash
script you are running.
$* Is all the parameters in a single string.
Code: Select all
#!/bin/sh
#template to wrap other filemanagers for use in place of ROX-Filer
USERF=""
while ([ $1 ]) do
case $1 in
-b)ARGS=$ARGS" "$1" ";shift;USERF=1;;
--border=*)ARGS=$ARGS" "$1;USERF=1;;
-B)ARGS=$ARGS" "$1" "$2;shift;USERF=1;;
--bottom=*)ARGS=$ARGS" "$1;USERF=1;;
-c)ARGS=$ARGS" "$1" "$2;shift;USERF=1;;
--client-id=*)ARGS=$ARGS" "$1;USERF=1;;
-d)shift;ARGS=$ARGS" "$1;; #as far as I can tell -d is useless or should use dirname
--dir=*)ARGS=$ARGS" "`echo $1 |cut -d "=" -f2`;;
-D)ARGS=$ARGS" "$1" "$2;shift;USERF=1;;
--close=*)ARGS=$ARGS" "$1;USERF=1;;
-h|--help)ARGS=$ARGS" "$1;;
-l)ARGS=$ARGS" "$1" "$2;shift;USERF=1;;
--left=*)ARGS=$ARGS" "$1;USERF=1;;
-m)ARGS=$ARGS" "$1" "$2;shift;USERF=1;; #alternatively use file or xdg-*
--mime-type=*)ARGS=$ARGS" "$1;USERF=1;;
-n|--new)ARGS=$ARGS" "$1;USERF=1;;
-p)ARGS=$ARGS" "$1" "$2;shift;USERF=1;; #PCMan-FM has its own "pinboard"
--pinboard=*)ARGS=$ARGS" "$1;USERF=1;;
-r)ARGS=$ARGS" "$1" "$2;shift;USERF=1;;
--right=*)ARGS=$ARGS" "$1;USERF=1;;
-R)ARGS=$ARGS" "$1;USERF=1;;
--RPC)ARGS=$ARGS" "$1;USERF=1;;
-s)ARGS=$ARGS" "$1" "$2;shift;USERF=1;;
--show=*)ARGS=$ARGS" "$1;USERF=1;;
-S)ARGS=$ARGS" "$1;USERF=1;;
--rox-session)ARGS=$ARGS" "$1;USERF=1;;
-t)ARGS=$ARGS" "$1" "$2;shift;USERF=1;;
--top=*)ARGS=$ARGS" "$1;USERF=1;;
-u)ARGS=$ARGS" "$1" "$2;shift;USERF=1;;
--user)ARGS=$ARGS" "$1;USERF=1;;
-U)ARGS=$ARGS" "$1" "$2;shift;USERF=1;; #alternatively use defaultbrowser ...
--url=*)ARGS=$ARGS" "$1;USERF=1;;
-v|--version)ARGS=$ARGS" "$1;; #most file managers have this switch
-x)ARGS=$ARGS" "$1" "$2;shift;USERF=1;;
--examine=*)ARGS=$ARGS" "$1;USERF=1;;
*)ARGS=$ARGS" "$1;; #not a rox option, so probably ok to just pass it.
esac
shift
done
[ $USERF ] && /usr/local/apps/ROX-Filer/ROX-Filer $ARGS || defaultfilemanager $ARGS