• [技术干货] shell脚本体系知识(5)
    基本重定向软件设计认为,程序应该有一个数据来源、数据出口和报告错误的地方。在 Linux 系统中,每个程序默认都会打开三个文件描述符 (file descriptor,fd):fd=0:标准输入,表示程序默认从哪里读取数据fd=1:标准输出,表示程序默认将数据输出到哪里fd=2:标准错误,表示程序默认将错误信息输出到哪里文件描述符,说白了就是系统为了跟踪打开的文件而分配给它的一个数字,这个数字和文件有对应关系:从文件描述符读取数据,即表示从对应的文件中读取数据,向文件描述符写数据,即表示向对应文件中写入数据。Linux 中万物皆文件,文件描述符也是文件。默认:fd=0 的标准输入是 /dev/stdin 文件fd=1 的标准输出是 /dev/stdout 文件fd=2 的标准错误是 /dev/stderr 文件这些文件默认又是各个终端的软链接文件:所以,默认情况下读写数据都是终端,例如:改变文件描述符对应的目标,可以改变数据的流向。比如标准输出 fd=1 默认流向是终端设备,若将其改为 /tmp/a.log,便能让数据写入 /tmp/a.log 文件中而不再是终端设备中。在 Shell 中,这种改变文件描述符目标的行为称为重定向,即重新确定数据的流向。其实,文件描述符有很多类操作,包括 fd 的重定向、fd 的分配 (open,即打开文件)、fd 复制 (duplicate)、fd 的移动 (move)、fd 的关闭 (close)。现在只介绍基础重定向操作。Shell 中,基础重定向操作有以下几种方式:[n]>file:覆盖式输出重定向,输出到 fd=n 的数据改变流向输出到 file 文件中,file 不存在则创建,file 存在则先清空再写入数据省略 n 时 >file,等价于 1>file,即标准输出覆盖重定向到 file 文件中[n]>>file:追加式输出重定向,输出到 fd=n 的数据改变流向输出到 file 文件的尾部,file 不存在则创建,file 存在则直接追加在文件尾部省略 n 时 >>file,等价于 1>>file,即标准输出追加重定向到 file 文件中[n]<file:输入重定向,以读取模式打开 file 文件并分配 fd=n,file 不存在则报错省略 n 时 <file,等价于 0<file,即直接从 file 中读数据通常程序都只从 fd=0 中读数据,所以当 n 不等于 0 时,需要多做一步操作 3<file <&3,看不懂先跳过&>file:这是特殊的重定向方式,表示将标准错误和标准输出都重定向到 file 文件中,等价于 >file 2>&1&>>file:这是特殊的重定向方式,表示将标准错误和标准输出都追加到 file 文件中,等价于 >>file 2>&1另外,经常用于输出的一个特殊目标文件是 /dev/null,它是空设备,可以直接丢掉所有写入它的数据。echo www.junmajinlong.com >/dev/null curl -I www.junmajinlong.com 2>/dev/null >/tmp/a.log cat </etc/fstab一个经常用的技巧是清空文件的方式:$ cat /dev/null >file $ >file区分 cat <file 和 cat filecat 是一个命令,这个命令的源代码中写了一些代码用来处理选项和参数。cat -n /etc/fstabcat 命令开始执行后,会识别 -n 选项,该选项会让 cat 输出时同时输出行号,cat 同时还会识别 /etc/fstab 参数,cat 会读取参数指定的文件然后输出。如果没有指定 cat 的文件参数,则 cat 默认会从标准输入中读取数据。默认的标准输入是终端,所以在没有改变标准输入的流向时,会从终端读取数据,也就是用户输入什么字符,就读取什么字符,然后输出什么字符:$ cat junmajinlong # 在终端输入 junmajinlong # 在终端输出 junma # 在终端输入 junma # 在终端输出 ^C但用户可以改变标准输入的来源。比如:$ cat </etc/fstab表示将标准输入来源改为 /etc/fstab 文件,于是 cat 会从 /etc/fstab 中读取数据。另外,约定俗成的,会使用一个 - 来表示标准输入或标准输出。下面是等价的,都表示从标准输入中读取数据cat - cat /dev/stdin cat注:这并非是一贯正确的,只是约定俗成的大多数程序的代码中都定义了 - 相关的代码处理。可参考相关命令的 man 手册。如 man cat 中有一行:With no FILE, or when FILE is -, read standard input.
  • [技术干货] shell脚本体系知识(4)
    后台执行命令在命令的结尾使用 & 符号,可以将这个命令放入后台执行。命令放入后台后,会立即回到 Shell 进程,Shell 进程会立即执行下一条命令 (如果有) 或退出。使用 $! 可以获取最近一个后台进程的 PID。sleep 20 & echo $!使用 wait 命令可以等待后台进程 (当前 Shell 进程的子进程) 完成:wait [n1 n2 n3 ...]不给定任何参数时,会等待所有子进程 (即所有后台进程) 完成。sleep 5 & wait echo haha多命令组合Shell 中有多种组合多个命令的方式。1.cmd1 退出后,执行 cmd2cmd1;cmd22.cmd1 正确退出 (退出状态码为 0) 后,执行 cmd2cmd1 && cmd23.cmd1 不正确退出后,执行 cmd2cmd1 || cmd2逻辑结合:&& 和 || 可以随意结合将多个命令分组:小括号或大括号可以组合多个命令
  • [技术干货] shell脚本体系知识(3)
    命令替换使用反引号或 $() 可以执行命令替换。`cmd` $(cmd)命令替换是指先执行 cmd,将 cmd 的输出结果替换到 $() 或反引号位置处。例如:echo `id root` echo $(id root)在 echo 命令执行前,会先执行 id 命令,id 命令的执行结果:$ id root uid=0(root) gid=0(root) groups=0(root)所以会将结果 js uid=0(root) gid=0(root) groups=0(root)替换 $(id root)。于是,echo 命令开始执行时,命令行已经变成了:echo uid=0(root) gid=0(root) groups=0(root)算术运算$[] 或 $(()) 或 let 命令可以做算术运算。let 是单独的命令,不能写在其它命令行中。a=3 let a=a+1 echo $a$[] 和 $(()) 可以写在命令行内部,Shell 在解析命令行的时候,会对它们做算术运算,然后将运算结果替换到命令行中。a=33 echo $[a+3] echo $((a+3))因为变量替换先于算术替换,所以,使用变量名或引用变量的方式都可以:a=333 echo $[$a+3] echo $(($a+3))退出状态码每个命令执行后都会有对应的进程退出状态码,用来表示该进程是否是正常退出。所以,在命令行中,在 Shell 脚本中,经常会使用特殊变量 $? 判断最近一个前台命令是否正常退出。通常情况下,如果 $? 的值:为 0,表示进程成功执行,即正常退出非 0,表示进程未成功执行,即非正常退出但非 0 退出状态码并不一定表示错误,也可能是正常逻辑的退出另外,在 Shell 脚本中,所有条件判断 (比如 if 语句、while 语句) 都以 0 退出状态码表示 True,以非 0 退出状态码为 False。exit 命令exit 命令可用于退出当前 Shell 进程,比如退出当前 Shell 终端、退出 Shell 脚本,等等。exit [N]exit 可指定退出状态码 N,如果省略 N,则默认退出状态码为 0,即表示正确退出。
  • [技术干货] shell脚本体系知识(2)
    变量的运用1. 变量命名界说变量时,变量名不加美元符号($,PHP言语中变量需求),如:your_name="yikoulinux"留神,变量名和等号之间不能有空格,这或许和你了解的悉数编程言语都不相同。一同,变量名的命名须遵从如下规矩:命名只能运用英文字母,数字和下划线,首个字符不能以数字开端。 中心不能有空格,能够运用下划线(_)。 不能运用标点符号。 不能运用bash里的要害字(可用help指令检查保存要害字)。 变量称谓一般习气为大写有用的 Shell 变量名示例如下:RUNOOB LD_LIBRARY_PATH _var var2 无效的变量命名: ?var=123 user*name=runoob2. 常用变量Linux Shell 中的变量分为:体系变量和用户自界说变量。体系变量:HOME、HOME、HOME、PWD、SHELL、SHELL、SHELL、USER 等等比方:echo $HOME 等等..用户自界说变量:界说变量:变量=值 显现当时 shell 中悉数变量:set 吊销变量:unset 变量 声明静态变量:readonly 变量,注意:不能 unset将指令的回来值赋给变量(要害)除了显式地直接赋值,还能够用句子给变量赋值,如:1)A=ls -la反引号,作业里边的指令,并把作用回来给变量 A2)A=$(ls -la)$等价于反引号3)for file in `ls /etc`或for file in $(ls /etc)以上句子将 /etc 下目录的文件名循环出来。3. 举例例1:意义如下:界说一个变量名为name的变量,值为一口linux 输出变量name的值 界说一个变量名为number的变量,初始值为22 输出变量number的值 直接输出带变量的字符串 运用双引号输出带变量的字符串 运用单引号输出带变量的字符串 运用双引号输出带不存在的变量的字符串,不存在的变量默许为空 运用双引号来声明字符串中的变量 运用大括号{&变量名},声明字符串中的变量注意:上述变量是暂时变量,当关闭终端后,变量就会消失。例2:删去变量并检查指定变量unset name 删去变量name检查name变量
  • shell脚本体系知识(1)
    hell 脚本基础Bash 注释Bash 只支持单行注释,使用#开头的都被当作注释语句:# 整行注释 echo hello world # 行尾注释通过 Bash 的一些特性,可以取巧实现多行注释:: ' 注释1 注释2 ' : <<'EOF' 注释1 注释2 EOF ____=' 注释1 注释2Bash 基本数据类型Bash 中基本数据类型只有字符串类型,连数值类型都没有 (declare -i 可强制声明数值类型)。# 都会当作字符串 echo haha echo 1234Bash 字符串串联Bash 中字符串的串联操作,直接将两段数据连接在一起即可,不需要任何操作符。例如:echo "junma""jinlong" echo 1234 5678命令基本知识变量赋值和引用变量a=3 echo $a a="www.junmajinlong.com" echo $a a='hello world' echo $aShell 中可以引用未定义的变量:echo $xyzdefabc可以定义空变量:a= echo $a变量替换变量替换是指在命令开始执行前,Shell 会先将变量的值替换到引用变量的位置处。例如:a="hello" echo $a world在 echo 命令开始执行前,Shell 会取得变量 a 的值 hello,并将它替换到命令行的 $a 处。于是,在 echo 命令开始执行时,命令行已经变成:echo hello world除了变量替换,Shell 还会做其它替换:命令替换进程替换算术运算替换大括号扩展波浪号扩展路径扩展这些扩展和替换,都是 Shell 在调用命令之前就完成的,这和其它语言解析代码的方式不一样。后面会详细解释 Shell 是如何做命令行解析的,如果不掌握命令行解析,当遇到命令行语法错误后很可能会花掉大量无谓的时间去调试命令。而掌握命令行解析后,就会对命令生命周期了如执掌,不敢说一次就能写对所有命令行,但能节省大量调试时间,对写命令行和写脚本的能力也会上升一个层次。