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 在内核空间所消耗的时间;

由于 usersys 只统计 cpu 消耗的时间,程序运行期间会调用 sleep 发生阻塞,也可能会等待网络或磁盘 IO,都会消耗大量时间。因此对于类似情况,real 的值就会大于其它两项之和。另外,也会遇到 real 远远小于 user + sys 的场景,如果程序在多个 cpu 上并行,那么 usersys 统计时间是多个 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做数字的四则运算

  1. 请用空格隔开每个项。

  2. 请将反斜杠(\)放在 Shell 特殊字符前面。

  3. 请对包含空格和其他特殊字符的字符串用引号括起来。

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、[ ]、[[ ]]

相关文章:

  • 2022-02-26
  • 2022-12-23
  • 2023-01-19
  • 2022-12-23
  • 2021-09-13
  • 2021-12-19
  • 2021-07-02
猜你喜欢
  • 2021-05-30
  • 2022-12-23
  • 2021-08-18
  • 2022-01-24
  • 2022-03-07
  • 2022-01-30
  • 2021-08-31
相关资源
相似解决方案