And I am expecting script to exit when I pass "m". But its not working as expected.
Ok, so, you have the conditional:
if [ $value != "y" ] || [ $value != "n" ]; then
echo "invalid"
...
If $value is m, it's not equal to y, and it's not equal to n, so that evaluates to (true or true), which is true, and the commands inside the if are executed.
If $value if y, it is equal to y, but is not equal to n, so that evaluates to (false or true), which is true, so the commands inside the if are executed again.
The only case where the commands inside the if would not be executed would be the case where both tests would be false -- $value would need to be equal to y and equal to n at the same time.
Basically, what you want here is this
if [ $value = "y" ] || [ $value = "n" ]; then
echo ok
else
echo invalid
fi
But without the useless "ok" branch, so the condition inverted:
if ! ( [ $value = "y" ] || [ $value = "n" ] ); then
echo invalid
fi
Now, the inverse of (A or B) is not (not A or not B), but (not A and not B), so that's what your condition needs to say.
Also, you want to quote the variable expansion, because otherwise whitespace in the contents of $value will mess up how the command is interpreted, so:
if [ "$value" != "y" ] && [ "$value" != "n" ]; then
echo invalid
fi
(or use [[ $value != "y" ]] etc., since [[ is special and one of the few cases where whitespace doesn't cause splitting.)
See also: