Mac Bash - doesn't recognize if[$#=0] - macos

It's been a while since I've scripted in bash so I made a small script to test things out. This is my script (the quoted text is some Dutch, doesnt really matter):
#isingelogd
if[$#=0]
then
echo "Geef user-id's op!" 1>$2 ; exit 1
fi
for uid in $*
do
if who|grep $uid >dev/null
then
echo $uid is ingelogd
else
echo $uid is niet ingelogd
fi
done
If I try to run it it tells me the following:
bash-3.2$ ./isingelogd
./isingelogd
./isingelogd: line 3: if[0=0]: command not found
./isingelogd: line 4: syntax error near unexpected token `then'
./isingelogd: line 4: `then'
If I check my version with bash -v I'm running 3.2 which I thought supported square brackets.
Has someone had a similar problem and found solution?

Look at your errors:
bash-3.2$ ./isingelogd
./isingelogd
./isingelogd: line 3: if[0=0]: command not found
./isingelogd: line 4: syntax error near unexpected token then'
./isingelogd: line 4:then'
See that command not found? you have an error in your script.
The [..] are actual commands, and like all commands, they need to be separated by white spaces. The = is a parameter to the [ command and also needs to be surrounded by white space. Change line #3 to this:
if [ $# -eq 0 ]
Since $# and 0 are numeric, you should use -eq which compares to numbers and not = which compares strings.
Try these commands:
$ ls -li /bin/test
$ ls -li /bin/[
You'll see they have the same inode number. They're links. (Yes, the [ and test are builtins into the shell, but they are linked builtin commands).
$ man test
will give you all of the various tests that [ can do. Again, note the difference between -eq vs. = and -gt vs. >.
Note the following:
if [ 54 > 123 ]
then
echo "54 is greater than 123"
fi
This will print out "54 is greater than 123". This won't:
if [ 54 -gt 123 ]
then
echo "54 is greater than 123"
fi

a.bash works for me in Mac. Content of a.bash is the following :
#!/bin/bash
if [ $# == 0 ]; then
echo "Usage da da do"
fi
export A=$1
echo $A
then execute with the following :
\# ] ./a.bash
Usage da da do

Related

Getting the line count of a file in a shell script with wc failing

my script check if the arguments are files or folders
if it is a file, he count the number of lines
after that, if the number of lines is great then 20 or less he do some instructions
the problem is in this instructionn= cat $a | wc -l
My script:
#!/usr/bin/env bash
echo 'Hello this is the test of' `date`
echo 'arguments number is ' $#
if [ $# -eq 4 ]
then
for a in $#
do
if [ -d $a ]
then
ls $a > /tmp/contenu
echo "contenu modified"
elif [ -f $a ]
then
# this instruction must set a numeric value into n
echo "my bad instruction"
n= cat $a | wc -l
echo "number of lines = " $n
# using the numeric value in a test (n must be numeric and takes the number of lines in the current file)
if [ $n -eq 0 ]
then
echo "empty file"
elif [ $n -gt 20 ]
then
echo ` head -n 10 $a `
else
cat $a
fi
else
echo "no file or directory found"
fi
done
else
echo "args number must be 4"
fi
This is the output of the execution of the incorrect instruction
my bad instruction
5
number of lines =
ExamenEx2.sh: line 19: [: -eq : opérateur unaire attendu
The line n= cat $a | wc -l is an offending instruction. Always remember that bash shell scripting is extremely case-sensitive. Your command is interpreted by the shell as having to run two separate commands
n= cat $a | wc -l
#^^ ^^^^^^^^^^^^^^
#1 2
The first part just stores an empty string to the variable n and the next prints the line count of the file stored in variable a. Notice that the shell does not throw errors for this. Because it is not violating the syntax (just the semantics are wrong). But the line count is never assigned to the variable n.
The error is seen when the conditional if [ $n -eq 0 ] is hit when you are doing a comparison with an empty variable on the LHS.
You wanted to run a command and store its output, you need command-substitution($(..)) for that. Assuming the $a contains a name of a file just do
n=$(wc -l < "$a")
Note, that I've removed the useless cat usage and piping it to wc. But wc can read from an input stream directly.
Also note that you have multiple bad practices in your script. Remember to do the following
Always double-quote the shell variables - "$#", "$#", [ -f "$a" ], [ -d "$a" ]
Don't use the `` for command-substitution, because it is not easily nestable and you might have issues related to quoting also.
You can use conditional expression [[ if you are sure if the script is running under bash in which a variable containing spaces can be used without quoting on the LHS

convert read string to integer in bash

I'm trying to read from user and then do the following.
read framechoice
if [ $framechoice -gt 100 ]; then
if [ $framechoice -lt 0 ]; then
framechoice=101
fi
fi
It gives me the following error.
[: -gt: unary operator expected
Can anyone tell me where I am going wrong.
This happens if you don't input anything:
$ cat myscript
read framechoice
if [ $framechoice -gt 100 ]; then
if [ $framechoice -lt 0 ]; then
framechoice=101
fi
fi
$ bash myscript
<enter>
myscript: line 2: [: -gt: unary operator expected
Try instead to actually enter something:
$ bash myscript
42<enter>
The script then exits with success.
Your program needs to cope with empty input. This is most easily achieved by properly quoting the variable; then
if [ "$framechoice" -gt 100 ]; then
evaluates to [ "" -gt 100 ] which is no longer is a syntax error; however, instead, it throws the warning integer expression expected.
Even better, maybe filter the input so that you do not attempt numeric comparisons before making sure the input is numeric.

not found error in shell script

I am trying to run the following code in debian terminal.
read var
if [$var -gt 0]; then
echo "Greater than zero"
fi
When I give 45 as an input to the variable var, the terminal is showing the following error
4:[ 45: Not Found
Why is the error coming and what is it's solution.
Spaces inside [ and ] are mandatory:
Try:
read var
if [ "$var" -gt 0 ]; then
echo "Greater than zero"
fi
/bin/[ is a binary in Unix that takes it's arguments from the string that comes after a space.

Bash script command result inside other variable to define prompt

I would like to define a prompt which will indicate with colors whether the command executed properly and whether the command was found. As for now I have something like this but I does not work properly.
PS1="\`COMMAND_RESULT=\$\?;
if [ $COMMAND_RESULT -eq 127 ]; then echo \[\e[33m\] ---=== Command not found ===--- ;
elif [ $COMMAND_RESULT -ne 0 ]; then echo \[\e[33m\]---=== \[\e[31m\]Oh noes, bad command \[\e[33m\]==---;
fi\`
\n\[\e[0;37m\][\[\e[1;31m\]\#\[\e[0;37m\]]
\[\e[0;32m\]\u\[\033[1;33m\]#\[\033[0;32m\]\h
As for now I get this error on bash start :
-bash: [: -eq: unary operator expected
-bash: [: -ne: unary operator expected
Don't pollute your PS1 with functions. You should use the special PROMPT_COMMAND variable to do this. The value of PROMPT_COMMAND is executed as a command prior to issuing each primary prompt.
Here is an example:
_check_command(){
local COMMAND_RESULT=$?
if [ $COMMAND_RESULT -eq 127 ]
then
echo -e "\e[1;33m---=== Command not found ===---\e[m"
elif [ $COMMAND_RESULT -ne 0 ]
then
echo -e "\e[1;31m---=== Oh noes, bad command ===---\e[m"
fi
}
PROMPT_COMMAND='_check_command'
PS1="\[\e[0;37m\][\[\e[1;31m\]\#\[\e[0;37m\]] \[\e[0;32m\]\u\[\033[1;33m\]#\[\033[0;32m\]\h "
There are many bash prompts you can find online to guide you. Here is one good example.
You probably should not escape $? as \$\?. Looks like it gets interpreted literally.
Also you can check out the Arch Wiki article that shows how to implement something similar to what you want. Look at this line:
PS1="$(if [[ ${EUID} == 0 ]]; then echo '\[\033[01;31m\]\h'; else echo '\[\033[01;32m\]\u#\h'; fi)\[\033[01;34m\] \w \$([[ \$? != 0 ]] && echo \"\[\033[01;31m\]:(\[\033[01;34m\] \")\$\[\033[00m\] "
especially this part:
([[ \$? != 0 ]] && echo \"\[\033[01;31m\]:(\[\033[01;34m\] \")

Bash script string comparison error, can't figure out

I fixed the code below so it works:
#!/bin/bash
out="$(cat /proc/acpi/bbswitch)"
if [[ "$out" == *OFF* ]];
then
tee /proc/acpi/bbswitch <<<ON
echo "Nvidia card activated."
else
tee /proc/acpi/bbswitch <<<OFF
echo "Nvidia card disabled."
fi
This is made for activating or disabling my optimus card. I get an error on line 4:
./.bb: line 4: [0000:01:00.0 OFF: command not found
OFF
Nvidia card disabled.
I can read from it that it tries to execute the $out variable. Why?
You need to ensure that there is at least 1 space between the brackets [ / ] and the actual variables; i.e.: change your code from
if ["$out" == "$is"];
to:
if [ "$out" == "$is" ];
And it should work.
The reason is that [ is actually the "test" command in bash. Try on your prompt:
which [
and you should see something like:
/usr/bin/[
Also, man [ to read more about syntax
(Note, since arguments are delimited by spaces, there needs to be a space between your 2nd variable and ] as well. Test uses ] as the terminating sentinel)

Resources