关于shell脚本的一些笔记 Jimmy


脚本开头

  1. #!/bin/sh
  2. #!/bin/bash

指定本脚本的解释路径。


脚本的执行方式

  • source
  • 直接执行脚本,sh script 或 ./srcipt

    利用直接执行的方式执行脚本

    1. ./script.sh
    2. 或者
    3. sh script.sh
    此中方式运行的shell脚本只是在bash的子进程中运行,但脚本运行结束,子进程中的变量或者是各种操作,不会返回到父线程,也就是说,在子线程中设置的各种环境变量,定义的各种脚本变量会因为子进程的结束而消亡。
    有一个脚本 script.sh,内容如下
    1. read -p "Input Name: " name
    2. echo -e ${name}
    在执行脚本前,尝试去读取 name 变量的值,确认该变量不存在
    1. $ echo ${name}
    2. # <- 输出为空,变量不存在
    以直接的方式运行脚本
    1. $ ./script.sh
    2. Input Name: chen
    3. chen # <- 输出变量name的内容
    退出脚本后,再读取 name 变量的值,
    1. $ echo ${name}
    2. # <- 输出为空,此时name变量随着子进程结束而消亡

    利用source来执行

    还是执行相同的脚本,脚本运行结束后,再尝试读取 name 变量的值
    1. $ source script.sh # 以source方式执行脚本
    2. Input Name: chen # 输入name变量的值
    3. chen # 脚本内部的echo
    4. $ echo ${name} # 脚本结束后,尝试读取
    5. chen # 显示变量的值
    因为 source 会在父进程中执行脚本,会使脚本在整个系统中生效。
    所以,想要使 ~/.bashrc 生效的方式是 source ~/.bashrc 而不是 sh ~/.bashrc

延时

在linux shell中使用延时。

sleep

  • 默认是秒延时

    1. sleep 0.5s // 延时0.5 s
    2. sleep 1s // 延时1 s
    3. sleep 1m // 延时1 min
    4. sleep 1h // 延时1 hour
    5. sleep 1d // 延时1 day

    usleep

  • 微秒延时


echo

  • 回显shell脚本的字符串内容;

命令语法

  1. $ echo [参数选项] [输出内容]

参数选项

  1. -n : 带参数 -n 表示输出不换行;
  2. -e : 带参数 -e 表示可输出转义字符;

例程

  • 不带参数 -n

    1. $ echo "hello world"
    2. hello world
  • 带参数 -n

    1. $ echo -n "hello world"
    2. $
  • 不带参数 -e

    1. $ echo "hello world \r\n"
    2. hello world \r\n // 转义字符被当作字符输出
  • 带参数 -e ```bash $ echo -e “hello world \r\n” hello world

$

  1. <a name="h8T6b"></a>
  2. ### 输出内容
  3. - **输出简单的字符串**
  4. echo 后无论带不带引号,对于输出字符串内容的效果是一样的。
  5. - 不带引号
  6. ```bash
  7. $ echo hello world
  • 带单引号

    1. $ echo 'hello world'
  • 带双引号

    1. $ echo "hello world"
  • 输出变量的内容

如果输出的内容是一个变量,那么引号的效果就不一样了。

  • 带单引号

单引号会无视所有的特殊字符,全部当作普通的字符输出

  1. $ echo '${USER}'

输出内容

  1. ${USER}
  • 带双引号

双引号会解释 $ (美元符) \ (反斜杠) ` (反单引号,tab键上面那个按键),但是会忽视文件通配符 *?(这两个文件通配符用来模糊搜索文件)

  1. $ echo "${USER}"

输出内容

  1. hero

但是会忽视文件通配符

  1. $ echo "*"
  • 不带任何引号

会解释所有的符号,包括$ (美元符) \ (反斜杠) ` (反单引号,tab键上面那个按键)和文件通配符。其中,文件通配符会输出当前所在目录下的所有的文件夹。

  1. $ echo ${USER} * $(date)

