shell 基础

Posted 那个少年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell 基础相关的知识,希望对你有一定的参考价值。

1. 输出命令

echo [选项] [输出内容]

选项:
• -e:支持反斜线控制的字符转换(具体参见表 1)
• -n:取消输出后行末的换行符号(内容输出后不换行)

2.shell脚本的结构(一般为三部分)

(1)声明脚本中的语言:

#!/bin/bash

(2)声明脚本的功能
以#开头的语句都是注释
(3)脚本的主体

3. 运行方式(运行前需注意该对该文件是否有执行的权限)

(1)使用路径直接运行
(2)通过bash调用脚本

bash  文件路径

4. 给命令设置别名

(1)显示系统中的命令别名

alias

(2)设置别名

alias 别名=\'原命令\'

注意:设置别名后,原命令失效。且设置的别名在系统中必须是不存在的。
使用命令设置的别名且在系统未注销、重启前有效,需要持久生效,需要修改配置文件
(3)删除别名

unalias 原命令

5. 提取命令grep

在文件中提取和匹配符合条件的所有字符串行

grep  [选项]  "搜索内容"  文件名

选项:
• -A 数字:列出符合条件的行,并列出后续的 n 行;
• -B 数字:列出符合条件的行,并列出前面的 n 行;
• -c:统计找到的符合条件的字符串的次数;
• -i:忽略大小写;
• -n:输出行号;
• -v:反向査找;
• --color=auto:搜索出的关键字用颜色显示;

6. 管道符

用来连接多条命令,但下一条命令的执行依赖于上一条命令的正确输出
“命令1 | 命令2” 命令2只能处理命令1的正确输出结果

ls -a /etc/ | more  

7. bash 通配符

通配符 作 用

  • ? 匹配一个任意字符
  • * 匹配 0 个或任意多个任意字符,也就是可以匹配任何内容
  • [ ] 匹配中括号中任意一个字符。例如,[abc] 代表一定匹配一个字符,或者是 a,或者是 b,或者是 c
  • [-] 匹配中括号中任意一个字符,- 代表一个范围。例如,[a-z] 代表匹配一个小写字母
  • [^] 逻辑非,表示匹配不是中括号内的一个字符。例如,[^0-9] 代表匹配一个不是数字的字符

8. 单引号和双引号、反引号

单引号内的内容会当成字符串原样输出
双引号内的内容会考虑特殊含义,比如"$"、"\\"
如果需要调用命令的输出或者将命令的输出赋值给变量,则需要反引号,反引号等价于$(命令),但为了避免反引号与单引号的混淆,常用的是 $(命令)代替反引号的使用

9. 圆括号与花括号

圆括号和花括号主要区别在于:
• () 执行一串命令时,需要重新开启一个子 Shell 来执行。
• {} 执行一串命令时,在当前 Shell 中执行。
• () 和 {} 都是把一串命令放田括号里面,并且命令之间用";"隔开。
• () 最后一条命令可以不用分号。
• {} 最后一条命令要用分号。
• {} 的第一条命令和左括号之间必须有一个空格。
• () 里的各命令不必和括号有空格。
• () 和 {} 中括号里面的某条命令的重定向只影响该命令,但括号外的重定向则会影响到括号里的所有命令。

其实在执行一串命令时,如果使用的是小括号,则这串命令所做的修改只在子 Shell 中生效,一旦命令执行结束,回到父 Shell 中,这个修改就会丟失;而如果使用的是大括号,则此串命令直接在父 Shell 中执行,命令执行结束后,修改依然会生效。
父shell和子shell互不干扰

10. 变量

(1)变量由字母、数字和下划线组成,不可以以数字开头
(2)在Bash中,变量的默认类型是字符串类型,如需进行数值运算,必须进行另外指定:

如:a=1+2
echo $a
1+2 

(3)变量两边用“=”连接,等号两边不能有空格
(4)变量叠加:
两种格式:"$变量名"或${变量名}
(5)将命令的结果作为变量的值赋值给变量,需要使用$()(不推荐使用反引号)
(6)环境变量建议使用大写区分

11. 用户自定义变量

(1)查询已经设定的变量

set [选项]

选项:
• -u:如果设定此选项,则在调用未声明的变量时会报错(默认无任何提示);
• -x:如果设定此选项,则在命令执行之前会先把命令输出一次;

(2)变量删除

Unset 变量名

12. 环境变量和自定义变量

环境变量是全局变量,而自定义变量是局部变量。如果将环境变量写入配置文件,则环境变量可以永久存在,否则一旦shell终止,则环境变量也失效了
(1)环境变量的设置

Export  age="18"

(2)环境变量的查询

Set   查询所有变量
Env  仅查询环境变量  

(3)删除

Unset  变量名

