shell脚本技巧

linux中shell变量

linux中shell变量$#,$@,$0,$1,$2的含义解释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

变量说明:
$$
Shell本身的PID(ProcessID)
$!
Shell最后运行的后台Process的PID
$?
最后运行的命令的结束代码(返回值)
$-
使用Set命令设定的Flag一览
$*
所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$@
所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$#
添加到Shell的参数个数
$0
Shell本身的文件名
$1~$n

A:$*$@的区别

$*$@都表示传递给函数或脚本的所有参数,不被双引号(“ “)包含时,都以"$1" "$2" … "$n"的形式输出所有参数。
但是当它们被双引号(“ “)包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n"的形式输出所有参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

#test.sh

#!/bin/bash
echo "\$*=" $*
echo "\"\$*\"=" "$*"
echo "\$@=" $@
echo "\"\$@\"=" "$@"
echo "print each param from \$*"
for var in $*
do
echo "$var"
done
echo "print each param from \$@"
for var in $@
do
echo "$var"
done
echo "print each param from \"\$*\""
for var in "$*"
do
echo "$var"
done
echo "print each param from \"\$@\""
for var in "$@"
do
echo "$var"
done

./test.sh "a" "b" "c" "d"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

$*= a b c d

"$*"= a b c d

$@= a b c d

"$@"= a b c d

print each param from $*

a

b

c

d

print each param from $@

a

b

c

d

print each param from "$*"

a b c d

print each param from "$@"

a

b

c

d

B:$?退出状态

就是上一个命令执行后的返回结果。退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1。不过,也有一些命令返回其他值,表示不同类型的错误。

getopts参数处理

使用getopts方式实现短选项的处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

#getopts.sh

#!/bin/bash
PROG=`basename $0`
usage() {
cat <<EOF
Usage: ${PROG} [OPTION]…
Find out the highest cpu consumed threads of java, and print the stack of these threads.
Example: ${PROG} -i interface -P 3306 start
Options:
-i, interface
-c, port
-h, --help display this help and exit
EOF
exit $1
}
while getopts "i:P:" arg
do
case $arg in
i)
interface=${OPTARG:-any}
;;
P)
port=${OPTARG:-3306}
;;
?)
usage 1
;;
esac
done
interface=${interface:-any}
port=${port:-3306}
shift $(($OPTIND - 1))
if [ $# -eq 0 ]; then
usage 1
fi
mode=$1
echo $interface
echo $port
echo $mode

A:while getopts ":a:bc" opt

第一个冒号表示忽略错误;字符后面的冒号表示该选项必须有自己的参数

B:shift $(($OPTIND - 1))

通过shift $(($OPTIND - 1))的处理,$*中就只保留了除去选项内容的参数,可以在其后进行正常的shell编程处理了。

C:basename $0 取出文件名

D:usage 1代表传参1,在usage中执行exit 1退出

1
2
3
4

if [ $# -eq 0 ]; then
usage 1
fi

F:放在shift $(($OPTIND - 1))之后,有两个作用:一是传入参数为0时退出,二是选项之后没有跟参数时退出

G:getopts不能直接处理长的选项(如:–prefix=/home等)

H:内置变量$OPTARG$OPTIND,$OPTARG存储相应选项的参数,而$OPTIND总是存储原始$*中下一个要处理的元素位置

I:interface=${OPTARG:-any}为了在interface为空字符串时赋值any,interface=${interface:-any},为了防止在interface没有输入时,设置为any

使用getopt实现长/短选项的处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

#basename命令用于打印目录或者文件的基本名称

PROG=`basename $0`

usage() {
cat <<EOF
Usage: ${PROG} [OPTION]...
Find out the highest cpu consumed threads of java, and print the stack of these threads.
Example: ${PROG} -c 10
Options:
-p, --pid find out the highest cpu consumed threads from the specifed java process,
default from all java process.
-c, --count set the thread count to show, default is 5
-h, --help display this help and exit
EOF
exit $1
}

if [ $# -eq 0 ]; then
usage 1
fi

ARGS=`getopt -n "$PROG" -a -o c:p:h -l count:,pid:,help -- "$@"`

#等价于[ $? -ne 0 ] && usage,就是如果前面的错误就调用usage方法

[ $? -ne 0 ] && usage 1

eval set -- "${ARGS}"
while true; do
case "$1" in
-c|--count)
count="$2"
shift 2

#;;这是case语法
;;
-p|--pid)
pid="$2"
shift 2
;;
-h|--help)
usage
;;
--)
shift
break
;;
esac
done

