I write the following shell script and cannot understand how it works.
#!/bin/bash
[ -n $HOME ]
echo $?
[ -z $HOME]
echo $?
Output = 0
1
What is the use of -n and -z options
With -n and -z you can check the length of a variable.
if [ -n "$HOME" ]; then
echo "length of \$HOME ist not zero"
fi
if [ -z "$HOME" ]; then
echo "length of \$HOME is zero"
fi
Related
I wanna write a script which check variables of this script.
I have tried some, but it isn't working. The idea is:
If on of the parameters is a number, print that it is number
If on of the parameters is a character, print that it is character
If 'man parameter' is executable, print that it is might be a function
Script I have tried:
#!/bin/bash
echo Hello $LOGNAME'!'
test $# -eq 0 && echo 'Try again, no parameters were entered' || echo 'Num of parameters is '$#
re='^[0-9]+$'
for i in $*
do
if ![["$i" =~ $re]];then
echo 'Parameter '$i' is alphabetical'
else
if [["$i" =~ $re]];then
echo 'Parameter '$i' is digital'
else
if [ $i];then
echo $i' might be a function. Try to use man of --help'
fi
fi
fi
done
#!/bin/bash
echo "Hello ${LOGNAME}!"
[ "$#" -eq 0 ] && { echo 'Try again, no parameters were entered'; exit 1; }
echo 'Num of parameters is '$#
re='^[0-9]+$'
for i in "$#"
do
if ! [[ "$i" =~ $re ]];then
echo "Parameter '$i' is alphabetical"
man "$i" > /dev/null 2> /dev/null
if [ "$?" -eq 0 ];then
echo "$i might be a function. Try to use man of --help"
fi
else
echo "Parameter '$i' is digital"
fi
done;
When you write a test you need spaces around your brackets.
You can easily find and fix those bugs if you use shellcheck
In my Programm how can i Iterate trough ENV in bash
if [ ! -z $USER_1 ]
then
echo "$USER_1":$(openssl passwd -apr1 $PASS_1) > ./passwords
fi
if [ ! -z $USER_2 ]
then
echo "$USER_2":$(openssl passwd -apr1 $PASS_2) > ./passwords
fi
if [ ! -z $USER_3 ]
then
echo "$USER_3":$(openssl passwd -apr1 $PASS_3) > ./passwords
fi
if [ ! -z $USER_4 ]
then
echo "$USER_4":$(openssl passwd -apr1 $PASS_4) > ./passwords
fi
if [ ! -z $USER_5 ]
then
echo "$USER_5":$(openssl passwd -apr1 $PASS_5) > ./passwords
fi
And so on how can i do it with N "User" when i don't know N
EDIT April 14: my first version was incomplete, here is a fix.
Create a loop to loop through your users:
#!/bin/bash
USER_1=u1
USER_2=u2
N=5
for (( counter=1; counter<=N; counter++ ))
do
username=USER_${counter}
password=PASS_${counter}
echo "DEBUG: $username"
echo "DEBUG: ${!username}"
if [[ -n ${!username} ]]
then
#echo "$username:$(openssl passwd -apr1 "$password")"> ./passwords
echo "DEBUG: USER_${counter} inside if"
fi
echo "========="
done
To use on your setup, comment out the debug statements and uncomment your openssl line.
My first version did not properly user the variable counter inside the other USER_? variable.
With this particular script, USER_1 and USER_2 will trigger the if since USER_3 and more are not set.
I've been handed an assignment which goes as follows;
I should write a program that checks a file and print out if one of the following happens:
File is created
file is modified
file is deleted
I've made a working program ( my noobish way):
bool=true
if [ -e "$1" ]
then
dato=$(date -r "$1" "+%s")
datony=$(date -r "$1" "+%s")
while [ "$bool" = true ]
do
echo "File exists!"
sleep $2
datony=$(date -r "$1" "+%s")
if [ "$dato" -ne "$datony" ]
then
bool=false
echo "File modified!"
fi
if [ ! -e "$1" ]; then
bool=false
echo "File erased"
fi
done
fi
if [ ! -e "$1" ]
then
while [ "$bool" = true ]
do
echo "File does not exist!"
sleep $2
if [ -e "$1" ]
then
bool=false
echo "File created!"
fi
done
fi
The problem now is that i should make a new script that should take multiple files and check their statuses using my existing script. I need som help with how i should use my script to do that.
If you want to continue using $1 for files and $2 for sleep time.
first, put sleep time in a variable
sleepTime=$2
Put all the code you already made in a function (or a program)
checkFile(){
bool=true
if [ -e "$1" ]
then
dato=$(date -r "$1" "+%s")
datony=$(date -r "$1" "+%s")
while [ "$bool" = true ]
do
echo "File exists!"
sleep $2
datony=$(date -r "$1" "+%s")
if [ "$dato" -ne "$datony" ]
then
bool=false
echo "File modified!"
fi
if [ ! -e "$1" ]; then
bool=false
echo "File erased"
fi
done
fi
if [ ! -e "$1" ]
then
while [ "$bool" = true ]
do
echo "File does not exist!"
sleep $2
if [ -e "$1" ]
then
bool=false
echo "File created!"
fi
done
fi
}
create another function to separate the files and call the other function on background.
func_splitFiles(){
while [ ! -z $1 ];
do
checkFile $1 $sleepTime &
shift;
done;
}
In the "main" program you just call the function to split files passing $1
func_splitFiles $1
You should call the program passing files between quotes.
program.sh "file1 file2 file3" 1
This is part of my script:
#!/bin/bash
USAGE(){
echo "Usage: ./`basename $0` <File1> <File2>"
}
if [ "$#" -ne "2" ]; then
USAGE
exit 1
fi
if [ ! -f "$1" ]; then
echo "The file \"$1\" does not exist!"
exit 1
fi
if [ ! -f "$2" ]; then
echo "The file \"$2\" does not exist!"
exit 1
fi
I want to check if file1 does not exist prints:
The file "file1" does not exist!
if file2 does not exist prints:
The file "file2" does not exist!
If both does not exist prints:
The files "file1" and "file2" don't exist!
How can I do that?
I want to know what the most logical (STANDARD) method is.
Of course you can do that... . There are many ways to obtain this. The most simple maybe:
if [ ! -f "$1" ] && [ ! -f "$2" ]; then
echo "The files \"$1\" and \"$2\" do not exist!"
exit 1
else
if [ ! -f "$1" ]; then
echo "The file \"$1\" does not exist!"
exit 1
fi
if [ ! -f "$2" ]; then
echo "The file \"$2\" does not exist!"
exit 1
fi
fi
If you don't want to do the checks two time, you can work with variables; something like this:
if [ ! -f "$1" ]; then
NOT1=1
fi
if [ ! -f "$1" ]; then
NOT2=1
fi
if [ -n "$NOT1" ] && [ -n "$NOT2" ]
....
You could do it like this so you only have to test each file once:
status=""
for file; do
[ -f "$file" ]
status+=$?
done
case $status in
11)
echo "The files \"$1\" and \"$2\" do not exist!"
exit 1
;;
10)
echo "The file \"$1\" does not exist!"
exit 1
;;
01)
echo "The file \"$2\" does not exist!"
exit 1
;;
esac
The logical is
if [ ! -f "$1" ]; then
if [ ! -f "$2" ]; then
echo "The files \"$file1\" and \"$file2\" don't exist!"
exit 1
else
echo "The file \"$1\" does not exist!"
exit 1
fi
fi
if [ ! -f "$2" ]; then
echo "The file \"$2\" does not exist!"
exit 1
fi
The readable is
if [ ! -f "$1" -a ! -f "$2" ]; then
echo "The files \"$file1\" and \"$file2\" don't exist!"
exit 1
fi
if [ ! -f "$1" ]; then
echo "The file \"$1\" does not exist!"
exit 1
fi
if [ ! -f "$2" ]; then
echo "The file \"$2\" does not exist!"
exit 1
fi
The readable is preferred.
Also not testing for existence twice as Chris Maes said could be logical too.
Simplified for Bash:
#!/bin/bash
if [[ $# -ne 2 ]]; then
echo "Usage: ${0##*/} <File1> <File2>"
elif [[ ! -f $1 && ! -f $2 ]]; then
echo "The files \"$1\" and \"$2\" don't exist!"
elif [[ ! -f $1 ]]; then
echo "The file \"$1\" does not exist!"
elif [[ ! -f $2 ]]; then
echo "The file \"$2\" does not exist!"
fi
You can use this additional condition:
if [ ! -f "$1" ] && [ ! -f "$2" ]; then
echo "Both files does not exist!"
exit 1
fi
I'm not sure you need that though. The two conditions you have, for first and second file, will be informative enough.
Alternatively, you can use just one condition by using logical OR ||. I'd suspect users wouldn't have an issue with understanding their misues of the script:
if [ ! -f "$1" ] || [ ! -f "$2" ]; then
USAGE
exit 1
fi
This question already has answers here:
Test for non-zero length string in Bash: [ -n "$var" ] or [ "$var" ]
(7 answers)
Closed 8 years ago.
I don't set any values for $pass_tc11; so it is returning null while echoing. How to compare it in if clause?
Here is my code. I don't want "Hi" to be printed...
-bash-3.00$ echo $pass_tc11
-bash-3.00$ if [ "pass_tc11" != "" ]; then
> echo "hi"
> fi
hi
-bash-3.00$
First of all, note you are not using the variable correctly:
if [ "pass_tc11" != "" ]; then
# ^
# missing $
Anyway, to check if a variable is empty or not you can use -z --> the string is empty:
if [ ! -z "$pass_tc11" ]; then
echo "hi, I am not empty"
fi
or -n --> the length is non-zero:
if [ -n "$pass_tc11" ]; then
echo "hi, I am not empty"
fi
From man test:
-z STRING
the length of STRING is zero
-n STRING
the length of STRING is nonzero
Samples:
$ [ ! -z "$var" ] && echo "yes"
$
$ var=""
$ [ ! -z "$var" ] && echo "yes"
$
$ var="a"
$ [ ! -z "$var" ] && echo "yes"
yes
$ var="a"
$ [ -n "$var" ] && echo "yes"
yes
fedorqui has a working solution but there is another way to do the same thing.
Chock if a variable is set
#!/bin/bash
amIEmpty='Hello'
# This will be true if the variable has a value
if [ $amIEmpty ]; then
echo 'No, I am not!';
fi
Or to verify that a variable is empty
#!/bin/bash
amIEmpty=''
# This will be true if the variable is empty
if [ ! $amIEmpty ]; then
echo 'Yes I am!';
fi
tldp.org has good documentation about if in bash:
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html