admin 管理员组

文章数量: 887021

note

1. Shell是什么

  • Shell的作用
    UNIX/Linux系统的内核负责控制硬件、管理内存和调度任务。Shell处于用户和操作系统之间,用户可以利用Shell实现对操作系统及其内核的控制和操作。登录操作系统后,系统会启动一个Shell,可以输入交互式指令。

  • Shell编程语言
    Shell是解释型的编程语言,除了大量命令外,还有变量、条件、循环、函数等。多个Shell命令按一定的逻辑写到一个文件中,可以实现一部分工作的自动化。

Shell有很多版本,当前使用最广泛的是bash。另一版zsh在完全兼容bash的基础上还有极好的用户体验。

2. chsh更换Shell

  • 查看当前安装了哪些Shell
# 方式一
cat /etc/shells
# 方式二
chsh -l
  • 查看当前使用的Shell
echo $SHELL /bin/bash
  • 将默认的Shell环境切换到zsh,重新登录后生效。
chsh -s /bin/zsh

chsh -s 修改的是/etc/passwd文件中用户名对应的行

3. export声明环境变量

  • 环境变量
    Shell的变量分为环境变量和自定义变量。环境变量可以在进程的子进程中继续生效,自定义变量在子进程中不生效。

  • 显示Shell变量的4个命令
    env:显示当前用户的环境变量,不显示自定义变量;
    export:功能同env,只是结果按变量名排序;
    set:显示当前Shell定义的所有变量,环境变量加自定义变量;
    declare:功能同set,结果按变量名排序;

  • P A T H 变量由多个路径组成,使用冒号分隔。用户输入的命令会依次进入 PATH变量 由多个路径组成,使用冒号分隔。用户输入的命令会依次进入 PATH变量由多个路径组成,使用冒号分隔。用户输入的命令会依次进入PATH中的路径寻找。
    把路径添加到环境变量:

export PATH=$PATH:/app/tools

4. read读取输入

read命令可以读取文件输入或标准输入,把信息存到变量中。

echo -n "input name please"
read name
exho "Welcome! $name"
exit 0
选项
  • -p 选项直接显示提示语
read -p "input name please" name
  • 接收多个变量
read -p "input name and age" name age

输入完成时,read会按空格分割输入的内容,分别存到后面的变量中。
输入的数据多于两个变量时,超出的内容都会在最后一个变量。
输入的数据少于两个时,多余的变量值为空。
如果read命令后没有写变量名,这些内容会存到环境变量$REPLY中。

  • -t 指定等待输入的时长
if read -t 5 -p "input name please" name
thenecho "Welcome $name"
elseecho "Time out"
exit 0
  • -s 密码输入
    -s选项使用户输入不会在屏幕上显示信息。
  • -r 禁用转义
    把系统的转义字符作为正常的字符读取。
接收来自文件的内容

文件可以使用三种方式读取

  1. 使用 -u 选项
# 读取文件,文件描述符编号为3
exec 3< test.txtcount=0
# 读取文件内容
while read -u 3 var
dolet count=$count+1# 输出行号和行的内容echo "Line $count: $var"
done
# 关闭文件描述符
exec 3<&-
exit 0
  1. 使用管道
count=1
cat test.txt | while read line
do# 输出行号和行的内容echo "Line $count: $line"let count=$count+1
done
echo "count=$count"
exit 0

由于管道两边需要新建进程,执行完循环后,新的进程结束了,循环中的变量也消失了,所以最后执行echo时显示的是第一行定义的变量的值。

  1. 使用重定向
count=0
while read line
dolet count=$count+1echo "Line $count: $line"
done test.txt
exit 0

5. expr计算器

四则运算
expr 10 + 10
expr 10 - 10
expr 10 / 10
expr 10 \* 10

注意:
需要空格隔开每个项;
Shell特殊字符需要使用反斜杠转义;
包含空格和其他特殊字符的字符串需要用引号括起来。

字符串操作

语法如下

# 正则匹配,返回结果的长度
expr match STR REGEXP
# 从POS位置开始截取LENGTH个字符
expr sunstr STR POS LENGTH
# 查找子字符串的起始位置
expr index STR SUBSTR
# 字符串长度
expr length STR
str="abcdefgh"
expr match $str ".*e"  # 输出"5"
expr substr $str 3 2   # 输出"cd"
expr index $str f      # 输出"6"
expr length $str       # 输出"8"

6. tmux 复用终端

tmux是Terminal MultipleXer的缩写。可以通过一个窗口操作多个会话。

  • centos安装tmux。会自动安装依赖libevent和ncurses。
yum install tmux
  • 启动tmux。
tmux new -s mysession

启动后会在终端底部出现绿色的状态条,上面的0:bash表示会话窗口。

  • 创建新窗口
    按ctrl+b组合键,然后再按c,就会创建一个新的窗口1:bash。
    窗口后面带*号,表示该窗口为活动状态。
    按ctrl+b组合键,然后按0,就把活动窗口切换到0:bash。

  • 退出会话,回到会话
    按ctrl+b组合键,然后按d,就会关闭tmux窗口,tmux会话会挂在服务器上自己运行,效果和终端运行的一样。效果不受个人电脑突发状况的影响。
    查看tmux会话列表

tmux ls

回到tmux会话

tmux a -t mysession

回到会话后,会话内的程序就是正常运行的样子。

7. alias起别名

alias可以为命令设置别名,避免记忆过多的选项。

命令行使用alia

alias的语法格式:alias [name[=value]]。等号前后不能加空格;value中有空格时,需要把value用引号包起来。

  • 查看别名
