How to check if there is a parameter provided in bash? - linux

I wanted to see if there is a parameter provided. But i don't know why this code wont work. What am i doing wrong?
if ![ -z "$1" ]
then
echo "$1"
fi

Let's ask shellcheck:
In file line 1:
if ![ -z "$1" ]
^-- SC1035: You need a space here.
In other words:
if ! [ -z "$1" ]
then
echo "$1"
fi
If, as per your comment, it still doesn't work and you happen to be doing this from a function, the function's parameters will mask the script's parameters, and we have to pass them explicitly:
In file line 8:
call_it
^-- SC2119: Use call_it "$#" if function's $1 should mean script's $1.

You could check the number of given parameters. $# represents the number of parameters - or the length of the array containing the parameters - passed to a script or a function. If it is zero then no parameters have been passed. Here is a good read about positional parameters in general.
$ cat script
#!/usr/bin/env bash
if (( $# == 0 )); then
echo "No parameters provided"
else
echo "Number of parameters is $#"
fi
Result:
$ ./script
No parameters provided
$ ./script first
Number of parameters is 1
$ ./script first second
Number of parameters is 2
If you would like to check the parameters passed to the script with a function then you would have to provide the script parameters to the function:
$ cat script
#!/usr/bin/env bash
_checkParameters()
{
if (( $1 == 0 )); then
echo "No parameters provided"
else
echo "Number of parameters is $1"
fi
}
_checkParameters $#
This will return the same results as in the first example.
Also related: What are the special dollar sign shell variables?

Related

What is -z in bash

I am trying to understand the following code:
if [ -z "$1" ] || [ -z "$2" || [ "${3:-}" ]
then
echo "Usage: $0 <username> <password>" >&2
exit 1
fi
I want to understand what we mean by -z "$1" and "${3:-}" in the code.
Please also help me understand >&2 in the code.
1) Your code is not correct, you missed one ] bracket somewhere. Probably after [ -z "$2" block.
2) if statement executes following command(s) and then executes block of code enclosed in then .. fi or then .. else keywords if the return value of the command(s) is true (their exit code is 0)
3) [ is just an alias for the test command (try man test). This command takes several parameters and evaluates them. For example, used with -z "$something" flags would return true (0) if $something is not set or is an empty string. Try it:
if [ -z "$variable" ]; then
echo Variable is not set or is an empty string
fi
4) || statement is an OR. Next command would be executed if the previous one returned false statement. So in the statement
if [ -z "$variable" ] || [ -z "$variable2" ]; then
echo Variable 1 or variable 2 is not set or is an empty string
fi
command [ -z "$variable2" ] would be executed only if variable was empty. The same could be achieved with different syntax:
if [ -z "$variable" -o -z "$variable2" ]; then
echo Variable 1 or variable 2 is not set or is an empty string
fi
which should be faster, because it requires only one instance of the test program to be run. Flag -o means OR, so you could read it as:
If variable is not set/empty OR variable2 is not set/EMPTY...
5) Statement "[ ${3:-} ]" means return true if $3 (the third argument of the script) is set.
6) >&2 is a stream redirection. Every process has two outputs: standard output and error output. These are independent and could be redirected (for example) to be written to two different files. >&2 means "redirect standard output to the same location as standard error".
So to sum up: commands between then .. fi will be executed IF the script is run with $1 empty or $2 empty or $3 NOT empty That means that the script should be run with exactly two parameters. And if not, the echo message will be printed to standard error output.
-z STRING means the length of STRING is zero.
${parameter:-word} If parameter is unset or null, the expansion of word is substituted. In your case $3 is just set with a blank value, if $3 do not have any value.
&2 writes to standard-error. I mean the stdout value of the executed command is sent to stderr,

How to execute a command in bash language and check its result