getopt

1
2
3
4
5
6
7
8
9
10
11

-a, --alternative
Allow long options to start with a single ‘-’.

-l, --longoptions longopts 支持的长选项,由冒号和字符组成类似getopts

-o, --options shortopts 支持的短选项,同上

-n, --name progname 命令就是通过该名称被调用

-- "$@" 将所有参数列表当作getopt入参,

倒计时效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

#sc 保存当前光标位置
#rc 恢复光标到最后保存位置

#ed 向前清除一个字符

#tput.sh

tput sc

count=10;

while true; do

if [ $count -gt 1 ]; then

let count--;

sleep 1;

tput rc

tput ed

echo -n $count Seconds;

else

break

fi

done

read命令

A:read后面的变量只有name一个,也可以有多个,这时如果输入多个数据,则第一个数据给第一个变量,第二个数据给第二个变量,如果输入数 据个数过多,则最后所有的值都给第一个变量。如果太少输入不会结束。在read命令行中也可以不指定变量.如果不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中

-p参数,允许在read命令行中直接指定一个提示

B:计时输入

1
2
3
4
5
6
7
8
9

#!/bin/bash
if read -t 5 -p "please enter your name:" name
then
echo "hello $name ,welcome to my script"
else
echo "sorry,too slow"
fi
exit 0

格式化输出 echo “$(date +%Y-%m-%d\ %H:%M:%S) ** 该服务器没有安装 MySQL Server”

eval 用法

shift

A:位置参数可以用shift命令左移。比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1$2$3丢弃,$0不移动。不带参数的shift命令相当于shift 1

B:Shift 命令还有另外一个重要用途, Bsh 定义了9个位置变量,从 $1$9,这并不意味着用户在命令行只能使用9个参数,借助 shift 命令可以访问多于9个的参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#shift.sh

if [ $# -eq 0 ]
then
echo "Usage:x_shift2.sh 参数"
exit 1
fi
sum=0
until [ $# -eq 0 ]
do
sum=`expr $sum + $1`
shift
done
echo "sum is: $sum"

./shift.sh 10 20 15

eval

eval命令将会首先扫描命令行进行所有的替换,然后再执行命令。该命令使用于那些一次扫描无法实现其功能的变量。该命令对变量进行两次扫描。这些需要进行两次扫描的变量有时候被称为复杂变量

eval set -- "{value}"

If no arguments follow this option, then the positional parameters are unset. Otherwise, the positional parameters are set to the args, even if some of them begin with a -.(即使有些参数是以-开头的,只要有参数,都会被设置位置参数)

1
2
3
4
5
6
7
8
9
10
11
12
13

#eval也可以用于回显简单变量,不一定时复杂变量。
NAME=ZONE
eval echo $NAME等价于echo $NAME
#两次扫描
test.txt内容:hello shell world!
myfile="cat test.txt"
(1)echo $myfile  #result:cat test.txt
(2)eval echo $myfile  #result:hello shell world!
从(2)可以知道第一次扫描进行了变量替换,第二次扫描执行了该字符串中所包含的命令
#获得最后一个参数
echo "Last argument is $(eval echo \$$#)"
echo "Last argument is $(eval echo $#)"

2> /dev/null || true

Regarding || true - If command return non 0 (zero) exit status (that usually indicating some type of error/failure) then true forcible set exit status code to 0 (zero) indicating success

stdin(标准输入,文件描述符0),stdout(标准输出,文件描述符1)和stderr(标准错误,文件描述符2)

2> /dev/null将错误信息丢弃

2>&1 将标准错误重定向到标准输出的地址(&1)

&>/dev/null 所有IO重定向(&>中的&可以代表任意,0,1,2,3……)

https://superuser.com/questions/1179844/what-does-dev-null-21-true-mean-in-linux

&&与|| 和&

&放在启动参数后面表示设置此进程为后台进程,一般为了防止信息输出干扰屏幕可以ping 127.0.0.1 &>/dev/null &

command1 && command2,如果command1执行成功,那么执行command2

command1 || command2,如果command1执行失败,那么执行command2

运算符

  • 算术运算符
  • 关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:

  • 布尔运算符
    运算符 说明 举例
    ! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
  • o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ]返回 true。
  • a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ]返回 false。
    • 逻辑运算符
      运算符 说明 举例
      && 逻辑的 AND [[ $a -lt 100&&$b -gt 100 ]] 返回 false
      || 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true
    • 字符串运算符
      运算符 说明 举例
      = 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
      != 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
  • z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
  • n 检测字符串长度是否为0,不为0返回 true。 [ -n $a ] 返回 true。
    str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。
    • 文件测试运算符
      操作符 说明 举例
  • b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ]返回 false。
  • c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
  • d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ]返回 false。
  • f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
  • g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ]返回 false。
  • k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ]返回 false。
  • p file 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
  • u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ]返回 false。
  • r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
  • w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
  • x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
  • s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
  • e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ]返回 true。
    Shell 基本运算符