# 查看所有别名
alias
# 查看单个命令是否为别名
alias vi
  • 取消别名
# 删除单个别名
unalias vi
# 删除全部别名
unlias -a
  • 重名的别名
    和某个命令重名的别名,Shell执行的只会是别名。
    如果想执行原本的命令,需要使用绝对路径或者在别名前使用反斜线。
  • value使用的引号
    使用双引号时,如果value中带有变量,则会把变量的值替换到命令中。使用单引号时,不会替换到命令中,命令仍然是包含变量的命令。
脚本中执行alias命令

Shell脚本中,alias功能默认是关闭的。

shopt命令可以开启alias的扩展选项expand_aliases。shopt -s expand_aliases

由于脚本执行时会产生一个新的进程,新进程中的expand_slashes是关闭状态,所以shopt开启alias的命令需要写在脚本里面。

脚本所在的是新进程,并没有外部Shell中alias设置的内容,想用到其中的别名,需要在脚本头部的“#!/bin/bash”后面加上“–login”选项,使执行脚本的子Shell成为一个login Shell,它会读取系统和用户的profile和rc文件,从而加载alias设置。
综合以上三点,脚本中使用别名需要做这些改动:

#!/bin/bash --login
shopt -s expand_aliases

8. history历史命令

history可以查看历史输入的命令。

重复上一句命令的4种方法
  1. 使用上方向键,回车执行;
  2. 输入!!,回车执行;
  3. 输入!-1,回车执行;
  4. 按Ctrl+P组合键,回车执行;
执行以前执行过的命令的两种方式
  1. 叹号定位法
    先执行history,找到想执行的命令后,记下这个命令前面的标号,输入!标号,然后回车执行。

  2. 搜索定位法
    按Ctrl+R组合键,会出现(reverse-i-search)''的提示,输入一些关键字,系统会从历史命令中做匹配。

清除历史命令

登录Shell时,Shell会加载文件.bash_history中的历史命令。系统会把内存中的历史命令追加到文件.bash_history中。

# 清除内存中的历史命令
history -c
# 使用内存中的历史命令覆盖.bash_history文件的内容
history -w
history的配置选项
# 历史命令输出时带上时间
export HISTTIMEFORMAT='%F %T'
# 设置内存中的历史命令的个数
export HISTSIZE=1000
# 设置文件中的历史命令的个数
expost HISTFILESIZE=1000
# 更改历史命令的文件位置
export HISTFILE=~/history.log# 清除历史命令中的重复条目
export HISTCONTROL=erasedups
# 不记录连续重复的命令
export HISTCONTROL=ignoredups
# 不记录空格开始的命令
export HISTCONTROL=ignorespace
# 相当于ignoredups+ignorespace
export HISTCONTROL=ignoreboth
保护重要命令的两种方式

一些重要命令在使用时不希望被记录在history中,防止系统被攻击时泄露信息。

  1. 设置HISTCONTROL环境变量export HISTCONTROL=ignorespace,然后在输入重要命令时,前面加上空格。
  2. 设置HISTIGNORE环境变量export HISTIGNORE=*,执行重要命令。结束后设置export HISTIGNORE=
    这样做显得麻烦,但是能避免忘记在命令前加空格。

9. xargs传递参数

管道可以将前面的标准输出作为后面的标准输入。
xargs可以把前面的标准输出作为后面的命令参数。
xargs经常和find命令一起使用。

  • xargs的分割符
    xargs的默认分隔符是空格,标准输入中出现的换行符、空格、制表符都会被换成空格。
    当一个参数中自带空格时,该参数也会被分割成多个参数。使用-0选项,可以把xargs的默认分隔符改为NULL。
    -0选项还会把单引号、双引号、反斜线等都认作普通字符。

  • 人为确定是否传参
    前一个命令的标准输出中,如果有一些参数不确定是否要传送,可以使用-p选项,xargs在传送参数前会进行确认。
    再加上-n选项,可以指定xargs每次处理的参数个数。

  • 指定终止点
    -E选项,可以让xargs在遇到特定的参数时终止。

10. time

time能用来测量命令的执行时间,或者给出系统资源的使用情况。

time显示的三种时间

执行time时,会出现三个统计时间
real表示命令从开始执行到完成耗费的CPU总时间,包括CPU时间、I/O阻塞的时间和CPU阻塞时间。
user是进程执行用户态代码耗费的CPU时间。仅指进程实际使用CPU的时间,不包括阻塞时间。
sys是进程在内核态运行所耗费的CPU时间,即执行内核系统调用耗费的CPU时间。

一般real=user+sys,也有例外情况。
进程发生阻塞,或者等待其他进程释放CPU时,会出现real>user+sys;
多核系统中,一些程序能同时利用多个核心的计算能力,这时real<user+sys;

有时同样的命令多次执行,time测出的耗时不一样。因为系统会对一些文件作缓存,第二次执行时会使用缓存中的数据,因此耗时变小。

如何显示资源使用情况

直接使用time,用的是bash内置的命令,只统计时间,不能显示资源消耗。
可以显示资源消耗的命令在/usr/bin/目录下。在time命令前加斜线,即可调用显示更多信息的time。

# 仅显示命令的时间消耗
time ls
# 显示时间消耗和资源消耗
\time ls
# 显示更详细的信息
\time -v ls

11. sleep

sleep可以让程序休息指定的时间。使用数值+单位来指定时间。

单位有s(秒),m(分钟),h(小时),d(天),默认使用秒。不同单位的多个时间可以联合使用,需用空格分开。

数值可以是浮点数,用来指定更小级别的睡眠。不过sleep对低于10ms的时间存在误差。

本文标签: note