1、shell判断符[ ]
|
操作符 |
说明 | 举例 |
|---|---|---|
| -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 |
2、Shell脚本中eq,ne,le,ge,lt,gt意义
- -eq:等于
- -ne:不等于
- -le:小于等于
- -ge:大于等于
- -lt:小于
- -gt:大于
3、Shell脚本中的set指令,比如set -x 和 set -e,set -u
set -x:
用于脚本调试,在liunx脚本中可用set -x就可有详细的日志输出.免的老是要echo了
set -e:
每个脚本都应该在文件开头加上set -e,这句语句告诉bash如果任何语句的执行结果不是true则应该退出。这样的好处是防止错误像滚雪球般变大导致一个致命的错
误,而这些错误本应该在之前就被处理掉。如果要增加可读性,可以使用set -o errexit,它的作用与set -e相同。
set -u
设置该选项后,当脚本在执行过程中尝试使用未定义过的变量时,报错并退出运行整个脚本(默认会把该变量的值当作空来处理)
set指令能设置所使用shell的执行方式,可依照不同的需求来做设置。
-a 标示已修改的变量,以供输出至环境变量。 -b 使被中止的后台程序立刻回报执行状态。 -C 转向所产生的文件无法覆盖已存在的文件。 -d Shell预设会用杂凑表记忆使用过的指令,以加速指令的执行。使用-d参数可取消。 -e 若指令传回值不等于0,则立即退出shell。 -f 取消使用通配符。 -h 自动记录函数的所在位置。 -H Shell 可利用"!"加<指令编号>的方式来执行history中记录的指令。 -k 指令所给的参数都会被视为此指令的环境变量。 -l 记录for循环的变量名称。 -m 使用监视模式。 -n 只读取指令,而不实际执行。 -p 启动优先顺序模式。 -P 启动-P参数后,执行指令时,会以实际的文件或目录来取代符号连接。 -t 执行完随后的指令,即退出shell。 -u 当执行时使用到未定义过的变量,则显示错误信息。 -v 显示shell所读取的输入值。 -x 执行指令后,会先显示该指令及所下的参数。 +<参数> 取消某个set曾启动的参数
4、bash 内置命令exec
exec表示执行一个命令,但是不会启动子shell,而只是替代当前shell并且所有环境都会被清空。
注:source 和 . 不启用新的shell,在当前shell中执行,设定的局部变量在执行完命令后仍然有效;
bash或sh 或shell script执行时,另起一个子shell,其继承父shell的环境变量,其子shelll的变量执行完后不影响父shell,注意三类的区别
exec是用被执行的命令行替换掉当前的shell进程,且exec命令后的其他命令将不再执行。例如在当前shell中执行 exec ls 表示执行ls这条命令来替换当前的shell 即为执行完后会退出当前shell。
为了避免这个结果的影响,一般将exec命令放到一个shell脚本中,用主脚本调用这个脚本,调用处可以用bash xx.sh(xx.sh为存放exec命令的脚本)。这样会为xx.sh
建立一个子shell去执行,当执行exec后该子脚本进程就被替换成相应的exec的命令
其中有一个例外:当exec命令对文件描述符操作的时候,就不会替换shell,而是操作完成后还会继续执行后面的命令
exec 3<&0 表示将操作符3也指向标准输入
exec ls 在shell中执行ls,ls结束后不返回原来的shell中了 exec <file 将file中的内容作为exec的标准输入 exec >file 将file中的内容作为标准写出 exec 3<file 将file读入到fd3中 sort <&3 fd3中读入的内容被分类 exec 4>file 将写入fd4中的内容写入file中 ls >&4 Ls将不会有显示,直接写入fd4中了,即上面的file中 exec 5<&4 创建fd4的拷贝fd5 exec 3<&- 关闭fd3
5、Linux中万物皆文件,文件描述符也是文件。默认:
fd=0的标准输入是/dev/stdin文件
fd=1的标准输出是/dev/stdout文件
fd=2的标准错误是/dev/stderr文件
2>&1:将标准错误重定向到标准输出(常用)
特殊重定向:
&>file:这是特殊的重定向方式,表示将标准错误和标准输出都重定向到file文件中,等价于>file 2>&1
&>>file:这是特殊的重定向方式,表示将标准错误和标准输出都追加到file文件中,等价于>>file 2>&1
6、快速清空文本
: > access.log > access.log true > access.log cat /dev/null > access.log echo -n "" > access.log echo > access.log truncate -s 0 access.log
7、dd运用
dd快速生成大文件
$ dd if=/dev/zero of=file.txt bs=1M count=1024
擦除硬盘数据
$ dd if=/dev/urandom of=/dev/sda
制作系统盘(sdb可以 U 盘,也可以是普通硬盘)
$ dd if=ubuntu-server-amd64.iso of=/dev/sdb
dd将小写字母全部转换成大写
$ dd if=testfile_2 of=testfile_1 conv=ucase
8、查看某个进程的运行时间(etime运行时间、rss内存)
ps -p 1858 -o etimes,etime ELAPSED ELAPSED 22382 06:13:02
9、计算程序运行时间(time命令)
$ time ./test real 0m1.003s user 0m0.000s sys 0m0.000s
-
real:表示的钟表时间,也就是从程序执行到结束花费的时间; -
user:表示运行期间,cpu 在用户空间所消耗的时间; -
sys:表示运行期间,cpu 在内核空间所消耗的时间;
由于 user 和 sys 只统计 cpu 消耗的时间,程序运行期间会调用 sleep 发生阻塞,也可能会等待网络或磁盘 IO,都会消耗大量时间。因此对于类似情况,real 的值就会大于其它两项之和。另外,也会遇到 real 远远小于 user + sys 的场景,如果程序在多个 cpu 上并行,那么 user 和 sys 统计时间是多个 cpu 时间,实际消耗时间 real 很可能就比其它两个之和要小了。
10、执行历史命令(实用)
-
!!:重复执行上条命令; -
!N:重复执行 history 历史中第 N 条命令,N 可以通过 history 查看; -
!pw:重复执行最近一次,以pw开头的历史命令,这个非常有用,小编使用非常高频; -
!$:表示最近一次命令的最后一个参数;
$ vim /root/sniffer/src/main.c $ mv !$ !$.bak # 相当于 $ mv /root/sniffer/src/main.c /root/sniffer/src/main.c.bak11、Vim 保存一个没有权限的已编辑文件
在保存文件前更改文件权限。
命令是:
:w !sudo tee %
这个命令将会要你输入密码,就像在命令行中使用 sudo vim一样。
11、在命令 history 中显示时间戳
临时设置:
export HISTTIMEFORMAT="%F %T `whoami` "
永久设置:
echo 'export HISTTIMEFORMAT="%F %T `whoami` "' >> /etc/profile
12、间接引用变量
VAR1="2323232"
VAR2="VAR1"
变量VAR1和变量VAR2,这个VAR2的值是VAR1的名字,那么我们现在想通过VAR2来获取VAR1的值
$ echo ${!VAR2}
2323232
$ eval echo \$$VAR2
2323232
eval会对后面的cmdLine进行两遍扫描,如果在第一遍扫面后cmdLine是一个普通命令,则执行此命令;如果cmdLine中含有变量的间接引用
利用eval实现将结果分别赋值给变量
#cat tt.sh
for i in $(echo "4 5 6"); do
eval a$i=$i
done
echo $a4 $a5 $a6
#cat tt1.sh
num=0
for i in $(eval echo $*);do #eval将{1,2}分解为1 2
let num+=1
eval node${num}="$i"
done
echo $node1 $node2 $node3
# bash a.sh 192.168.1.1{1,2}
192.168.1.11 192.168.1.12
13、shell脚本中“if”语法如何嵌套
if [ 条件 ] then 命令1 命令2 ….. else if [ 条件 ] then 命令1 命令2 …. else 命令1 命令2 ….. fi fi
14、数字运算
expr 1 + 2909 2910 test=$[16 + 4] $ echo $test 20 $let 5+2 7 ###小数计算 echo "scale=2; 2.03+2.04" | bc
注:expr做数字的四则运算
-
请用空格隔开每个项。
-
请将反斜杠(\)放在 Shell 特殊字符前面。
-
请对包含空格和其他特殊字符的字符串用引号括起来。
15、shell高级变量
${string/substring/replacement} 仅仅替换第一次匹配
${string//substring/replacement} 替换所有的匹配
范例:
zjz="123,124,zhz,zjksd" #3设定字符串
str=${zjz//,/ } ##替换字符串中的逗号为空格
echo $str ##输出效果
123 124 zhz zjksd
脚本运用:字符串的替换
#cat tt.sh
#!/bin/bash
str="1,2,3,4";
str=${str//,/ };
arr=($str);
#遍历数组
for each in ${arr[*]}
do
echo $each
done
16、shell特性之快捷键
ctrl + w ## 从光标处删至该单词结束 ctrl + y ## 撤销删除 ctrl + k ## 从光标处删除至行尾 ctrl + u ## 从光标处删除至行首
17、进制转换(2#表示:将1010二进制数转换为10进制数)
echo $(( 2#1010 ))
18、echo ${PATH#*:} # 参数替换
${file#*/}: 拿掉第一条/及其左边的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}: 拿掉最后一条/及其左边的字符串:my.file.txt
${file#*.}: 拿掉第一个.及其左边的字符串:file.txt
${file##*.}: 拿掉最后一个.及其左边的字符串:txt
${file%/*}: 拿掉最后条/及其右边的字符串:/dir1/dir2/dir3
${file%%/*}: 拿掉第一条/及其右边的字符串:(空值)
${file%.*}: 拿掉最后一个.及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}: 拿掉第一个.及其右边的字符串:/dir1/dir2/dir3/my
记忆的方法为:
[list]#是去掉左边, ##最后一个
%是去掉右边, %%第一个
$ echo ${PATH}
/usr/local/share/miniconda3/bin/:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/op_admin/.local/bin:/home/op_admin/bin
echo ${PATH#*:}
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/op_admin/.local/bin:/home/op_admin/bin
$ echo ${PATH##*:}
/home/op_admin/bin
19、一行输入对个命令,使用 ; 隔开
echo hello; echo there; echo zjz
20、逗号链接了一系列的算术操作,虽然里边所有的内容都被运行了,但只有最后一项被返回
let "t2 = ((a = 9, 15 / 3))" #echo $t2 5 #echo $a 9
21、命令组()
在()中的命令列表,将作为一个子 shell 来运行,在()中的变量,由于是在子 shell 中,所以对于脚本剩下的部分是不可用的。
#(a=hello;echo $a) hello #echo $a 9
https://www.junmajinlong.com/shell/script_course/shell_tutorial/ 骏马金龙
https://www.cnblogs.com/f-ck-need-u/p/7427357.html shell测试命令test、[ ]、[[ ]]