I'm trying to learn the bash language. How do I execute a Linux command with a dynamic argument and check whether or not the returning string is empty. For example:
if ls "my_directory123" == `emtpy string` then
....
end
If you are testing for an empty directory pass in the first positional parameter "$1", you can test:
if test -z "$(ls -A "$1")" ; then
or
if [ -z "$(ls -A "$1")" ]; then
which are equivalent uses of the test of [ keywords.
Assign the result of the command to a variable and compare it as a string.
result=$(ls "my_directory123")
if [ "$result" = "" ]
then
echo empty
fi
TEST=`ls`
if [$TEST == ""]; then
echo "do something"
fi
if you want to run this in the terminal you key in each line at a time. If you prefer you can put everything in a file prepend with
#!/bin/bash
to make an executable string once you run
chmod +x FILENAME
Need to call Command Substitution and check for returned value. Some think like this
x=$(ls path)
if [ -z "$x" ] ;then echo empty ; else echo no empty; fi

What means the -z value in an if expression on a Linux script?

In this script I found this if expression:
if [ -z $1 ]; then
echo "Usage: createpkg.sh <rev package>"
exit
else
CURRENT_VERSION=$1
fi
My problem is that I can't find what exactly means this -z value.
From the content of the echo I can deduct that (maybe) $1 variable represents the sotware version. and that (maybe) -z is a void value. So if I execute the script without passing to it the version of the software that I would packing it print me the correct procedure to execute the script.
But I am not sure about the real meaning of the -z value.
From man test:
-z STRING
the length of STRING is zero
So the condition:
if [ -z $1 ]; then
means "if the variable $1 is empty". Where $1 is probably the first parameter of the script: if you execute it like ./script <parameter1> <parameter2>, then $1=parameter1, $2=parameter2 and so forth.
help test tells:
String operators:
-z STRING True if string is empty.
In your example, the script would print Usage: createpkg.sh <rev package> and exit if an argument was not supplied.

How to catch missing argument in function mistake?

I have just made the following mistake, where I am passing an argument to a function which is empty.
var1="ok"
var2=$notDefined
func $var1 $var2
func() {
var1=$1
var2=$2
echo $var1
echo $var2
}
For each argument in the function I could do
if [ -z $1 ]; then echo "Empty argument"; fi
But is there a more generic method to do this, so it is easy reusable, and would perhaps even tell the variable name that is empty?
You can stop whole script by set -u. It will fail if you try to use unset variable. It is very general approach.
Bash will output following localized message to standard error:
bash: x: unbound variable
You want to use the ? bash variable substitution operator:
var1=${1:?"undefined!"}
If $1 exists and isn't null, var1 is set to its value, otherwise bash prints 1 followed by "undefined!" and aborts the current command or script. This syntax can used for any bash variable.
In your case the empty variables are created, because there are too few arguments to the function.
You can get the number of passed arguments via $#. All variables that use $n with a higher number n must then be empty. You could check for a sufficiently high number of arguments at the beginning of your function.
#!/bin/bash
var1="ok"
var2=$notDefined
func() {
if [[ $# -ge 2 ]]; then
var1=$1
var2=$2
echo $var1
echo $var2
else
echo "Missing values"
fi
}
func $var1 $var2
Here it is running
./test.sh
Missing values
Here it is with two values:
#!/bin/bash
var1="ok"
var2="dokie"
func() {
if [[ $# -ge 2 ]]; then
var1=$1
var2=$2
echo $var1
echo $var2
else
echo "Missing values"
fi
}
func $var1 $var2
Results with:
./test.sh
ok
dokie

Bash ARGS help - getting random error

Trying to set rules if a certain variable is put into place, can someone identify wtf I'm missing here?
test.sh:
#!/bin/bash
args=($#)
if [ "$#" = "--cron" ]; then
echo "WORKS!";
else echo "FAILS"
fi
output of ./test.sh:
./test.sh: line 3: [: =: unary operator expected
FAILS
However, when I run ./test.sh --cron, it works, and WORKS is output.
The correct way to do this varies a bit depending on exactly what you're trying to do. If you want to check whether the first argument is --cron, use this:
if [ "$1" = "--cron" ]; then
If you want to check whether the only argument is --cron, use this:
if [ "$*" = "--cron" ]; then
(Note that this is one of very few cases where "$*" is the right way to do something -- it expands to all arguments separated by spaces, but treated as a single word for parsing purposes.)
If you want to check whether any argument is --cron, use this:
cronopt=false
for argument; do
if [ "$argument" = "--cron" ]; then
cronopt=true
break # note: if you are scanning the arguments for other things too, remove this
fi
done
if $cronopt; then
...
BTW, I'm not sure what you're using the args=($#) line for, but if you want to store the arguments in an array the correct way to do it is args=("$#") -- the quotes keep it from doing word splitting, filename expansion, etc before putting the args into the array.
This should work, but only for the first element, of you want more you might have to do a for or while loop to iterate thru the arguments.
#!/bin/bash
args=($1)
if [ $args ] && [ $args = "--cron" ]; then
echo "WORKS!";
else echo "FAILS"
fi
In this case, I believe "$#" is too well quoted.
Try comparing against "$1", or use:
#!/bin/bash
args=($#)
if [ "$*" = "--cron" ]; then
echo "WORKS!";
else
echo "FAILS"
fi

Resources