dirname截取给定路径目录部分

1.示例1

1
2
3
#!/bin/sh  
# 跳转到脚本所在目录
cd $(dirname "$0") || exit 1

2.示例2

1
2
>> dirname /usr/bin/sort 
/usr/bin

#跳转到脚本所在目录,并输出当前目录地址到SCRIPTS_DIR变量,

1
SCRIPTS_DIR="$(cd $(dirname "$0"); pwd -P)"
  • pwd
    • -P代表avoid all symlinks(避免所有符号链接)
      1
      2
      3
      4
      5
      6
      7
      [root@server /home/q/mysql/multi/3308/private]# ln -s /tmp test
      [root@server /home/q/mysql/multi/3308/private]# ll
      lrwxrwxrwx 1 root root 4 Mar 21 23:50 test -> /tmp
      [root@server /home/q/mysql/multi/3308/private/test]# pwd
      /home/q/mysql/multi/3308/private/test
      [root@server /home/q/mysql/multi/3308/private/test]# pwd -P
      /tmp

pv

通过管道监视数据的进度

1
2
-f, --force
Force output. Normally, pv will not output any visual display if standard error is not a terminal. This option forces it to do so.

点命令

A:. $(dirname $0)/wsrep_sst_common从当前目录读取wsrep_sst_common文件并在当前进程执行,类似import语句,相当于source命令
B:可以使用点命令/source命在不修改文件权限的情况下,直接执行shell脚本. test.sh/source test.sh,它与直接执行shell的区别在于这样执行的shell是在本地shell中执行,而./test.sh 是在子shell中执行。
C:常用在多个shell文件公用变量时,可以将变量抽到一个文件中,在使用时source进去
15.declare用于声明 shell 变量
-a Each name is an indexed array variable (see Arrays above).

冒号命令

没有效果; 该命令除了扩展参数和执行任何指定的重定向之外什么都不做。 返回零退出代码

  • 脚本注释、占位符

    • 占位符啥也不做,只起到占位符的作用。比如在编写脚本的过程中,某些语法结构需要多个部分组成,但开始阶段并没有想好或完成相应的代码,这时就可以用:来做占位符,否则执行时就会报错。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      #!/bin/sh  

      : this is single line comment

      : 'this is a multiline comment,
      second line
      end of comments'

      if [ "1" == "1" ]; then
      echo "yes"
      else
      :
      fi
  • 执行任何指定的重定向

    1
    2
    : > file等价于>file
    : ${VAR:=DEFAULT} 等价于 VAR=${VAR:=DEFAULT} 相当于将VAR重定向为DEFAULT值

shell中的冒号“:”–个人整理总结版-注意与makfle中:的区别

shell特殊字符和引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ 变量表达式
& 后台作业
* 字符串通配符
( 启动子 shell
) 停止子 shell
\ 应用下一个字符
| 管道
[ 开始字符集通配符号
] 结束字符集通配符号
{ 开始命令块
} 结束命令块
; shell 命令分隔符
' 强引用
" 弱引用
< 输入重定向
输出重定向
/ 路径名目录分割符
? 单个任意字符
! 管道行逻辑 NOT

bash 数组学习笔记

bash 数组学习笔记

shell 编程:冒号 后面跟 等号,加号,减号,问号的意义

  • :=句法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    只有当变量username已被定义,而且是一个空值时,变量username才会被设置为变量LOGNAME的值
    [root@server ~]# username=""
    [root@server ~]# echo "${username:=$LOGNAME}"
    root
    [root@server ~]# username="ss"
    [root@server ~]# echo "${username:=$LOGNAME}"
    ss
    [root@server ~]# echo "${name:=$LOGNAME}"
    root
    [root@server ~]# echo $name
    root
    [root@server ~]#
  • =句法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    只有当变量name未被定义过,变量name才会被设置为变量LOGNAME的值,当username被定义过,则会输出空行
    [root@server ~]# username=""
    [root@server ~]# echo "${username=$LOGNAME}"

    [root@server ~]# username="ss"
    [root@server ~]# echo "${username=$LOGNAME}"
    ss
    [root@server ~]# echo "${name=$LOGNAME}"
    root
    [root@server ~]# echo $name
    root

