引号
引号的必要性
变量和替换操作,在脚本中执行变量替换时,最容易犯的一个错误就是引号的错误
==双引号
双引号 使用双引号可以引用除字符$,`反引号,\反斜杠外的任意字符或者字符串
hzmct@U-64:/study/linuxtest/day03$ echo -e "hello world,$SHELL"
hello world,/bin/bash
==单引号
单引号 单引号与双引号类似,不同的是shell会忽略任何引用值。换句话说,如果屏蔽了其特殊含义,会将引号里的所有字符,包括引号都作为一个字符。
echo -e ' hello world, $SHELL '\n* wangbaoming '
结论:单引号让特殊字符失去意义。
hzmct@U-64:/study/linuxtest/day03$ echo -e "hello world,$SHELL "
hello world,/bin/bash
hzmct@U-64:/study/linuxtest/day03$ echo -e 'hello world,$SHELL'
hello world,$SHELL
==反引号
反引号 反引号用于设置系统命令的输出到变量。shell将反引号中的内容作为一个系统命令,并执行其内容
echo "hzmct `echo $PATH`"
hzmct /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/oracle/11.2/client64/bin
==反斜杠
反斜杠
如果一个字符有特殊含义,反斜杠防止shell误解其含义,即:屏蔽其特殊含义。
ECHO下属字符含有特殊含义:$ * + ^ ` ‘’ | ?
eg:echo * echo \*
hzmct@U-64:$ echo *hello*
*hello*
hzmct@U-64:$ echo *hello *
*hello 1.sh 1.txt 1weizhi.sh 2find.sh exec.sh grep.out readonline.sh read.sh testdir1.sh testdir.sh who.out
hzmct@U-64:$ echo *hello \*
*hello *
hzmct@U-64:$
表达式类型
按位运算符
~op1 反运算符
op1<<op2 左移运算符
op1>>op2 右移运算符
op1 & op2 与比较运算符
op1 ^ op2 异或运算符
op1 | op2 或运算符
eg: echo $[2<<4] echo $[2^4]
$[ ] 表示形式告诉shell对方括号中的表达式求值
eg: echo $[3+9]
逻辑运算符
&& 逻辑与运算
|| 逻辑或运算符 echo $[1||1]
赋值运算符
=,+=,-=,*=,/=,%=,&=,^=、|=,<<=,>>=
let count = $count + $change
let count += $change
let 执行算术运算并将结果赋给一个变量
hzmct@U-64:/study/linuxtest/day03$ var=10
hzmct@U-64:/study/linuxtest/day03$ let var+=10
hzmct@U-64:/study/linuxtest/day03$ echo $var
20
表达式替换
$[] 和 $(( )) 习惯使用$[],所有shell的求值都是用整数完成
$[]可以接受不同基数的数字
[base#n] n表示基数从2到36任意基数
[wbm@wmblinux64 myshell]$ echo $[10#8+191]
199
hzmct@U-64:$ echo $[2#1+10]
11
hzmct@U-64:$ echo $[2#2+10]
bash: 2#2: value too great for base (error token is "2#2")
hzmct@U-64:/study/linuxtest/day03$ echo $[2#0+10]
10
运算符的优先级(不确定的地方,多加括号)
方法一:使用let命令
hzmct@U-64:$ var=10
hzmct@U-64:$ let var+=10
hzmct@U-64:$ echo $var
20
方法2:使用双圆括号
hzmct@U-64:~$ v1=$(( 4*5))
hzmct@U-64:~$ echo $v1
20
shell输入与输出
echo
终端用户登录linux服务器,为每一个终端用户启动一个shell程序。
echo命令可以显示文本行或变量,或者把字符串输入到文件。
echo [option] string
-e 解析转义字符
-n 回车不换行,linux系统默认回车换行 eg: echo –n “abc” ; echo “abc”
-转义字符(\c(回车不换行) \f(禁止)\t(回车换行) \n(回车换行))
例子
1 #!/bin/bash
2 #echo
3 echo -e "hello world...\n\n\n"
4 echo "ok"
5 echo "空,后面没有任何东西,将要有一个回车换行"
6 echo
7 echo -n "asdf"
8 echo "echo -e 解析转义字符 -n 回车不换行">mylog.txt
read
read语句可以从键盘或文件的某一行文本中读入信息,并将其制复制给一个变量。
read var1 var2 …. 若只指定了一个变量,那么read将会把所有的输入赋给该变量,直至遇上第一个文件结束符或者回车。如果给了多个变量,他们按照顺序分别赋予不同的变量。shell将用空格作为变量之间的分隔符。
例子
1 #!/bin/bash
2 #注意回车不换行的用法
3 echo -n "First Name:"
4 read firstname
5 echo -n "Last Name:"
6 read lastname lastname2
7 echo -e "FirstName:${firstname}\n"
8 echo -e "LastName:${lastname}\n"
9 echo -e "LastName2:${lastname2}\n"
hzmct@U-64:/study/linuxtest/day03$ ./4read.sh
First Name:aa
Last Name:vv bb cc
FirstName:aa
LastName:vv
LastName22:bb cc
hzmct@U-64:/study/linuxtest/day03$
cat
cat 是一个简单而通用的命令,可用它显示文件内容、创建文件、还可以用它来显示控制字符。
cat [options] filename1 … filename2 ….
-v 显示控制字符
使用cat命令时注意,它不会在文件分页处停下来;它会一下显示完整个文件。如果希望每次显示一页,可以使用more命令 或把cat命令的输出通过管道传递到另外一个具有分页功能的命令(more、less)中。
man cat
//显示控制字符
hzmct@U-64:/study/linuxtest/day03$ cat -v 3.txt
pwd
echo -e M-hM-'M-#M-fM-^^M-^PM-hM-=M-,M-dM-9M-^IM-eM--M-^WM-gM-,M-& -n M-eM-^[M-^^M-hM-=M-&M-dM-8M-^MM-fM-^MM-"M-hM-!M-^L
//连续查看2 个文件
hzmct@U-64:/study/linuxtest/day03$ cat 1.txt mylog.txt ;
pwd
echo -e 解析转义字符 -n 回车不换行
//将1.txt mylog.txt输入到3.txt,若3.txt不存在则创建
hzmct@U-64:/study/linuxtest/day03$ cat 1.txt mylog.txt >3.txt
管道
可以通过管道把一个命令的输出传递给另外一个命令做输入。管道用竖线表示
格式:命令1 | 命令2
cat myfile | more
ls –l | grep “myfile”
df –k | awk ‘{print $1}’ | grep –v “Filesystem文件系统”
df –k 看磁盘空间 查找第一列 去除filesystem字符排除掉
tee将输出同时发送到显示器和文件
tee 命令把结果输出到标准输出,另一个副本输出到相应文件
tee –a file -a: 表示追加 不加-a表示覆盖
该命令一般用于管道之后 (一般看到输出,并存文件)
eg who | tee –a who.out
df –k | awk ‘{print $1}’ | grep –v “Filesystem” | tee partation.txt
//例子
hzmct@U-64:/study/linuxtest/day03$ cat 3.txt |tee -a tee.log
pwd
echo -e 解析转义字符 -n 回车不换行
hzmct@U-64:/study/linuxtest/day03$ cat tee.log
pwd
echo -e 解析转义字符 -n 回车不换行
标准输入、标准输出和错误
当我们在shell中执行命令的时候,每个进程都和三个打开的文件相联系,并使用文件描符来引用 这些文件。由于文件描述符不容易记忆, shell同时也给出了相应的文件名。
下面就是这些文件描述符及它们通常所对应的文件名:
输入文件—标准输入 0
输出文件—标准输出 1
错误输出文件—标准错误 2
系统中实际上有12个文件描述符,但是正如我们在上表中所看到的,0、1、2是标准输入、出和错误。可以任意使用文件描述符3到9。
文件重定向
文件重定向:改变程序运行的输入来源和输出地点
==重定向标准输出
$ cat 1.txt|sort 1>sort.out
$ cat 1.txt|sort>sort.out 这两个命令相同,不写默认为1
$ pwd>>1.txt
//创建长度为0的空文件
$ >1.txt
==重定向标准输入
eg1:
sort<file 将file的内容输入到sort进行排序,排序后的结果sort命令输出
hzmct@U-64:/study/linuxtest/day03$ cat 1.txt
/study/linuxtest/day03
11\n22\n
11
22
hzmct@U-64:/study/linuxtest/day03$ sort<1.txt>name.txt
hzmct@U-64:/study/linuxtest/day03$ cat name.txt
11
11\n22\n
22
/study/linuxtest/day03
==重定向标准错误
//grep命令在name.txt中搜索11字符串,若出错,则将错误信息输入到/dev/null中。下面例子没有错误信息,正确的信息输出到屏幕
$ grep "11" name.txt 2>/dev/null
11
11\n22\n
~结合使用标准输出和标准错误
//正确信息输入到right.txt中 错误信息输入到err.txt中
hzmct@U-64:/study/linuxtest/day03$ cd kk 1>right.txt 2>err.txt
hzmct@U-64:/study/linuxtest/day03$ cat err.txt
-bash: cd: kk: No such file or directory
hzmct@U-64:/study/linuxtest/day03$
~合并标准输出和标准错误
//将正确的信息和错误的信息都定向到同一个文件中
$ grep "hello" hello.txt>grep.out 2>&1
$ cat grep.out
grep: hello.txt: No such file or directory
exec和文件描述符在一起 (重点)
1、 exec命令可以用来代替当前shell;换句话说,并没有启动子shell,使用
这一命令时,任何现有环境都将被清除,并重新启动一个shell。
exec command command通常是一个shell脚本。
Eg:测试执行完该命令后,需要重新登录shell,然后export声明的变量都失效了。exec ./hello.sh
//例子 执行完命令后,却退出了。。。。
hzmct@U-64:/study/linuxtest/day03$ exec ls
1.sh 1weizhi.sh 3echo.sh err.txt grep.out right.txt tee.log testdir.sh
1.txt 2find.sh 4read.sh exec.sh name.txt sort.out testdir1.sh
Connection closed by foreign host.
Disconnected from remote host(u1) at 10:00:29.
Type `help' to learn how to use Xshell prompt.
[c:\~]$
Reconnecting in 30 seconds. Press any key to exit local shell.
......
2、对文件描述符进行操作时,也只有这么使用,它不会覆盖你的当前的shell
//例子
#!/bin/bash
#把0号文件描述符的东西赋值给3号文件描述符 把name.txt的东西
#赋给0号文件描述符,即name.txt作为标准输入了
exec 3<&0 0<name.txt
read line1
read line2
#使用完要还原,将3号文件描述符赋给0号文件描述符
exec 0<&3
echo $line1
echo $line2
//查看name.txt的内容
hzmct@U-64:/study/linuxtest/day03$ cat name.txt
11
22
33
hzmct@U-64:/study/linuxtest/day03$ ./5exec.sh
11
22