输出内容

  1. $ echo ${USER} * $(date)
  2. hero Cpp Qt_Project Unix 2021 05 05 星期三 11:59:32 CST
  3. // hero是当前的账号
  4. // Cpp Qt_Project Unix 是当前目录下的文件夹
  5. // 2021年 05月 05日 星期三 11:59:32 CST 是$(date)的结果
  • 在shell中显示带颜色的字符
    1. $ echo -e "\033[颜色1;颜色2m [要显示的字符串] \033[0m"
    格式解析
    1. -e : 对转义字符生效
    2. \033[颜色1;颜色2m 转义序列
    3. \033[ : 转义序列的开始,其中\033代表Esc符号,也可以使用\E\e来代替
    4. 颜色1和颜色2 : 表示字体的前景色或背景色,至于颜色1和颜色2哪一个表示前景色,哪一个表示背景色,由其设定的数值来决定,前景色和背景色的数值空间是不同的
    5. m 转义序列的终止标志
    6. \033[0m : 表示将颜色恢复回原来的配色
    1. ![3-1P926164539348.jpg](https://cdn.nlark.com/yuque/0/2021/jpeg/21465892/1620197070716-463b380d-a30f-4ac2-ba75-53047f568e32.jpeg#clientId=u30d47f84-ef72-4&from=ui&id=u50680dc9&margin=%5Bobject%20Object%5D&name=3-1P926164539348.jpg&originHeight=272&originWidth=464&originalType=binary&ratio=1&size=82729&status=done&style=none&taskId=u33e908e3-79e2-46a8-ba54-683bd6ea493)<br />颜色列表:
色彩 绿 洋红
前景色 30 31 32 33 34 35 36 37
背景色 40 41 42 43 44 45 46 47

gnome-terminal

在脚本可以通过 gnome-terminal 命令直接打开一个终端。

命令语法

  1. $ gnome-terminal [选项操作]

选项操作

  1. --window : 打开一个新的终端窗口,--window --windown 可打开2
  2. --tab : 在当前终端中打开一个新的页
  3. --maximize : 打开终端后窗口最大化
  4. --full-screen : 打开终端后窗口全屏
  5. --title="new title" : 给打开的窗口或者页命令
  6. --geometry=80x25+10+10 : 打开终端并设置大小和位置

read

shell利用 read 函数来读取用户的输入,用以实现shell与用户的交互过程。

命令语法

  1. $ read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]

参数说明

  1. -a : 后面需跟随一个变量aname,其中aname被认为是个数组,数组元素以空格隔开;
  2. -d 指定读取行的结束符号。默认结束符号为换行符。
  3. -n 限制读取N个字符就自动结束读取,如果没有读满N个字符就按下回车或遇到换行符,则也会结束读取。
  4. -N 严格要求读满N个字符才自动结束读取,即使中途按下了回车或遇到了换行符也不结束。其中换行符或回车算一个字符。
  5. -p 给出提示符。默认不支持"\n"换行,要换行需要特殊处理,见下文示例。例如,-p "请输入密码:"
  6. -r 禁止反斜线的转义功能。这意味着"\"会变成文本的一部分。
  7. -s : 静默模式。输入的内容不会回显在屏幕上。
  8. -t : 等待输入超时事件,跟随一个等待时间;
  9. -u : 从给定文件描述符(fd=N)中读取数据。

例程

-a

  1. $ read -a array_list
  1. 输出数组
  1. $ echo ${array_list[0]} // 输出数组的第一个元素
  2. $ echo ${array_list[@]} // 输出数组

-p

  1. $ read -p "Please Input" input_var
  1. 输出输入的内容
  1. $ echo ${input_var}

date

date用来获取或者设置时间。在shell里调用date可显示当前的系统时间。

  1. $echo $(date)
  1. 输出内容
  1. 2021 05 09 星期日 15:55:24 CST

命令语法

  1. $ date [选项] ... [+格式]

选项

  1. -d 字符串 : --date=字符串,显示给定<字符串>描述的时间,而非“当前时间”。最多4位,xx:xx:00
  2. -r 文件名 : --reference=文件名,显示指定<文件名>的最后修改时间;
  3. -s 字符串 --set=字符串,按照给定<字符串>描述的时间来设置时间

格式

使date以给定的格式输出。

  1. $ date +"%a"
  1. %% 一个文字的 %
  2. %a 当前locale 的星期名缩写(例如: 日,代表星期日)
  3. %A 当前locale 的星期名全称 (如:星期日)
  4. %b 当前locale 的月名缩写 (如:一,代表一月)
  5. %B 当前locale 的月名全称 (如:一月)
  6. %c 当前locale 的日期和时间 (如:200533 星期四 23:05:25)
  7. %C 世纪;比如 %Y,通常为省略当前年份的后两位数字(例如:20)
  8. %d 按月计的日期(例如:01)
  9. %D 按月计的日期;等于%m/%d/%y
  10. %e 按月计的日期,添加空格,等于%_d
  11. %F 完整日期格式,等价于 %Y-%m-%d
  12. %g ISO-8601 格式年份的最后两位 (参见%G)
  13. %G ISO-8601 格式年份 (参见%V),一般只和 %V 结合使用
  14. %h 等于%b
  15. %H 小时(00-23)
  16. %I 小时(00-12)
  17. %j 按年计的日期(001-366)
  18. %k 小时,空格补充空白位( 0..23);与 %_H 相同
  19. %l 小时,空格补充空白位( 1..12);与 %_I 相同
  20. %m 月份(01..12
  21. %M 分钟(00..59
  22. %n 换行
  23. %N 纳秒(000000000..999999999
  24. %p 当前地区时间设置中 AM PM 的等效值(“上午”或“下午”),未知则为空
  25. %P 类似 %p,但使用小写
  26. %q 一年中的季度(1..4
  27. %r 当前地区时间中十二小时制钟表时间(例如,下午 111104秒)
  28. %R 24 小时制的时间和分钟;和 %H:%M 相同
  29. %s 1970-01-01 00:00:00 UTC 以来的秒数
  30. %S 秒(00-60)
  31. %t 输出制表符 Tab
  32. %T 时间,等于%H:%M:%S
  33. %u 星期,1 代表星期一
  34. %U 一年中的第几周,以周日为每星期第一天(00-53)
  35. %V ISO-8601 格式规范下的一年中第几周,以周一为每星期第一天(01-53)
  36. %w 一星期中的第几日(0-6),0 代表周一
  37. %W 一年中的第几周,以周一为每星期第一天(00-53)
  38. %x 当前locale 下的日期描述 (如:12/31/99)
  39. %X 当前locale 下的时间描述 (如:23:13:48)
  40. %y 年份最后两位数位 (00-99)
  41. %Y 年份
  42. %z +hhmm 数字时区(例如,-0400)
  43. %:z +hh:mm 数字时区(例如,-04:00)
  44. %::z +hh:mm:ss 数字时区(例如,-04:00:00)
  45. %:::z 数字时区带有必要的精度 (例如,-04,+05:30)
  46. %Z 按字母表排序的时区缩写 (例如,EDT)

例程

-d / —date

  1. $ date -d 2222
  2. $ date --date=2222
  1. 输出内容
  1. 2021 05 09 星期日 22:22:00 CST

部分格式举例

  1. $ date +"%B %d %H %M"
  1. 输出内容
  1. 五月 09 16 37