:=句法要比=句法限制更松些,:=句法允许变量为空,只有:=句法=句法赋值
当脚本或者函数需要依赖某些定义变量时,就要使用这种语法。它主要应用于登陆。如果一个特定环境变量还没有被定义,就可以给它赋予脚本所需要的值


  • :-句法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    只有当变量username为空时,在`“${}”`句法中username被替换为`$LOGNAME`
    [root@server ~]# username=""
    [root@server ~]# echo "${username:-$LOGNAME}"
    root
    [root@server ~]# echo $username

    [root@server ~]# username="ss"
    [root@server ~]# echo "${username:-$LOGNAME}"
    ss
    [root@server ~]# echo "${usernameee:-$LOGNAME}"
    root
  • -句法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    只有当变量username为空时,在`“${}”`句法中username不会被替换
    [root@server ~]# username=""
    [root@server ~]# echo "${username-$LOGNAME}"

    [root@server ~]# username="ss"
    [root@server ~]# echo "${username-$LOGNAME}"
    ss
    [root@server ~]# echo "${usernamesss-$LOGNAME}"
    root

:-句法要比-句法限制更松些,:-句法允许变量为空,但是与:=句法要比`=句法区别是都不会给变量赋值
当脚本评价或检查系统环境的时,:-句法和-句法都可以使用。这两种检查基本上是相反的,它们用默认值替换变量,或者甚至于不依赖username变量是否已经被定义。如果脚本中急需要一组被定义的变量,也需要一些不该被定义的变量,那么在脚本执行任务之前组合这两种句法,肯定可以实现正确的设置。


  • :?句法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    当变量未被定义或者定义了一个空值时,那么在echo命令中就会使用LOGNAME的值,并且脚本退出执行
    [root@server ~]# username="sss"
    [root@server ~]# echo "${username:?$LOGNAME}"
    sss
    [root@server ~]# username=""
    [root@server ~]# echo "${username:?$LOGNAME}"
    bash: username: root
    [root@server ~]# echo "${useme:?$LOGNAME}"
    bash: useme: root
  • ?句法

    1
    2
    3
    4
    5
    当变量未被定义时那么在echo命令中就会使用LOGNAME的值,并且脚本退出执行
    [root@server ~]# username=""
    [root@server ~]# echo "${username?$LOGNAME}"
    [root@server ~]# echo "${userna?$LOGNAME}"
    bash: userna: root

:?句法?句法区别在于,?句法允许变量为空”


  • :+句法只有当变量已被定义而且是非空的时候,“${}”表达式才执行替换

    1
    2
    3
    4
    5
    6
    7
    [root@server ~]# username="ss"
    [root@server ~]# echo "${username:+$LOGNAME}"
    root
    [root@server ~]# username=""
    [root@server ~]# echo "${username:+$LOGNAME}"

    [root@server ~]# echo "${usernam+$LOGNAME}"
  • +句法,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    只要变量被定义了即使为空,“${}”表达式也执行替换
    [root@server ~]# echo "${use+$LOGNAME}"

    [root@server ~]# username="ss"
    [root@server ~]# echo "${username+$LOGNAME}"
    root
    [root@server ~]# username=""
    [root@server ~]# echo "${username+$LOGNAME}"
    root

:+句法要比+句法要求苛刻些,+句法允许变量为空


区别:

  • :?句法?句法与其他句法区别
    错误之后退出,其他不会
  • :=句法=句法与其他句法区别
    只有:=句法与`=句法会将结果赋值给变量,其他都不会
  • :++:--区别
    最主要的区别是:++示例检查的是一个已定义的变量,而不是未定义的变量
  • :?句法?句法:=句法=句法区别
    主要区别是会退出,=会赋值.
    linux bash shell之变量替换

