Bash optional parameters and setting to default - bash

I have a bash upload script which looks like this -
if [ $# -lt 2 ]
then
echo usage: $0 /path/to/mvn /path/to/libs [procs] [groupId]
fi
MVN_EXE=$1
LIB_DIR=$2
PROCS=10
GROUPID=$4:-'default'
if [ $# -gt 2 ]
then
PROCS=$3
fi
I want the GROUPID to be the 4th arg or to be set automatically to 'default'. Could I be advised on the correct syntax for this? A google search has given me this so far.
Would I then need to add an additional if search along the lines of -
if [$# -gt 3]
then
PROCS=$3
GROUPID=$4
fi
or just replace the original if statement with the new version?
Thanks

You just forgot the curly braces. You can use them to avoid the final if statement too:
if [ $# -lt 2 ]
then
echo usage: $0 /path/to/mvn /path/to/libs [procs] [groupId]
fi
MVN_EXE=$1
LIB_DIR=$2
PROCS=${3:-10}
GROUPID=${4:-'default'}

Correct syntax is:
GROUPID=${4:-'default'}

Related

Stumped: this script does not work as expected?

I'm stumped when writing a simple script.
Essentially the $u variable is does not take u=$USER. Here's the code:
#!/bin/bash
if [ $# > 0 ] ; then
u=$1
else
u=$USER
fi
echo $u
The fix
You have 2 equally viable options:
Use -gt
if [ $# -gt 0 ]
Use double brackets [[ (Does a lexicographic comparison but will work for this case)
if [[ $# > 0 ]]
Why?
When you did if [ $# > 0 ] the > was treated like an output redirection command similar to echo "foo" > file.txt. You might notice you have created a file named 0 someplace after executing:
if [ $# > 0 ]
When deciding between using [...] or [[...]] many find the answer is to use double brackets
Getting fancy
Now if what you'd really like to do is write a script that gives a default value to the u variable if none is provided by the first argument I would recommend using a neat bash syntax trick for implementing default values
u=${1:-${USER}}
I believe I found the answer using double brackets
#!/bin/bash
if [[ $# > 0 ]] ; then
u=$1
else
u=${USER}
fi
echo $u
Not sure I fully understand why it failed with single brackets.

bash: if statement with multiple checks

In my bash script I need to check if the first CLI is defined and the second one is an existing file
Here is what I have:
if [!$2] && [! -f $1 ]; then
....
fi
So $2 should exist (string) and $1 should be the existing file on the filesystem!
Any suggestions ?
If by suggestions you mean what do I need to make it work, then what you need to do is to add spaces around brackets. Also it is good to quote the variables:
if [ -n "$2" ] && [ ! -f "$1" ]; then
...
fi
From man test:
-n STRING
the length of STRING is nonzero

How can I check the length of an argument in bash?

Let's say I want to check if the first argument is 2 characters long. I tried
if [ ${#$1} -e 2]
but it doesn't work.
Don't use $ in the parameter expansion
Use -eq for numerical comparison
Add a space before the ]:
All in all:
if [ ${#1} -eq 2 ]
then
echo "It's two characters long"
fi

Removing files in Unix using bash

I'm trying to delete a large amount of files from my computer, and I'm trying to write a bash script to do so using the rm command. What I want to know is how to do equality in bash, and why my code (posted below) won't compile. Thank you for your help!
#!/bin/bash
# int-or-string.sh
b="0000"
c="linorm"
f=500
e1=2
e2=20
e3=200
e4=2000
for i in {0..10000}
do
a=$(($f*$i))
if ["$i" -eq "$e1"]
then
b="000"
echo $b$
fi
if ["$i" -eq "$e2"]
then
b='00'
fi
if ["$i" -eq "$e3"]
then
b='0'
fi
if ["$i" -eq "$e4"]
then
b =''
fi
if [bash$ expr "$i" % "$e3$ -ne 0]
then
d = $b$c$a
rm d
fi
done
Shell scripts aren't compiled at all.
You need spaces after your [ and before your ].
if [ "$i" -eq "$e1" ]
There's an errant bash$ in there you probably don't want at all. It should probably be a $() operator:
if [ $(expr "$i" % "$e3") -ne 0 ]
You can't have spaces around the = in bash. For example, change b ='' to b='' and d = $b$c$a to d=$b$c$a.
echo $b$ looks like it should be echo $b.
Shell script does not compile it is a scripting language.
Try to fix this line :
if [bash$ expr "$i" % "$e3$ -ne 0]
Make it like below :
if [ $(expr "$i" % "$e3$") -ne 0 ]
You need spaces around the square brackets. The [ is actually a command, and like all commands needs to be delineated by white space.
When you set values for variables in shell, you do not put spaces around the equals signs.
Use quotation marks when doing comparisons and setting values to help delineate your values.
What happens if none of the if conditions are true, and $b isn't set.
What is the logic behind this code. It seems to be a bunch of random stuff. You're incrementing $ from 1 to 10000, but only setting the value of $b on only four of those values. Every 200 steps, you delete a file, but $b may or may not be set even though it's part of the file name.
Did you write this program yourself? Did you try to run it? What errors were you getting? Did you look at the lines referenced by those errors. It looks like you included the bash$ prompt as part of the command.
There were plenty of errors, and I've cleaned most of them up. The cleaned up code is posted below, but it still doesn't mean it will do what you want. All you said is you want to delete "a large amount of files" on your computer, but gave no other criteria. You also said "What I want to know is how to do equality in bash" which is not the question you stated in you header.
Here's the code. Note the changes, and it might lead to whatever answer you were looking for.
#!/bin/bash
# int-or-string.sh
b="0000"
c="linorm"
f=500
e1=2
e2=20
e3=200
e4=2000
for i in {0..10000}
do
a=$(($f*$i))
if [ "$i" -eq "$e1" ]
then
b="000"
elif [ "$i" -eq "$e2" ]
then
b='00'
elif [ "$i" -eq "$e3" ]
then
b='0'
elif [ "$i" -eq "$e4" ]
then
b=''
fi
if ! $(($i % $e3))
then
d="$b$c$a"
rm "$d"
fi
done
ERRORS:
Spaces around the [ and ]
The rm "$d" command was originallyrm dwhich would just remove a file namedd`.
if/then statement converted to if/else if.
Rewrote [ $(expr "$1" % "$e3") -ne 0 ].
No need for expr since BASH has $((..)) syntax.
No need for test command ([) since if automatically evaluates zero to true and non-zero to false.
Added quotes.

Argument Checking Problem in Bash Script

So basically I am trying to check the arguments that are passed into the script. If it has three arguments and the third argument is a 1, then I want it to continue. I also want it to continue if it has four arguments and the third argument is not a 1.
So basically I thought that I could just do...
if ([ $# -ne 3 ] and [ "$3" -ne "2" ])
then
exit 0
fi
However it seems that Bash does not have and's to use for if's,so then I figured that I could just use nested if's, however now it's complaining still. So this is what I have currently...
if [ $# -ne 3 ]
then
if [ "$3" -ne "1" ]
then
echo "Improper number of arguments.
FORMAT make-csv-data <STUDY> <TAG> <MODE> <SELECT>
Select can be left off if you want all data (Mode=1)
"
exit 0
fi
fi
if [ $# -ne 4 ]
then
if [ "$3" -ne "2" ]
then
echo "Improper number of arguments.
FORMAT make-csv-data <STUDY> <TAG> <MODE> <SELECT>
Select can be left off if you want all data (Mode=1)
"
exit 0
fi
fi
So where am I going wrong? Can I not nest if statements in Bash? Is there a super-zen way of doing this that I'm missing altogether?
Thanks for the any help you could give me.
New Problem...
Now, for some reason or another, the code isn't working at all. There are no errors or anything, it just doesn't work. It doesn't check the number of arguments. I've run the script with no arguments at all and it just skips it like it's not even there.
Weird part is that I was sure that the code was working yesterday. Come back today, not so much. Any ideas on what the problem is? (Sorry, but I have to remove the accepted answer on this.)
if [[ $# = 3 && "$3" != "1" ]]
then
echo "Improper number of arguments.
FORMAT make-csv-data <STUDY> <TAG> <MODE> <SELECT>
Select can be omitted if all data is required (Mode=1)
"
exit 0
fi
if [[ $# > 4 ]]
then
echo "Improper number of arguments.
FORMAT make-csv-data <STUDY> <TAG> <MODE> <SELECT>
Select can be omitted if all data is required (Mode=1)
"
exit 0
fi
EDIT II:
There are a few things that the Bash shell isn't liking about this script that I'm trying to do. I'll probably end up rewriting it in another scripting language and do a few more things that I have in mind for the project. Thanks for the help in any case.
if [ $# -ne 3 -a "$3" -ne "1" ]; then
exit 0
fi
For reference
-a = and
-o = or
Or, you could just use use:
if [[ $# != 3 && "$3" != "1" ]]; then
Please see:
http://bash-hackers.org/wiki/doku.php/commands/classictest#and_and_or
and
http://bash-hackers.org/wiki/doku.php/syntax/ccmd/conditional_expression
Since you're just checking exit/return values with "if", you need to provide something, e.g. a command, that provides meaningful ones based on your tests. [ is such a command, another possibility is the [[ keyword.
The actual correct examples already were mentioned by scragar above, I don't want to just repeat them :)

Resources