How can I check the length of an argument in bash? - 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

Related

Bash why quotes in while cycles make different behaviour?

I wanted to read an input $1 using parameters. I used this code:
while [ -n "$1" ]
do
case $1 in
-dt) do something;;
esac
shift
done
Why if I remove those quotes in the while instruction the script is stuck in a permanent loop? Quotes should let you evaluate a string making special characters like normal characters but I'm not inserting any special character in the input and anyway it has a different behavior with or without quotes
Without the quotes, when $1 is empty, [ -n $1 ] will become [ -n ] which means [ -n "-n" ] which is TRUE.
According to bash manual:
test and [ evaluate conditional expressions using a set of rules
based on the number of arguments.
0 arguments
The expression is false.
1 argument
The expression is true if and only if the argument is not null.
[...]

Argument isn't passed (bash)

I'm working with shell scripts.
I'm in the test section, where if an argument is passed:
The expression is true if, and only if, the argument is not null
And here I have implemented the following code:
[ -z $num ]; echo $?;
Your exit:
0
Why?
Firstly, [-z should be [ -z, otherwise you would be getting an error like [-z: command not found. I guess that was just a typo in your question.
It sounds like you're quoting the wrong part of the manual, which would apply to tests like this:
[ string ] # which is equivalent to
[ -n string ]
Either of which would return success (a 0) for a non-empty string.
With -z, you're checking that the length of the string is 0.
However, as always, be careful with unquoted variables, since:
[ -z $num ]
# expands to
[ -z ]
# which is interpreted in the same way as
[ string ]
i.e. your test becomes "is -z a non-empty string?", to which the answer is yes, so the test returns 0. If you use quotes around "$num" then the test does what you would expect.

Multiple If Statements in Bash Script

I am trying to make a bash script with the output based on the input.
My code looks like this:
#!/bin/bash
echo "Letter:"
read a
if a=3
then
echo "LOL"
fi
if a=4
then
echo "ROFL"
fi
But when I enter 3 or 4, I get both LOL and ROFL.
Is there a way for me to get LOL for 3 and ROFL for 4?
Sorry if I'm using incorrect terms and stuff, I'm new to bash scripting.
In bash, a=3 is an assignment, not a test. Use, e.g.:
if [ "$a" = 3 ]
Inside [...], the equal sign tests for string (character) equality. If you want to test for numeric value instead, then use '-eq` as in:
if [ "$a" -eq 3 ]
The quotes around "$a" above are necessary to avoid an "operator" error when a is empty.
bash also offers a conditional expressions that begin with [[ and have a different format. Many like the [[ format better (it avoids, for example, the quote issue mentioned above) but the cost is loss of compatibility with other shells. In particular, note that dash, which is the default shell (/bin/sh) for scripts under Debian-derived distributions, does not have [[.
Bash thinks you're trying to assign a variable by saying a=3. You can do the following to fix this:
Use the = operator whilst referencing the variable with a $, like so: if [[ $a = 3 ]]
Use the -eq operator, which is special and doesn't require you to reference the variable with a $, but may not be compatible with all sh-derived shells: if [[ a -eq 3 ]]. If you wish to use -eq without Bash reference the variable: if [[ $a -eq 3 ]]
Note:
The double square brackets [[ ... ]] are a preferred format with specifically Bash conditionals. [ ... ] is good with any sh-derived shell (zsh, tcsh, etc).
if a=3 will assign value 3 to variable a
unless a is readonly variable, if a=3 always returns TRUE
same for if a=4
To compare variable a with a value, you can do this if [ $a = 3 ]
so the script should change to
#!/bin/bash
echo "Letter:"
read a
if [ $a = 3 ]
then
echo "LOL"
fi
if [ $a = 4 ]
then
echo "ROFL"
fi
Since a is read from user input, there is possibility user key in:
non numeric value
a string with empty space
nothing, user may just press Enter key
so a safer way to check is:
if [ "x$a" = "x3" ]

Bash optional parameters and setting to default

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'}

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.

Resources