13. bash位置参数变量用法

ls   a.conf  b.conf  c.conf
// 则 $0 的值就是 ls 命令本身,$1,$2,$3 的值分别是 a.conf  b.conf  c.conf

位置参数变量 作 用

  • $n
    n 为数字,$0 代表命令本身,$1〜$9 代表第 1〜9 个参数,10 以上的参数需要用大括号包含, 如${10}
  • $*
    这个变量代表命令行中所有的参数,把所有的参数看成一个整体
  • $@
    这个变量也代表命令行中所有的参数,不过 $@ 把每个参数区别对待
  • $#
    这个变量代表命令行中所有参数的个数

14. 预定义变量(已定义、不能更改的全局变量)

预定义变量 作 用

  • $?
    最后一次执行的命令的返回状态。如果这个变量的值为 0,则证明上一条命令正确执行;如果这 个变量的值为非 0 (具体是哪个数由命令自己来决定),则证明上一条命令执行错误
  • $$ 当前进程的进程号(PID)

  • $!
    后台运行的最后一个进程的进程号(PID)

15. 接收标准输入

Read  【选项】  【变量名】

选项:
• -p "提示信息":在等待read输入时,输出提示信息;
• -t 秒数:read命令会一直等待用户输入,使用此选项可以指定等待时间;
• -n 字符数:read命令只接收指定的字符数就会执行;
• -s: 隐藏输入的数据,适用于机密信息的输入;

read -n 1 -t 30 -p "Please select your gender[M/F]:" gender

提示"请选择性别"并等待30秒,把用户的输入保存到变量gender中
使用"-n 1"选项只接收一个输入字符就会执行(无须按回车键)

16. 数值运算

(1)使用declare声明变量类型

declare [+/-] [选项] 变量名

选项:
• -:给变量设定类型属性;
• +:取消变量的类型属性;
• -a:将变量声明为数组型;
• -i:将变量声明为整数型(integer);
• -r:将变量声明为只读变量。注意,一旦设置为只读变量,既不能修改变量的值,也不能删除变量,甚至不能通过 +r 取消只读属性;
• -x:将变量声明为环境变量;
• -p:显示指定变量的被声明的类型;

Name[0]="zhang san"
Name[1]="li ming"
Name[2]="xiao ming"
echo ${name}
// zhang san
echo ${name[*]}
// zhang san li ming xiao ming

(2)使用expr或let数值运算工具

Dd = $(expr $aa + $bb)

注意+号两边必须有空格,否则运算不执行

let  ee = $aa+$bb (推荐的运算方法)

(3)$((运算式))或者$[运算式]

Gg=$[$aa+$bb]

17.常用运算符

优先级    运算符    说 明
-,+    单目负、单目正
!,~    逻辑非、按位取反或补码
*, /, %    乘、除、取模
+, -    加、减
<<, >>    按位左移、按位右移
<=, >=, <, >    小于或等于、大于或等于、小于、大于
== ,!=    等于、不等于
&    按位与
^    按位异或
|    按位或
&&    逻辑与
II    逻辑或
=,+=,•=,*=,/=,%=,&=, |=, <<=, >>=    赋值、运算且赋值

18.错误处理

# 1. 开启变量不存在报错提示,默认变量不存在会忽略
set -u

# 2. 出现错误立刻退出
set -e

# 3. 如果是管道操作中出错,后面还会继续执行,所以 set -e 需要其他命令配合
set -eo pipefail

# 4. 查看每条命令执行结果,用于调试
set -x

# 5. 总结之前
建议在每个脚本开头都加上命令:set -euo pipefail

# 6. exit 钩子
function finish {
  err=$?
  if [[ $err == 1 ]]; then
    echo \'1\'
  fi
}

trap finish EXIT

这里的 trap 是一个内置命令,用来捕捉发送给程序的信号。它接受两个参数,第一个是处理信号的方式,第二个则是信号名。

# 7. 代码调试
如果只想调试代码而不执行,可以通过 sh -n *.sh 

此外,我们还可以增强 set -x 指令的效果,上文说过被执行的指令前面会有 + 的前缀,它其实是是通过一个叫做 PS4 的环境变量来控制的。我们可以修改这个变量:
export PS4=\'+{$LINENO:${FUNCNAME[0]}} \'
这里会显示代码所在行数(LINENO)和当前函数名(FUNCNAME[0])

以上是关于shell 基础的主要内容,如果未能解决你的问题,请参考以下文章

Linux bash基础特性二

逆向及Bof基础实践

20155307刘浩《网络对抗》逆向及Bof基础

代码片段:Shell脚本实现重复执行和多进程

20155311高梓云《网络对抗》逆向及Bof基础

20145301赵嘉鑫《网络对抗》逆向及Bof基础