# test-integer2: evaluate the value of an integer.
INT=-5 if [[ "$INT" =~ ^-?[0-9]+$ ]]; then if [ $INT -eq 0 ]; then echo"INT is zero." else if [ $INT -lt 0 ]; then echo"INT is negative." else echo"INT is positive." fi if [ $((INT % 2)) -eq 0 ]; then echo"INT is even." else echo"INT is odd." fifi else echo"INT is not an integer." >&2 exit 1 fi
1 2 3 4
(base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ chmod +x test-integer2.sh (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./test-integer2.sh INT is negative. INT is odd.
[[ ]]添加的另一个功能是==操作符支持类型匹配。
1 2 3 4 5 6 7
#!/bin/bash
FILE=foo.bar
if [[ $FILE == foo.* ]]; then echo"$FILE matches pattern 'foo.*'" fi
(base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ if ((1)); thenecho"It is true."; fi It is true. (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ if ((0)); thenecho"It is true."; f
$ read --help read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] Read a line from the standard input and split it into fields.
Reads a single line from the standard input, or from file descriptor FD if the -u option is supplied. The line is split into fields as with word splitting, and the first word is assigned to the first NAME, the second word to the second NAME, and so on, with any leftover words assigned to the last NAME. Only the characters found in$IFS are recognized as word delimiters.
If no NAMEs are supplied, the line read is stored in the REPLY variable.
Options: -a array assign the words read to sequential indices of the array variable ARRAY, starting at zero -d delim continue until the first character of DELIM is read, rather than newline -e use Readline to obtain the line in an interactive shell -i text use TEXT as the initial text for Readline -n nchars return after reading NCHARS characters rather than waiting for a newline, but honor a delimiter if fewer than NCHARS characters are read before the delimiter -N nchars return only after reading exactly NCHARS characters, unless EOF is encountered or readtimes out, ignoring any delimiter -p prompt output the string PROMPT without a trailing newline before attempting to read -r do not allow backslashes to escape any characters -s do not echo input coming from a terminal -t timeout time out and return failure if a complete line of input is not read within TIMEOUT seconds. The value of the TMOUT variable is the default timeout. TIMEOUT may be a fractional number. If TIMEOUT is 0, read returns immediately, without trying to read any data, returning success only if input is available on the specified file descriptor. The exit status is greater than 128 if the timeout is exceeded -u fd read from file descriptor FD instead of the standard input
Exit Status: The return code is zero, unless end-of-file is encountered, readtimes out (inwhichcase it's greater than 128), a variable assignment error occurs, or an invalid file descriptor is supplied as the argument to -u.
echo -n "Please enter an integer -> " read int if [[ "$int" =~ ^-?[0-9]+$ ]]; then if [ $int -eq 0 ]; then echo"$int is zero." else if [ $int -lt 0 ]; then echo"$int is negative." else echo"$int is positive." fi if [ $((int % 2)) -eq 0 ]; then echo"$int is even." else echo"$int is odd." fi fi else echo"Input value is not an integer." >&2 exit 1 fi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
(base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ chmod +x read-integer.sh (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-integer.sh Please enter an integer -> q Input value is not an integer. (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-integer.sh Please enter an integer -> 1 1 is positive. 1 is odd. (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-integer.sh Please enter an integer -> 0 0 is zero. (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-integer.sh Please enter an integer -> -5 -5 is negative. -5 is odd.
(base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ chmod +x read-multiple.sh (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-multiple.sh Enter one or more values > a b c d e var1 = 'a' var2 = 'b' var3 = 'c' var4 = 'd' var5 = 'e' (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-multiple.sh Enter one or more values > a var1 = 'a' var2 = '' var3 = '' var4 = '' var5 = '' (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-multiple.sh Enter one or more values > a b c d e f g var1 = 'a' var2 = 'b' var3 = 'c' var4 = 'd' var5 = 'e f g
如果read命令之后没有列出变量名,则一个shell变量REPLY将会包含所有的输入。
1 2 3 4 5 6 7
#!/bin/bash
# read-single: read multiple values into default variable
echo -n "Enter one or more values > " read echo"REPLY = '$REPLY'"
1 2 3 4
(base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ chmod +x read-single.sh (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-single.sh Enter one or more values > a b c d REPLY = 'a b c d'
-p选项,指定提示信息:
1 2 3 4 5 6
#!/bin/bash
# read-single: read multiple values into default variable
read -p "Enter one or more values > " echo"REPLY = '$REPLY'"
1 2 3 4
(base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ chmod +x read-single2.sh (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-single2.sh Enter one or more values > 127309 218741 REPLY = '127309 218741'
FILE=/etc/passwd read -p "Enter a user name > " user_name file_info=$(grep "^$user_name:"$FILE) if [ -n "$file_info" ]; then IFS=":"read user pw uid gid name home shell <<<"$file_info" echo"User = '$user'" echo"UID = '$uid'" echo"GID = '$gid'" echo"Full Name = '$name'" echo"Home Dir. = '$home'" echo"Shell = '$shell'" else echo"No such user '$user_name'" >&2 exit 1 fi
(base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ chmod +x read-ifs.sh (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-ifs.sh Enter a user name > onns No such user 'onns' (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-ifs.sh Enter a user name > hs User = 'hs' UID = '1000' GID = '1000' Full Name = 'hs,,,' Home Dir. = '/home/hs' Shell = '/bin/bash' (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-ifs.sh Enter a user name > git User = 'git' UID = '1001' GID = '1001' Full Name = ',,,' Home Dir. = '/home/git' Shell = '/usr/bin/git-shell'
shell允许在一个命令之前给一个或多个变量赋值。这些赋值会暂时改变之后的命令的环境变量。
1 2 3 4 5 6 7 8
IFS=":"read user pw uid gid name home shell <<<"$file_info"
# 等价于👇
OLD_IFS="$IFS" IFS=":" read user pw uid gid name home shell <<< "$file_info" IFS="$OLD_IFS"
# is input a valid filename? if [[ $REPLY =~ ^[-[:alnum:]\._]+$ ]]; then echo"'$REPLY' is a valid filename." if [[ -e $REPLY ]]; then echo"And file '$REPLY' exists." else echo"However, file '$REPLY' does not exist." fi
# is input a floating point number? if [[ $REPLY =~ ^-?[[:digit:]]*\.[[:digit:]]+$ ]]; then echo"'$REPLY' is a floating point number." else echo"'$REPLY' is not a floating point number." fi
# is input an integer? if [[ $REPLY =~ ^-?[[:digit:]]+$ ]]; then echo"'$REPLY' is an integer." else echo"'$REPLY' is not an integer." fi else echo"The string '$REPLY' is not a valid filename." fi
(base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ chmod +x read-validate.sh (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-validate.sh Enter a single item > read-validate.sh 'read-validate.sh' is a valid filename. And file 'read-validate.sh' exists. 'read-validate.sh' is not a floating point number. 'read-validate.sh' is not an integer. (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-validate.sh Enter a single item > -1.234 '-1.234' is a valid filename. However, file '-1.234' does not exist. '-1.234' is a floating point number. '-1.234' is not an integer. (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-validate.sh Enter a single item > -3 '-3' is a valid filename. However, file '-3' does not exist. '-3' is not a floating point number. '-3' is an integer. (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./read-validate.sh Enter a single item > ,,..eqwehu The string ',,..eqwehu' is not a valid filename.
number=1 set -x # Turn on tracing if [ $number = 1 ]; then echo"Number is equal to 1." else echo"Number is not equal to 1." fi set +x # Turn off tracing
1 2 3 4 5 6
(base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ chmod +x trouble.sh (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./trouble.sh + '[' 1 = 1 ']' + echo'Number is equal to 1.' Number is equal to 1. + set +x
case word in [pattern [| pattern]...) commands ;;]... esac
模式
描述
a)
若单词为a,则匹配
[[:alpha:]])
若单词是一个字母字符,则匹配
???)
若单词只有3个字符,则匹配
*.txt)
若单词以.txt字符结尾,则匹配
*)
匹配任意单词
添加;;&的语法允许case语句继续执行下一条测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#!/bin/bash
# case4-2: test a character
read -n 1 -p "Type a character > " echo case$REPLYin [[:upper:]]) echo"'$REPLY' is upper case." ;;& [[:lower:]]) echo"'$REPLY' is lower case." ;;& [[:alpha:]]) echo"'$REPLY' is alphabetic." ;;& [[:digit:]]) echo"'$REPLY' is a digit." ;;& [[:graph:]]) echo"'$REPLY' is a visible character." ;;& [[:punct:]]) echo"'$REPLY' is a punctuation symbol." ;;& [[:space:]]) echo"'$REPLY' is a whitespace character." ;;& [[:xdigit:]]) echo"'$REPLY' is a hexadecimal digit." ;;& esac
1 2 3 4 5 6 7
(base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ chmod +x case4-2.sh (base) hs@hs-Z390-AORUS-PRO:/mnt/data/onns/Desktop$ ./case4-2.sh Type a character > a 'a' is lower case. 'a' is alphabetic. 'a' is a visible character. 'a' is a hexadecimal digit.