This question already has answers here:
How to pass the value of a variable to the standard input of a command?
(9 answers)
Closed 11 months ago.
Here I have the simple code in which I am trying to store the value of program output to a variable in bash.
#!/bin/bash
i=0
for value in {1..10}
do
variable=`$value | ./unpackme`
str="What's my favorite number? Sorry, that's not it!"
if [[ "$variable" == "$str" ]]
then
echo "hello"
fi
done
The output I am getting is as follows:
Output screenshot
Please help me fix this. Thanks in advance.
You may try :
#!/bin/bash
str="What's my favorite number? Sorry, that's not it!"
for value in {1..10}; do
variable=$(./unpackme <<< "$value")
if [ "$variable" = "$str" ]; then
echo "hello"
fi
done
Some notes :
New style $(command) is preferred to `command`.
string in command <<< string is what is called a here string : command standard input is fed with string (think of it as : echo string | command).
[ "$variable" = "$str" ]: Take care of [[ "$a" == "$b" ]]/[[ "$a" = "$b" ]], they will consider the right part of ==/= as a pattern, and may not do what you want.
Related
This question already has answers here:
Two conditions in a bash if statement
(8 answers)
Bash if statement with multiple conditions throws an error
(4 answers)
Closed 2 years ago.
I'm using
if[ "$wordCount" -gt 10 ]
To check if there are more than 10 words in the line, but how can I also check if a specific string, say "Brown Cow" is also within the line?
So the conditional should only work if the line has a wordCount of over 10 and contains the string "Brown Cow" within the $line string. Is there a way to do that within Linux/Bash? Or will I need a multi-line or different conditional like case to do it?
Using grep and then piping to the while loop, I was able to get it to work by just only running the lines with the specified string into the loop in the first place and using the same conditional if statement with:
grep -n "Brown Cow" fileName | while read line;
do
lineNumber=$(echo $line | cut -d: -f1)
lineText=${line#*;}
wordCount=`echo $line | wc -w`
if[ "$wordCount" -gt 10 ]
Commands
done
Should I update my original question to show more code or is this a sufficient answer for anyone who runs into a similar issue in the future?
You can use a regular expression or glob pattern in a [[ expression. Since the string you're looking for has spaces, it needs to be in a variable to compensate for parser restrictions:
phrase="Brown Cow"
if [[ $wordCount -gt 10 && $line =~ $phrase ]]; then
# Success
else
# Failure
fi
or
# Note the *'s for a wildcard pattern match
phrase="*Brown Cow*"
if [[ $wordCount -gt 10 && $line = $phrase ]]; then
# Success
else
# Failure
fi
This question already has answers here:
Test for empty string with X"" [duplicate]
(2 answers)
Closed 2 years ago.
Hello I have a simple example which I am confused about:
#!bin/bash
#test_str is a script to test whether a string is empty or not
x=''
if [ -n $x ]
then
echo "'$x' is not empty"
else
echo "'$x' empty"
fi
chmod u+x test_str
./test_str
The output:
'' is not empty
This occurs also if I've not declared a variable (x here).
If I use the flag -z to test for emptiness it works fine:
if [ -z $x ]
then
echo "'$x' is empty"
else
echo "'$x' not empty"
fi
The output:
'' is empty
So how can I use -n correctly?
Thank you!
This is because [ -n $n ] is expanded to [ -n ] so there is nothing to compare and it will return true.
Instead, you should use [ -n "${n}" ] to prevent such errors and to prevent globbing.
This question already has answers here:
When to wrap quotes around a shell variable?
(5 answers)
Closed 3 years ago.
here is my script:
#!/bin/bash
read -p "para:" teatp
if [ -z $teatp ]; then
echo '-z is ture'
else
echo '-z is false'
fi
if [ -n $teatp ]; then
echo '-n is ture'
else
echo '-n is false'
fi
when I input nothing and press enter, the result is
para:
-z is ture
-n is ture
on the other hand, when I input something and press enter, the result is
para:qwer1234
-z is false
-n is ture
which confused me is the first result -n is ture.
I think the -n and -z are antonyms, but why is the result the same?
There must be something I ignore or misunderstand.
I will be appreciate if someone can point out
the #testp should be quote by double quotation marks?
like:
[ -n "$teatp" ]
This question already has answers here:
Why can't I specify an environment variable and echo it in the same command line?
(9 answers)
Closed 2 years ago.
I saw codes like this:
fqdn='computer1.daveeddy.com'
IFS=. read hostname domain tld <<< "$fqdn"
echo "$hostname is in $domain.$tld"
# => "computer1 is in daveeddy.com"
I think it works because IFS is assigned to . in the third line.. So I tried this:
x=100 echo $x
but found the bash doesn't print anything, while I expect it will print 100..
Moreover, I found x=100 echo $x; echo $x print nothing, while x=100; echo $x prints 100, which is very confusing.
Does anyone have ideas about this?
The $x is expanded before echo runs, and the result is passed to echo as an argument. echo does not use the value of x in its environment.
In the first example, read uses the value of IFS in its environment to split the string it receives via the here string.
here is another way to think about it:
$ a="echo 100" $a
This is equal to:
$ a="echo 100"
Because at the time of scanning the line, $a is empty. Variable substition occurs first, so the $a just disappears.
Compare this to a very similar statment:
$ a="echo 100"; $a # returns "100"
This question already has answers here:
How to check if a string has spaces in Bash shell
(10 answers)
Closed 3 years ago.
e.g string = "test test test"
I want after finding any occurance of space in string, it should echo error and exit else process.
The case statement is useful in these kind of cases:
case "$string" in
*[[:space:]]*)
echo "argument contains a space" >&2
exit 1
;;
esac
Handles leading/trailing spaces.
There is more than one way to do that; using parameter expansion
you could write something like:
if [ "$string" != "${string% *}" ]; then
echo "$string contains one or more spaces";
fi
For a purely Bash solution:
function assertNoSpaces {
if [[ "$1" != "${1/ /}" ]]
then
echo "YOUR ERROR MESSAGE" >&2
exit 1
fi
}
string1="askdjhaaskldjasd"
string2="asjkld askldja skd"
assertNoSpaces "$string1"
assertNoSpaces "$string2" # will trigger error
"${1/ /}" removes any spaces in the input string, and when compared to the original string should be exactly the same if there are not spaces.
Note the quotes around "${1/ /}" - This ensures that leading/trailing spaces are taken into consideration.
To match more than one character, you can use regular expressions to define a pattern to match - "${1/[ \\.]/}".
update
A better approach would be to use in-process expression matching. It will probably be a wee bit faster as no string manipulation is done.
function assertNoSpaces {
if [[ "$1" =~ '[\. ]' ]]
then
echo "YOUR ERROR MESSAGE" >&2
exit 1
fi
}
For more details on the =~ operator, see the this page and this chapter in the Advanced Bash Scripting guide.
The operator was introduced in Bash version 3 so watch out if you're using an older version of Bash.
update 2
Regarding question in comments:
how to handle the code if user enter
like "asd\" means in double quotes
...can we handle it??
The function given above should work with any string so it would be down to how you get input from your user.
Assuming you're using the read command to get user input, one thing you need to watch out for is that by default backslash is treated as an escape character so it will not behave as you might expect. e.g.
read str # user enters "abc\"
echo $str # prints out "abc", not "abc\"
assertNoSpaces "$str" # no error since backslash not in variable
To counter this, use the -r option to treat backslash as a standard character. See read MAN Page for details.
read -r str # user enters "abc\"
echo $str # prints out "abc\"
assertNoSpaces "$str" # triggers error
The == operator inside double brackets can match wildcards.
if [[ $string == *' '* ]]
You can use grep as:
string="test test test"
if ( echo "$string" | grep -q ' ' ); then
echo 'var has space'
exit 1
fi
I just ran into a very similar problem while handling paths. I chose to rely on my shell's parameter expansion rather than looking for a space specifically. It does not detect spaces at the front or the end, though.
function space_exit {
if [ $# -gt 1 ]
then
echo "I cannot handle spaces." 2>&1
exit 1
fi
}