shell 基础
1. 变量
a=123
b=jkl
c=$(ls)
- 使用变量
echo $a
let a=a+789
- shell 没有变量类型之说,只有在比较时有字符串和整数之说;
1.a 预定义变量/特殊变量
$# 表示位置参数的数量
$* 表示所有位置参数的内容
$0 这个程序的执行名字
$n 这个程序的第n个变量 n=1…9
2. 比较
- 整数
-eq
-ne
-ge
-gt
-lt
-le
- 字符串
-z 空串
-n 非空串
=
!=
- 0为真 1为假;
3. 命令替换
- 反引号
echo "`ls -a`"
- $()
4. 引用
- 单引号
- 双引号
- 反斜杠\
5. 执行
Date
d=$(Date)
以上两条都执行了date指令 ,不过后一条把输出返回了
lock=$(./pcieserver -I 130 -d 1)
6. 子进程 命令分组
- 多个命令可以用;分割,依次执行
pwd; ls;cd /etc;pwd
- 使用括号会生成子shell来执行对应命令,进程列表 又称命令分组
(pwd;ls;cd /etc;pwd;echo $BASH_SUBSHELL)
- {cmd1;cmd2;}
$BASH_SUBSHELL 大于0 则说明启动子进程;
7.将命令置入后台运行 &
sleep 3000 &
8. 处理用户输入
- 用户输入参数以空格分割; 如果参数中含有空格则使用引号包起来
- ${11} 大于10个的参数
- $0 脚本名
- $# 参数个数
- getopt getopts 处理参数
9. 函数
1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值
函数返回值在调用该函数后通过 $? 来获得。
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
function 的名字可以当做命令用, 使用命令替换
echo "`ls -a`"
function name(
cmd
)
#或者
name(){
cmd
}
$# 判断参数个数
read -p "enter a value:" value
echo "the value is : $value"
#!/bin/bash
#数组num
num=(1 2 3 4 5 6)
array() {
local value=1 #加local表示value是局部参数,不影响函数外的同名参数
for i in $@ #所有的参数{1..6}
do
let value*=$i
done
echo "$value"
}
array ${num[@]}
//测试
[root@mysql-master /soft/scripts]# sh function2.sh
720
####传入数组参数,输出数组参数####
#!/bin/bash
num=(1 2 3)
num2=(3 4 5)
array() {
local newarr=($@)
for((i=0;i<$#;i++)) #或者写成for i in $@;do;outarr[j++]=$[$i*3];done
do
outarr[$i]=$(( ${newarr[$i]} * 3 ))
done
echo "${outarr[@]}"
}
reslut=`array ${num[*]}`
echo $reslut
reslut2=`array ${num2[*]}`
echo $reslut2
//测试
[root@mysql-master /soft/scripts]# sh function3.sh
3 6 9
9 12 15
10 source的替代
. 是正规用法 作用相当于source
. test.sh
11 && || 条件判断
&& 和 ||
&&:用来执行条件成立后执行的命令
||:用来执行条件不成立后的执行命令
[root@localhost mnt]# id toto # 用户toto不存在无法查看
id: toto: no such user
[root@localhost mnt]# id toto &> /dev/null && echo yes || echo no # 判断用户是否存在
no # 由于用户不存在 条件不成立 所以输出no
[root@localhost mnt]# useradd toto # 创建用户之后 用户存在
[root@localhost mnt]# id toto &> /dev/null && echo yes || echo no # 条件成立 输出yes
yes
docker rm --force cx166 && docker ps -a | grep cx166 && echo failure || echo success
12 Shell重定向&>file、2>&1、1>&2的区别
shell上:
0表示标准输入
1表示标准输出
2表示标准错误输出
默认为标准输出重定向,与 1> 相同
2>&1 意思是把 标准错误输出 重定向到 标准输出.
&>file 意思是把 标准输出 和 标准错误输出 都重定向到文件file中
用例子说话:
- grep da * 1>&2
- rm -f $(find / -name core) &> /dev/null
上面两例中的 & 如何理解,&不是放到后台执行吗?
>1表示 输出到名字为1的文件;而 >&1 中&1表示文件操作符
牛解:
1.&>file或n>&m均是一个独立的重定向符号,不要分开来理解。
2.明确文件和文件描述符的区别。
3.&>file表示重定向标准输出和错误到文件
例如:
rm -f $(find / -name core) &> /dev/null,/dev/null是一个文件,这个文件比较特殊,所有传给它的东西它都丢弃掉。
4.n>&m表示使文件描述符n成为输出文件描述符m的副本。这样做的好处是,有的时候你查找文件的时候很容易产生无用的信息,如:2> /dev/null的作用就是不显示标准错误输出;另外当你运行某些命令的时候,出错信息也许很重要,便于你检查是哪出了毛病,如:2>&1
例如:
注意,为了方便理解,必须设置一个环境使得执行grep da *命令会有正常输出和错误输出,然后分别使用下面的命令生成三个文件:
grep da * > greplog1
grep da * > greplog2 1>&2
grep da * > greplog3 2>&1 //grep da * 2> greplog4 1>&2 结果一样
#查看greplog1会发现里面只有正常输出内容
#查看greplog2会发现里面什么都没有
#查看greplog3会发现里面既有正常输出内容又有错误输出内容
我们使用>或者>>对输出进行重定向。符号的左边表示文件描述符,如果没有的话表示1,也就是标准输出,符号的右边可以是一个文件,也可以是一个输出设备。当使用>时,会判断右边的文件存不存在,如果存在的话就先删除,然后创建一个新的文件,不存在的话则直接创建。但是当使用>>进行追加时,则不会删除原来已经存在的文件。
- 2>&1是将stderr合并到stdout,以及&>是stderr与stdout合并输出的意思.
- 放在>后面的&,表示重定向的目标不是一个文件,而是一个文件描述符;
- 换言之 2>1 代表将stderr重定向到当前路径下文件名为1的regular file中,而2>&1代表将stderr重定向到文件描述符为1的文件(即/dev/stdout)中;
- 而&>file是一种特殊的用法,也可以写成>&file,二者的意思完全相同,都等价于>file 2>&1
- linux在执行shell命令之前,就会确定好所有的输入输出位置,并且从左到右依次执行重定向的命令,所以>/dev/null 2>&1的作用就是让标准输出重定向到/dev/null中(丢弃标准输出),然后错误输出由于重用了标准输出的描述符,所以错误输出也被定向到了/dev/null中,错误输出同样也被丢弃了。执行了这条命令之后,该条shell命令将不会输出任何信息到控制台,也不会有任何信息输出到文件中。
In the following descriptions, if the file descriptor number is omitted, and the first character of the redirection operator is ‘<’, the redirection refers to the standard input (file descriptor 0). If the first character of the redirection operator is ‘>’, the redirection refers to the standard output (file descriptor 1).
- &> 等如 2>&1 , > 等如 1> ,那是缩写
例子:( 重点 !!! 按照这个思路去理解)
2>&1 >/dev/null 的过程是这样的:
没重定向的时候,是 1->stdout, 2->stderr
2>&1,就是让2指向1指向的文件,从而变成 1,2->stdout,关闭stderr
>/dev/null,就是让1指向/dev/null,从而变成 1->/dev/null, 2->stdout
最终结果就是程序的标准输出输出到/dev/null,标准错误输出输出到标准输出。
13 文件描述符
1 => stdout # /dev/stdout
2 => stderr
0 => stdin