BASH: OR operator for positional $1
Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
I faced some issue, where OR operator doesn't work for $1.
Eg:
if [[ "$1" != '1' || '2' ]]
then
echo "BAD"
else
echo "OK"
fi
When I run this test no matter what $1 is, BAD always appears.
How can I tie $1 to be 1 or 2 only?
linux bash
add a comment |Â
up vote
0
down vote
favorite
I faced some issue, where OR operator doesn't work for $1.
Eg:
if [[ "$1" != '1' || '2' ]]
then
echo "BAD"
else
echo "OK"
fi
When I run this test no matter what $1 is, BAD always appears.
How can I tie $1 to be 1 or 2 only?
linux bash
This is a very common error. I see it a lot with beginner programmers. However it is not how boolean logic works. Imagine putting in brackets. Where could you put them to make it work? Note there are some languages that you can askif $1 is not in '1', '2' then â¦
(see case example in bash).
â ctrl-alt-delor
Feb 8 at 12:47
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I faced some issue, where OR operator doesn't work for $1.
Eg:
if [[ "$1" != '1' || '2' ]]
then
echo "BAD"
else
echo "OK"
fi
When I run this test no matter what $1 is, BAD always appears.
How can I tie $1 to be 1 or 2 only?
linux bash
I faced some issue, where OR operator doesn't work for $1.
Eg:
if [[ "$1" != '1' || '2' ]]
then
echo "BAD"
else
echo "OK"
fi
When I run this test no matter what $1 is, BAD always appears.
How can I tie $1 to be 1 or 2 only?
linux bash
edited Feb 8 at 11:55
Jeff Schaller
31.3k846105
31.3k846105
asked Feb 8 at 11:52
faceless
253
253
This is a very common error. I see it a lot with beginner programmers. However it is not how boolean logic works. Imagine putting in brackets. Where could you put them to make it work? Note there are some languages that you can askif $1 is not in '1', '2' then â¦
(see case example in bash).
â ctrl-alt-delor
Feb 8 at 12:47
add a comment |Â
This is a very common error. I see it a lot with beginner programmers. However it is not how boolean logic works. Imagine putting in brackets. Where could you put them to make it work? Note there are some languages that you can askif $1 is not in '1', '2' then â¦
(see case example in bash).
â ctrl-alt-delor
Feb 8 at 12:47
This is a very common error. I see it a lot with beginner programmers. However it is not how boolean logic works. Imagine putting in brackets. Where could you put them to make it work? Note there are some languages that you can ask
if $1 is not in '1', '2' then â¦
(see case example in bash).â ctrl-alt-delor
Feb 8 at 12:47
This is a very common error. I see it a lot with beginner programmers. However it is not how boolean logic works. Imagine putting in brackets. Where could you put them to make it work? Note there are some languages that you can ask
if $1 is not in '1', '2' then â¦
(see case example in bash).â ctrl-alt-delor
Feb 8 at 12:47
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
5
down vote
accepted
With standard sh
syntax (so not only recognised by bash
but all other POSIX compatible shells):
case $1 in
(1 | 2) echo OK;;
(*) echo BAD;;
esac
Or:
if [ "$1" = 1 ] || [ "$1" = 2 ]; then
echo OK
else
echo BAD
fi
(note that it's a byte-to-byte comparison of strings. 01, 1e0, 1.0, 20/20, 0x1 would also be considered as BAD even though numerically they could be regarded as being the same as 1
).
Note that the =
/!=
operators in bash
's [[...]]
construct (copied from ksh
) are actually pattern matching operators as opposed to equality operators, so in this special case where you want to match a single character, you could also use [[ $1 != [12] ]]
like you could do case $1 in ([12])
in standard sh
syntax.
Magnificent idea with case! Dunno how didn't i use it myself )
â faceless
Feb 8 at 12:42
add a comment |Â
up vote
4
down vote
The reason you always go into the BAD
branch of the if
statement is that the test
[[ "$1" != '1' || '2' ]]
first tests whether $1
is not 1
, and if it is not, BAD
is printed. If it is, 2
is evaluated as a test. A string like 2
is always true, and BAD
is printed.
Instead:
if [ "$1" != '1' ] && [ "$1" != '2' ]; then
or, with arithmetic tests,
if [ "$1" -ne 1 ] && [ "$1" -ne 2 ]; then
or, using arithmetic evaluation,
if (( $1 != 1 )) && (( $1 != 2 )); then
add a comment |Â
up vote
1
down vote
if [[ "$1" != '1' || "$1" != '2' ]]
then
echo "BAD"
else
echo "OK"
fi
Then != statement needs to be repeated for the not equal to 2 as well as 1
The result is the same.
â faceless
Feb 8 at 11:59
add a comment |Â
up vote
1
down vote
The logic of ($1 != 1) OR ($1 != 2)
is flawed.
If $1
is 1
then it is not equal to 2
so the test will be true.
Also, if $1
is 2
then it is not equal to 1
so the test will be also true.
In short, the test will always be true.
You should test equality: ($1 == 1) or ($1 == 2)
like this:
if [[ ($1 == '1') || ($1 == '2') ]]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
Or simpler (in ksh, bash or zsh):
[[ $1 == [12] ]] && echo "$1 OK" || echo "$1 BAD"
Or using sh syntax (portable to all POSIX shells):
if [ "$1" = '1' ] || [ "$1" = '2' ]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
Or with a case idiom:
case $1 in
(1 | 2) echo "$1 OK" ;;
(*) echo BAD "$1 BAD" ;;
esac
All the above is a string comparison, if you want a numeric comparison, you may do:
if [ "$1" -eq 1 ] || [ "$1" -eq 2 ]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
However, that will not work if $1
is 1.0
or 1e0
or many other numerical equivalent to 1
. Will work with 01
or 0001
though.
2
Note that what is supported in[ "$1" -eq 1 ]
varies from shell/[
to shell/[
(and is an arbitrary command injection in some if$1
comes from an untrusted source). With ksh93, that would return true for 1.0 or 1e0 or 20/20 and sometimes with RANDOM%2 and reboot with'a[$(reboot)]'
.
â Stéphane Chazelas
Feb 8 at 19:15
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
With standard sh
syntax (so not only recognised by bash
but all other POSIX compatible shells):
case $1 in
(1 | 2) echo OK;;
(*) echo BAD;;
esac
Or:
if [ "$1" = 1 ] || [ "$1" = 2 ]; then
echo OK
else
echo BAD
fi
(note that it's a byte-to-byte comparison of strings. 01, 1e0, 1.0, 20/20, 0x1 would also be considered as BAD even though numerically they could be regarded as being the same as 1
).
Note that the =
/!=
operators in bash
's [[...]]
construct (copied from ksh
) are actually pattern matching operators as opposed to equality operators, so in this special case where you want to match a single character, you could also use [[ $1 != [12] ]]
like you could do case $1 in ([12])
in standard sh
syntax.
Magnificent idea with case! Dunno how didn't i use it myself )
â faceless
Feb 8 at 12:42
add a comment |Â
up vote
5
down vote
accepted
With standard sh
syntax (so not only recognised by bash
but all other POSIX compatible shells):
case $1 in
(1 | 2) echo OK;;
(*) echo BAD;;
esac
Or:
if [ "$1" = 1 ] || [ "$1" = 2 ]; then
echo OK
else
echo BAD
fi
(note that it's a byte-to-byte comparison of strings. 01, 1e0, 1.0, 20/20, 0x1 would also be considered as BAD even though numerically they could be regarded as being the same as 1
).
Note that the =
/!=
operators in bash
's [[...]]
construct (copied from ksh
) are actually pattern matching operators as opposed to equality operators, so in this special case where you want to match a single character, you could also use [[ $1 != [12] ]]
like you could do case $1 in ([12])
in standard sh
syntax.
Magnificent idea with case! Dunno how didn't i use it myself )
â faceless
Feb 8 at 12:42
add a comment |Â
up vote
5
down vote
accepted
up vote
5
down vote
accepted
With standard sh
syntax (so not only recognised by bash
but all other POSIX compatible shells):
case $1 in
(1 | 2) echo OK;;
(*) echo BAD;;
esac
Or:
if [ "$1" = 1 ] || [ "$1" = 2 ]; then
echo OK
else
echo BAD
fi
(note that it's a byte-to-byte comparison of strings. 01, 1e0, 1.0, 20/20, 0x1 would also be considered as BAD even though numerically they could be regarded as being the same as 1
).
Note that the =
/!=
operators in bash
's [[...]]
construct (copied from ksh
) are actually pattern matching operators as opposed to equality operators, so in this special case where you want to match a single character, you could also use [[ $1 != [12] ]]
like you could do case $1 in ([12])
in standard sh
syntax.
With standard sh
syntax (so not only recognised by bash
but all other POSIX compatible shells):
case $1 in
(1 | 2) echo OK;;
(*) echo BAD;;
esac
Or:
if [ "$1" = 1 ] || [ "$1" = 2 ]; then
echo OK
else
echo BAD
fi
(note that it's a byte-to-byte comparison of strings. 01, 1e0, 1.0, 20/20, 0x1 would also be considered as BAD even though numerically they could be regarded as being the same as 1
).
Note that the =
/!=
operators in bash
's [[...]]
construct (copied from ksh
) are actually pattern matching operators as opposed to equality operators, so in this special case where you want to match a single character, you could also use [[ $1 != [12] ]]
like you could do case $1 in ([12])
in standard sh
syntax.
edited Feb 8 at 12:56
answered Feb 8 at 12:12
Stéphane Chazelas
281k53516847
281k53516847
Magnificent idea with case! Dunno how didn't i use it myself )
â faceless
Feb 8 at 12:42
add a comment |Â
Magnificent idea with case! Dunno how didn't i use it myself )
â faceless
Feb 8 at 12:42
Magnificent idea with case! Dunno how didn't i use it myself )
â faceless
Feb 8 at 12:42
Magnificent idea with case! Dunno how didn't i use it myself )
â faceless
Feb 8 at 12:42
add a comment |Â
up vote
4
down vote
The reason you always go into the BAD
branch of the if
statement is that the test
[[ "$1" != '1' || '2' ]]
first tests whether $1
is not 1
, and if it is not, BAD
is printed. If it is, 2
is evaluated as a test. A string like 2
is always true, and BAD
is printed.
Instead:
if [ "$1" != '1' ] && [ "$1" != '2' ]; then
or, with arithmetic tests,
if [ "$1" -ne 1 ] && [ "$1" -ne 2 ]; then
or, using arithmetic evaluation,
if (( $1 != 1 )) && (( $1 != 2 )); then
add a comment |Â
up vote
4
down vote
The reason you always go into the BAD
branch of the if
statement is that the test
[[ "$1" != '1' || '2' ]]
first tests whether $1
is not 1
, and if it is not, BAD
is printed. If it is, 2
is evaluated as a test. A string like 2
is always true, and BAD
is printed.
Instead:
if [ "$1" != '1' ] && [ "$1" != '2' ]; then
or, with arithmetic tests,
if [ "$1" -ne 1 ] && [ "$1" -ne 2 ]; then
or, using arithmetic evaluation,
if (( $1 != 1 )) && (( $1 != 2 )); then
add a comment |Â
up vote
4
down vote
up vote
4
down vote
The reason you always go into the BAD
branch of the if
statement is that the test
[[ "$1" != '1' || '2' ]]
first tests whether $1
is not 1
, and if it is not, BAD
is printed. If it is, 2
is evaluated as a test. A string like 2
is always true, and BAD
is printed.
Instead:
if [ "$1" != '1' ] && [ "$1" != '2' ]; then
or, with arithmetic tests,
if [ "$1" -ne 1 ] && [ "$1" -ne 2 ]; then
or, using arithmetic evaluation,
if (( $1 != 1 )) && (( $1 != 2 )); then
The reason you always go into the BAD
branch of the if
statement is that the test
[[ "$1" != '1' || '2' ]]
first tests whether $1
is not 1
, and if it is not, BAD
is printed. If it is, 2
is evaluated as a test. A string like 2
is always true, and BAD
is printed.
Instead:
if [ "$1" != '1' ] && [ "$1" != '2' ]; then
or, with arithmetic tests,
if [ "$1" -ne 1 ] && [ "$1" -ne 2 ]; then
or, using arithmetic evaluation,
if (( $1 != 1 )) && (( $1 != 2 )); then
edited Feb 8 at 12:41
answered Feb 8 at 12:02
Kusalananda
103k13202318
103k13202318
add a comment |Â
add a comment |Â
up vote
1
down vote
if [[ "$1" != '1' || "$1" != '2' ]]
then
echo "BAD"
else
echo "OK"
fi
Then != statement needs to be repeated for the not equal to 2 as well as 1
The result is the same.
â faceless
Feb 8 at 11:59
add a comment |Â
up vote
1
down vote
if [[ "$1" != '1' || "$1" != '2' ]]
then
echo "BAD"
else
echo "OK"
fi
Then != statement needs to be repeated for the not equal to 2 as well as 1
The result is the same.
â faceless
Feb 8 at 11:59
add a comment |Â
up vote
1
down vote
up vote
1
down vote
if [[ "$1" != '1' || "$1" != '2' ]]
then
echo "BAD"
else
echo "OK"
fi
Then != statement needs to be repeated for the not equal to 2 as well as 1
if [[ "$1" != '1' || "$1" != '2' ]]
then
echo "BAD"
else
echo "OK"
fi
Then != statement needs to be repeated for the not equal to 2 as well as 1
answered Feb 8 at 11:56
Raman Sailopal
1,18117
1,18117
The result is the same.
â faceless
Feb 8 at 11:59
add a comment |Â
The result is the same.
â faceless
Feb 8 at 11:59
The result is the same.
â faceless
Feb 8 at 11:59
The result is the same.
â faceless
Feb 8 at 11:59
add a comment |Â
up vote
1
down vote
The logic of ($1 != 1) OR ($1 != 2)
is flawed.
If $1
is 1
then it is not equal to 2
so the test will be true.
Also, if $1
is 2
then it is not equal to 1
so the test will be also true.
In short, the test will always be true.
You should test equality: ($1 == 1) or ($1 == 2)
like this:
if [[ ($1 == '1') || ($1 == '2') ]]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
Or simpler (in ksh, bash or zsh):
[[ $1 == [12] ]] && echo "$1 OK" || echo "$1 BAD"
Or using sh syntax (portable to all POSIX shells):
if [ "$1" = '1' ] || [ "$1" = '2' ]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
Or with a case idiom:
case $1 in
(1 | 2) echo "$1 OK" ;;
(*) echo BAD "$1 BAD" ;;
esac
All the above is a string comparison, if you want a numeric comparison, you may do:
if [ "$1" -eq 1 ] || [ "$1" -eq 2 ]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
However, that will not work if $1
is 1.0
or 1e0
or many other numerical equivalent to 1
. Will work with 01
or 0001
though.
2
Note that what is supported in[ "$1" -eq 1 ]
varies from shell/[
to shell/[
(and is an arbitrary command injection in some if$1
comes from an untrusted source). With ksh93, that would return true for 1.0 or 1e0 or 20/20 and sometimes with RANDOM%2 and reboot with'a[$(reboot)]'
.
â Stéphane Chazelas
Feb 8 at 19:15
add a comment |Â
up vote
1
down vote
The logic of ($1 != 1) OR ($1 != 2)
is flawed.
If $1
is 1
then it is not equal to 2
so the test will be true.
Also, if $1
is 2
then it is not equal to 1
so the test will be also true.
In short, the test will always be true.
You should test equality: ($1 == 1) or ($1 == 2)
like this:
if [[ ($1 == '1') || ($1 == '2') ]]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
Or simpler (in ksh, bash or zsh):
[[ $1 == [12] ]] && echo "$1 OK" || echo "$1 BAD"
Or using sh syntax (portable to all POSIX shells):
if [ "$1" = '1' ] || [ "$1" = '2' ]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
Or with a case idiom:
case $1 in
(1 | 2) echo "$1 OK" ;;
(*) echo BAD "$1 BAD" ;;
esac
All the above is a string comparison, if you want a numeric comparison, you may do:
if [ "$1" -eq 1 ] || [ "$1" -eq 2 ]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
However, that will not work if $1
is 1.0
or 1e0
or many other numerical equivalent to 1
. Will work with 01
or 0001
though.
2
Note that what is supported in[ "$1" -eq 1 ]
varies from shell/[
to shell/[
(and is an arbitrary command injection in some if$1
comes from an untrusted source). With ksh93, that would return true for 1.0 or 1e0 or 20/20 and sometimes with RANDOM%2 and reboot with'a[$(reboot)]'
.
â Stéphane Chazelas
Feb 8 at 19:15
add a comment |Â
up vote
1
down vote
up vote
1
down vote
The logic of ($1 != 1) OR ($1 != 2)
is flawed.
If $1
is 1
then it is not equal to 2
so the test will be true.
Also, if $1
is 2
then it is not equal to 1
so the test will be also true.
In short, the test will always be true.
You should test equality: ($1 == 1) or ($1 == 2)
like this:
if [[ ($1 == '1') || ($1 == '2') ]]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
Or simpler (in ksh, bash or zsh):
[[ $1 == [12] ]] && echo "$1 OK" || echo "$1 BAD"
Or using sh syntax (portable to all POSIX shells):
if [ "$1" = '1' ] || [ "$1" = '2' ]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
Or with a case idiom:
case $1 in
(1 | 2) echo "$1 OK" ;;
(*) echo BAD "$1 BAD" ;;
esac
All the above is a string comparison, if you want a numeric comparison, you may do:
if [ "$1" -eq 1 ] || [ "$1" -eq 2 ]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
However, that will not work if $1
is 1.0
or 1e0
or many other numerical equivalent to 1
. Will work with 01
or 0001
though.
The logic of ($1 != 1) OR ($1 != 2)
is flawed.
If $1
is 1
then it is not equal to 2
so the test will be true.
Also, if $1
is 2
then it is not equal to 1
so the test will be also true.
In short, the test will always be true.
You should test equality: ($1 == 1) or ($1 == 2)
like this:
if [[ ($1 == '1') || ($1 == '2') ]]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
Or simpler (in ksh, bash or zsh):
[[ $1 == [12] ]] && echo "$1 OK" || echo "$1 BAD"
Or using sh syntax (portable to all POSIX shells):
if [ "$1" = '1' ] || [ "$1" = '2' ]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
Or with a case idiom:
case $1 in
(1 | 2) echo "$1 OK" ;;
(*) echo BAD "$1 BAD" ;;
esac
All the above is a string comparison, if you want a numeric comparison, you may do:
if [ "$1" -eq 1 ] || [ "$1" -eq 2 ]; then
echo "$1 OK"
else
echo "$1 BAD"
fi
However, that will not work if $1
is 1.0
or 1e0
or many other numerical equivalent to 1
. Will work with 01
or 0001
though.
edited Feb 8 at 19:11
Stéphane Chazelas
281k53516847
281k53516847
answered Feb 8 at 19:02
Isaac
6,6381734
6,6381734
2
Note that what is supported in[ "$1" -eq 1 ]
varies from shell/[
to shell/[
(and is an arbitrary command injection in some if$1
comes from an untrusted source). With ksh93, that would return true for 1.0 or 1e0 or 20/20 and sometimes with RANDOM%2 and reboot with'a[$(reboot)]'
.
â Stéphane Chazelas
Feb 8 at 19:15
add a comment |Â
2
Note that what is supported in[ "$1" -eq 1 ]
varies from shell/[
to shell/[
(and is an arbitrary command injection in some if$1
comes from an untrusted source). With ksh93, that would return true for 1.0 or 1e0 or 20/20 and sometimes with RANDOM%2 and reboot with'a[$(reboot)]'
.
â Stéphane Chazelas
Feb 8 at 19:15
2
2
Note that what is supported in
[ "$1" -eq 1 ]
varies from shell/[
to shell/[
(and is an arbitrary command injection in some if $1
comes from an untrusted source). With ksh93, that would return true for 1.0 or 1e0 or 20/20 and sometimes with RANDOM%2 and reboot with 'a[$(reboot)]'
.â Stéphane Chazelas
Feb 8 at 19:15
Note that what is supported in
[ "$1" -eq 1 ]
varies from shell/[
to shell/[
(and is an arbitrary command injection in some if $1
comes from an untrusted source). With ksh93, that would return true for 1.0 or 1e0 or 20/20 and sometimes with RANDOM%2 and reboot with 'a[$(reboot)]'
.â Stéphane Chazelas
Feb 8 at 19:15
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f422783%2fbash-or-operator-for-positional-1%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
This is a very common error. I see it a lot with beginner programmers. However it is not how boolean logic works. Imagine putting in brackets. Where could you put them to make it work? Note there are some languages that you can ask
if $1 is not in '1', '2' then â¦
(see case example in bash).â ctrl-alt-delor
Feb 8 at 12:47