Linux shell 中$() 反引号,${},$[] $(()),[ ] (( )) [[ ]]作用与区别

  • $()和 反引号
    用来做命令替换用

    • 各自的优缺点
      a.反引号 基本上可用在全部的 unix shell 中使用,若写成 shell script ,其移植性比较高。但反单引号容易打错或看错。
      b.$()并不是所有shell都支持。
      1
      2
      3
      4
      5
      6
      [root@server ~]# version=$(uname -r)
      [root@server ~]# echo $version
      2.6.32-358.23.2.el6.x86_64
      [root@server ~]# version=`uname -r`
      [root@server ~]# echo $version
      2.6.32-358.23.2.el6.x86_64
  • ${ }
    ${ }用于变量替换。一般情况下,$var${var} 并没有啥不一样。但是用 ${ } 会比较精确的界定变量名称的范围

    1
    2
    3
    4
    5
    [root@server ~]# A=B
    [root@server ~]# echo $AB

    [root@server ~]# echo ${A}B
    BB
1
2
3
4
5
6
7
8
9
10
11
12
[root@server ~]#  A='abcde'
[root@server ~]# echo ${A#cd}
abcde
[root@server ~]# echo ${A#ab}
cde
[root@server ~]# echo ${A%de}
abc
[root@server ~]# A='abcabcde'
[root@server ~]# echo ${A/abc/df}
dfabcde
[root@server ~]# echo ${A//abc/df}
dfdfde
  • $[] $(())
    它们是一样的,都是进行数学运算的。支持+ - * / %:分别为 “加、减、乘、除、取模”。但是注意,bash只能作整数运算,对于浮点数是当作字符串处理的
    1
    2
    3
    4
    5
    6
    7
    [root@server ~]# a=5; b=7; c=2
    [root@server ~]# echo $(( a+b*c ))
    19
    [root@server ~]# echo $(( (a+b)/c ))
    6
    [root@server ~]# echo $(( (a*b)%c))
    1

$(( )) 中的变量名称,可于其前面加$符号来替换,也可以不用
$(( $a + $b * $c)) 也可得到 19 的结果

  • [ ]:
    即为test命令的另一种形式

1.你必须在左括号的右侧和右括号的左侧各加一个空格,否则会报错
2.test命令使用标准的数学比较符号来表示字符串的比较,而用文本符号来表示数值的比较。很多人会记反了。使用反了,shell可能得不到正确的结果。
3.大于符号或小于符号必须要转义,否则会被理解成重定向。

  • (( ))及[[ ]]:
    它们分别是[ ]的针对数学比较表达式和字符串表达式的加强版
    • [[ ]]中增加了另一个特性:模式匹配
    • 其中(( )),不需要再将表达式里面的大小于符号转义,除了可以使用标准的数学运算符外,还增加了以下符号:

Linux shell 中$() ,${},$[] $(()),[ ] (( )) [[ ]]作用与区别

获取本机IP地址

1
2
ipaddr=`/sbin/ifconfig | grep 'inet addr:' | grep -v '127.0.0.1'|cut -d : -f2 | awk '{print $1}'`
echo $ipaddr

umark 022

预设权限
目录的预设权限是:

1
0777 drwxrwxrwx

文件的预设权限是:

1
0666 -rw-rw-rw-

其中r的十进制值是4,w的十进制值是2,x的十进制值是1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
umask=022中"022"是八进制的写法,如果换成二进制是000010010
在unix中文件权限是三类用户,三种权限。三类用户分别是文件所有者user(u),文件所有者所在主群组group(g)、其它用户others(o),三种权限分别是起读read(r)、写write(w)、执行execute(x)。
如果一个文件的权限如下:所有者有读写的权限,群组有读和执行权限、其它用户有读权限,可以写成:
rw-r-xr--
其中前三位指明了所有者的权限、中间三位指明了组权限、最后三位指明了其它用户的权限。我们用ls -l可以看到文件权限详情,列出来的是10位,最前一位如果是d表示是子目录。
说回来,如果把这上面9位字母换成二进制数则是:
110101100
如果换成八进制是多少?
因此文件权限可以用9位二进制数表示。umask在英文中是屏蔽的意思,那么
umask=022
指屏蔽文件的022权限,到底屏蔽了什么?将这个八进制数用二进制表示
000010010
换算成字母是
----w--w-
#指取消组的写权限、取消其它用户的写权限。
屏蔽这些权限后,剩下什么权限呢?用字母表示是:
#rwxr-xr-x
用二进制数表示是:
111101101
你可以对比一下
000010010
可以知道屏蔽前后的换算关系。

umask决定目录和文件被创建时得到的初始权限
umask = 022时
新建的目录 权限是755
文件的权限是 644

readonly WSREP_SST_OPT_BYPASS

readonly命令用于定义只读shell变量和shell函数。readonly命令的选项-p可以输出显示系统中所有定义的只读变量。
http://man.linuxde.net/readonly