I am writing the following code:
if [ $opt -ge $max -o $opt -le 0 ]
then
echo "Bad";
else
echo "Good";
if [ $opt = "\" -o $opt = "/" ]
then
echo "Good";
else
echo "Invlaid"; //Line number 21
fi
fi //Line number 23 no Line number 24.
this shows an error:
./file.sh: line 21: unexpected EOF while looking for matching `"'
./file.sh: line 24: syntax error: unexpected end of file
If I place this code:
if [ $opt -ge $max -o $opt -le 0 ]
then
echo "Bad";
else
echo "Good";
fi //Line number 23 no Line number 24.
Then there is no error. I am not able to figure out the problem.
Where you write "\" you start a string literal whose first character is a double quote. To include a back slash in a string you have to precede it with another:
"\\"
Backslash \ inside double quotes needs to be escaped or else you can use single quotes like this:
if [ $opt = '\' -o $opt = '/' ]; then
echo "Good"
fi
Single quotes treat the wrapped string literally that's the precise reason single quote in shell cannot be escaped.
opt="\\"
echo $opt
\
if [ $opt = "/" -o $opt = "\\" ]; then echo "Hi"; else echo "bye"; fi
Hi
Related
I have a code similar to below:
while [ $k = 0 ];
do
if [ $Year1 = $Year2 ] && [ $Month1 = $Month2 ]; then
echo "abcd"
else
echo"erty"
The error is line highlighted line > line 144]: [: argument expected
At least one of your variables contains unexpected data (e.g. is empty, or has spaces or new line characters), causing the [ command to not receive the arguments it expects.
Always quote your variables ("$Year1" instead of $Year1) to avoid surprises like this one.
while [ "$k" = 0 ]; do if [[ $Year1 == $Year2 && $Month1 == $Month2 ]]; then echo "abcd"; else echo "erty"; fi; done
Helpfull could be: https://www.shellcheck.net
You should use == for comparisons instead of = and also please use -eq whenever you want to use == if your code is for integer comparison. For example,
if [ $FLAG -eq 1 ];then
For strings, you can use =, like for example NOTE : Edited as pointed by Sir Athos
if [ "$Year1" = "$Year2" ] && [ "$Month1" = "$Month2" ]; then
or if you are comparing variable with string then, you can also use ==,
if [ "$STA" == "Completed" ];then
Adding test script to further clarify :
-bash-4.2$ cat string.sh
#!/bin/bash -x
str1="Hello There"
str2="Hello There"
if [ "$str1" = "$str2" ];then
echo "Matched"
else
echo "Not Matched"
fi
if [ "$str1" == "Hello There" ];then
echo "Matched"
else
echo "Not Matched"
fi
-bash-4.2$ ./string.sh
+ str1='Hello There'
+ str2='Hello There'
+ '[' 'Hello There' = 'Hello There' ']'
+ echo Matched
Matched
+ '[' 'Hello There' == 'Hello There' ']'
+ echo Matched
Matched
-bash-4.2$
In the following two lines I get this error?
What is wrong?
Debian Buster
my.sh: 101: [: !=: unexpected operator
my.sh: 103: [: !=: unexpected operator
if [ $CONTINUE != "y" ] && [ "$CONTINUE" != "n" ]; then
elif [ $CONTINUE = "n" ]; then
update
echo "\nContinue downloading? [y/n]"
read CONTINUE
# Error: Invalid argument
if [ $CONTINUE != "y" ] && [ $CONTINUE != "n" ]; then
error "Invalid argument"
elif [ $CONTINUE = "n" ]; then
echo "\nDonwload terminated!"
exit
fi
The script you’ve posted has various issues, which are highlighted by ShellCheck:
Line 1:
echo "\nContinue downloading? [y/n]"
^-- SC2028: echo may not expand escape sequences. Use printf.
Line 2:
read CONTINUE
^-- SC2162: read without -r will mangle backslashes.
Line 5:
if [ $CONTINUE != "y" ] && [ $CONTINUE != "n" ]; then
^-- SC2086: Double quote to prevent globbing and word splitting.
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
if [ "$CONTINUE" != "y" ] && [ "$CONTINUE" != "n" ]; then
Line 7:
elif [ $CONTINUE = "n" ]; then
^-- SC2086: Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
elif [ "$CONTINUE" = "n" ]; then
Line 8:
echo "\nDonwload terminated!"
^-- SC2028: echo may not expand escape sequences. Use printf.
But despite these issues the script actually otherwise works as expected on Debian (Buster)’s default shell (which is dash). You might be running a non-default shell. The easiest way to solve your issue is therefore to
Declare a valid shebang line
Fix the issues highlighted above.
Which leaves us with this:
#!/bin/sh
printf "\nContinue downloading? [y/n] "
read -r CONTINUE
error() {
printf >&2 '%s\n' "$#"
exit 1
}
if [ "$CONTINUE" != y ] && [ "$CONTINUE" != n ]; then
error "Invalid argument"
elif [ "$CONTINUE" = n ]; then
printf "\nDownload terminated!\n"
exit
fi
(This also adds a definition for the undefined error call; substitute as appropriate.)
I'm trying to use comparison in bash, but just can't make it work.
#!/bin/bash
str="75.00 W, 170.00 W"
function str_check {
pow_array=()
regexp='([0-9]+)\.[0-9]+[[:space:]]W,[[:space:]]([0-9]+)\.[0-9]+[[:space:]]W'
[[ $str =~ $regexp ]] && for (( i = 0; i < 3; i++ )); do
pow_array+=("${BASH_REMATCH[$i]}")
done
if [ "$1" -lt ${pow_arr[1]} ]; then
echo "Available power limit is ${pow_array[0]}"
echo "Setting up ${pow_array[1]}"
elif [ "$1" -gt "${pow_arr[2]}" ]; then
echo "Available power limit is ${pow_array[0]}"
echo "Setting up ${pow_array[2]}"
else
echo "All good, setting up $1"
fi
}
str_check "70"
str_check "100"
str_check "200"
Already have tried '[[', '((' '[', qoute and unquote everething, but getting all kind of errors or wrong results. Need someone to give me a hand.
./t.sh: line 9: [: 70: unary operator expected
./t.sh: line 12: [: : integer expression expected
Time to discover shellcheck !
Line 9:
if [ "$1" -lt ${pow_arr[1]} ]; then
^-- SC2154: pow_arr is referenced but not assigned (did you mean 'pow_array'?).
^-- SC2086: Double quote to prevent globbing and word splitting.
Change all the references to pow_arr into pow_array and it works !
I'm writing a shell script that automatically writes a bash script using cat. However, when I run the script, the produced bash script does not include data found in quotation marks. Here's my script:
cat <<EOS > script.bash
scriptDir=`dirname "$0"`
scriptName=`basename "$0"`
singleLine=0
function process ()
{
for file
do
if [ "${file}" = "-singleLine" ]
then
singleLine=1
else
if [ "${file}" = "-" ]
then
processStdIn
else
processFile "${file}"
fi
fi
done
}
function processFile ()
{
file="$1"
if [ -f "${file}" ]
then
printf "<table border=\"1\">"
if [ ${singleLine} -eq 0 ]
then
echo
fi
cat "${file}" | sed 's|,|</td><td>|g' |
while read line
do
printf "<tr><td>${line}</td></tr>"
if [ ${singleLine} -eq 0 ]
then
echo
fi
done
printf "</table>"
echo
else
echo "${file} does not exist!" >&2
fi
}
function processStdIn ()
{
tempFile=`GetTempPathName.ksh "${scriptName}"`
while read line
do
echo "${line}" >> "${tempFile}"
done
processFile "${tempFile}"
rm "${tempFile}"
}
function usage ()
{
echo " Usage: ${scriptName} [ -singleLine ] \"file 1\" [ . . . \"file N\" ]"
echo
echo " You may substitute '-' in place of a file to read from STDIN."
echo
echo " Use the -singleLine flag if you want to generate the HTML on"
echo " a single line. This flag may show up anywhere on the command-"
echo " line. But only data specified after this flag will be"
echo " generated in this manner."
}
if [ $# -gt 0 ]
then
process "$#"
else
usage
fi
EOS
Here's script.bash:
scriptDir=.
scriptName=test.sh
singleLine=0
function process ()
{
for file
do
if [ "" = "-singleLine" ]
then
singleLine=1
else
if [ "" = "-" ]
then
processStdIn
else
processFile ""
fi
fi
done
}
function processFile ()
{
file=""
if [ -f "" ]
then
printf "<table border=\"1\">"
if [ -eq 0 ]
then
echo
fi
cat "" | sed 's|,|</td><td>|g' |
while read line
do
printf "<tr><td></td></tr>"
if [ -eq 0 ]
then
echo
fi
done
printf "</table>"
echo
else
echo " does not exist!" >&2
fi
}
function processStdIn ()
{
tempFile=
while read line
do
echo "" >> ""
done
processFile ""
rm ""
}
function usage ()
{
echo " Usage: [ -singleLine ] \"file 1\" [ . . . \"file N\" ]"
echo
echo " You may substitute '-' in place of a file to read from STDIN."
echo
echo " Use the -singleLine flag if you want to generate the HTML on"
echo " a single line. This flag may show up anywhere on the command-"
echo " line. But only data specified after this flag will be"
echo " generated in this manner."
}
if [ 0 -gt 0 ]
then
process ""
else
usage
fi
How can I get cat to include the quoted material?
Replace:
cat <<EOS > script.bash
With:
cat <<'EOS' > script.bash
This prevents shell expansion of what is in the here document.
Documentation
From man bash:
The format of here-documents is:
<<[-]word
here-document
delimiter
No parameter expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any
characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document
are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command sub‐
stitution, and arithmetic expansion. In the latter case, the character sequence \<newline> is ignored, and \ must be used
to quote the characters \, $, and `.
The most important part of that is:
If word is unquoted, all lines of the here-document are subjected to
parameter expansion, command substitution, and arithmetic expansion.
To stop all that expansion, just quote word which in your case is EOS.
I'm trying to put the 'f-$count'(f-1,f-2) name into the array.
Below is the code,
echo "Enter the count"
read count
echo $count
#arr=()
i=1
while true;
do
if ["$i" -gt "$count"]; then
exit 0
else
arr[$i]=f-$i
i=$((i+1))
fi
done
echo ${arr[#]}
I'm getting the error as 'script.sh: line 11: [3570: command not found
' continuously.
In shell programming, the brackets in the if MUST be delimited by spaces:
if ["$i" -gt "$count"]; then
MUST be:
if [ "$i" -gt "$count" ]; then
[EDIT] The left bracket ([) is actually a built-in shell command and so requires the space afterwards to delimit it from its parameters, as with any command.