I want to validate a file name in bash to make sure that I don't have this '[]' character in it
I have this :
if ! [[ $filename=~ ^[a-zA-Z]+$ ]]; then
echo 'Wrong filename input' >&2
exit 1
fi
but I want explicitly avoid [] and allow other special characters.
any advice?
Thanks.
Use spaces around =~ operator:
[[ ! "$filename" =~ ^[a-zA-Z]+$ ]] && echo "bad filename" || echo "its good"
OR your own script:
if [[ ! "$filename" =~ ^[a-zA-Z]+$ ]]; then
echo 'Wrong filename input' >&2
exit 1
fi
Update:
If you want to explicitly avoid only [ and ] then following check is better:
if [[ "$filename" == *[]\[]* ]]; then
echo 'Wrong filename input' >&2
exit 1
fi
Related
I wanna write a script which check variables of this script.
I have tried some, but it isn't working. The idea is:
If on of the parameters is a number, print that it is number
If on of the parameters is a character, print that it is character
If 'man parameter' is executable, print that it is might be a function
Script I have tried:
#!/bin/bash
echo Hello $LOGNAME'!'
test $# -eq 0 && echo 'Try again, no parameters were entered' || echo 'Num of parameters is '$#
re='^[0-9]+$'
for i in $*
do
if ![["$i" =~ $re]];then
echo 'Parameter '$i' is alphabetical'
else
if [["$i" =~ $re]];then
echo 'Parameter '$i' is digital'
else
if [ $i];then
echo $i' might be a function. Try to use man of --help'
fi
fi
fi
done
#!/bin/bash
echo "Hello ${LOGNAME}!"
[ "$#" -eq 0 ] && { echo 'Try again, no parameters were entered'; exit 1; }
echo 'Num of parameters is '$#
re='^[0-9]+$'
for i in "$#"
do
if ! [[ "$i" =~ $re ]];then
echo "Parameter '$i' is alphabetical"
man "$i" > /dev/null 2> /dev/null
if [ "$?" -eq 0 ];then
echo "$i might be a function. Try to use man of --help"
fi
else
echo "Parameter '$i' is digital"
fi
done;
When you write a test you need spaces around your brackets.
You can easily find and fix those bugs if you use shellcheck
#!/bin/bash
var="true"
i=1
while $var
do
read -p "Enter value (true/false): " var
if [[ $var == "true" ]]
then
echo "Iteration : $i"
((i++))
elif [[ $var == "false" ]]
then
echo "Exiting the process"
elif [[ $? -eq 1 ]]
then
echo "Invalid Choice."
echo "Avaialable Choices are true or false"
exit
fi
done
Script is Working Fine. I Enter true the loop will iterate for false the script stops.
I want the script will continue asking "Enter Value" if any other value instead of true or false will be entered.
This would do the same with a more academic syntax:
i=0
while :; do
printf 'Enter value (true/false): '
read -r var
case $var in
true)
i=$((i + 1))
printf 'Iteration : %d\n' $i
;;
false)
printf 'Exiting the process\n'
break
;;
*)
printf 'Invalid Choice.\nAvaialable Choices are true or false\n'
;;
esac
done
You might find this to be a cleaner solution:
i=0
while true; do
read -p "enter value: " myinput
if [[ $myinput = true ]]; then
echo "iteration $i"
i=$((i+1))
elif [[ $myinput = false ]]; then
echo "exiting"
exit
else
echo "invalid input"
fi;
done;
The issue I see with your current code is that it is unclear which command's exit status $? refers to. Does it refer to the echo in the previous elif block? Or the last condition check? Or something else entirely?
I'm new in bash. I tried that:
#!/bin/bash
i=1
while [[ $var != "false" ]]
do
read -p "Enter value (true/false): " var
if [[ $var == "true" ]]
then
echo "Iteration : $i"
((i++))
elif [[ $var == "false" ]]
then
echo "Exiting the process"
elif [[ $? -eq 1 ]]
then
echo "Invalid Choice."
echo "Avaialable Choices are true or false"
fi
done
I changed while $var with while [[ $var ]] because while works like if. It runs the given command. In there it is $var's value.
And I moved exit to first elif expression's end. So if user type false program will exit.
I want an if/then statement in Bash and I can't seem to get it to work. I would like to say "If the line begins with > character, then do this, else do something else".
I have:
while IFS= read -r line
do
if [[$line == ">"*]]
then
echo $line'first'
else
echo $line'second'
fi
done
But it isn't working.
I also tried to escape the ">" by saying:
if [[$line == ^\>*]]
Which didn't work either.
Both ways I am getting this error:
line 27: [[>blah: command not found
Suggestions?
Spaces are needed inside [[ and ]] as follows:
if [[ "$line" == ">"* ]]; then
echo "found"
else
echo "not found"
fi
This attempt attempt uses a regex:
line="> line"
if [[ $line =~ ^\> ]] ; then
echo "found"
else
echo "not found"
fi
This one uses a glob pattern:
line="> line"
if [[ $line == \>* ]] ; then
echo "found"
else
echo "not found"
fi
Spacing is important.
$ [[ ">test" == ">"* ]]; echo $?
0
$ [[ "test" == ">"* ]]; echo $?
1
if grep -q '>' <<<$line; then
..
else
..
fi
using grep is much better :)
I need to check that the input consists only of numeric characters. I have the code below, but it didn't work properly.
if [[ $1 =~ [0-9] ]]; then
echo "Invalid input"
fi
It should give true only for 678686 not for yy66666.
How about this:-
re='^[0-9]+$'
if ! [[ $Number =~ $re ]] ; then
echo "error: Invalid input" >&2; exit 1
fi
or
case $Number in
''|*[!0-9]*) echo nonnumeric;;
*) echo numeric;;
esac
Try using start/end anchors with your pattern. If you don't, the match succeeds with a part of a test string. Don't forget that you have to use a pattern matching the complete test string if you follow this suggestion.
if [[ $1 =~ ^[0-9]+$ ]]; then
echo "Invalid input"
fi
Check out this SO post for more details.
I found an interesting Bash script that will test if a variable is numeric/integer. I like it, but I do not understand why the "0" is not recognized as a number? I can not ask the author, hi/shi is an anonymous.
#!/bin/bash
n="$1"
echo "Test numeric '$n' "
if ((n)) 2>/dev/null; then
n=$((n))
echo "Yes: $n"
else
echo "No: $n"
fi
Thank you!
UPDATE - Apr 27, 2012.
This is my final code (short version):
#!/bin/bash
ANSWER=0
DEFAULT=5
INDEX=86
read -p 'Not choosing / Wrong typing is equivalent to default (#5): ' ANSWER;
shopt -s extglob
if [[ $ANSWER == ?(-)+([0-9]) ]]
then ANSWER=$((ANSWER));
else ANSWER=$DEFAULT;
fi
if [ $ANSWER -lt 1 ] || [ $ANSWER -gt $INDEX ]
then ANSWER=$DEFAULT;
fi
It doesn't test if it is a numeric/integer. It tests if n evaluates to true or false, if 0 it is false, else (numeric or other character string) it is true.
use pattern matching to test:
if [[ $n == *[^0-9]* ]]; then echo "not numeric"; else echo numeric; fi
That won't match a negative integer though, and it will falsely match an empty string as numeric. For a more precise pattern, enable the shell's extended globbing:
shopt -s extglob
if [[ $n == ?(-)+([0-9]) ]]; then echo numeric; else echo "not numeric"; fi
And to match a fractional number
[[ $n == #(?(-)+([0-9])?(.*(0-9))|?(-)*([0-9]).+([0-9])) ]]