11
33
新手上路
1.什么是Shell Shell是一个命令解释器,它的作用是解释执行用户输入的命令及程序等,用户每输入一条命令,Shell就解释执行一条。这种从键盘一输入命令,就可以立即得到回应的对话方式,称为交互的方式。 2.Shell脚本 当命令或程序语句不在命令行下执行,而是通过一个程序文件来执行时,该程序就被称为Shell脚本。如果在Shell脚本里内置了很多条命令、语句及循环控制,然后将这些命令一次性执行完毕,这种通过文 件执行脚本的方式称为非交互的方式。 3.Shell的分类 Shell脚本语言是弱类型语言(无须定义变量的类型即可使用),在Unix/Linux中主要有两大类Shell:一 类是Bourne shell,另一类是C shell。 4.Shell脚本语言的优势 Shell脚本语言的优势在于处理偏操作系统底层的业务,例如:Linux系统内部的很多应用(有的是应用的一部分)都是使用Shell脚本语言开发的。 对于一些常见的系统脚本,使用Shell开发会更简单、更快速,例如:让软件一键自动化安装、优化,监控报警脚本,软件启动脚本,日志分析脚本等。 5.脚本开头 在执行bash脚本的时候,内核会根据“#! ”后的解释器来确定该用哪个程序解释这个脚本中的内容。#!/bin/bash复制代码6.Shell脚本的执行 Shell脚本是从上至下依次执行每一行的命令及语句的,即执行完了一个命令后再执行下一个,如果在Shell脚本中遇到子脚本(即脚本嵌套)时,就会先执行子脚本的内容,完成后再返回父脚本继续执行父脚本内后续的命令及语句。 通常情况下,在执行Shell脚本时,会向系统内核请求启动一个新的进程,以便在该进程中执行脚本的命令及子Shell脚本。 Shell脚本的执行通常可以采用以下几种方式。bash script-name`bash script-name或sh script-name:这是当脚本文件本身没有可执行权限(即文件权限属性x位为-号)时常使用的方法,或者脚本文件开头没有指定解释器时需要使用的方法。`./script-name`path/script-name或 ./script-name:指在当前路径下执行脚本(脚本需要有执行权限),需要将脚本文件的权限先改为可执行(即文件权限属性加x位),具体方法为chmod +x script-name。然后通过脚本绝对路径或相对路径就可以直接执行脚本了。`source script-namesource script-name或.script-name:这种方法通常是使用source或“.”(点号)读入或加载指定的Shell脚本文件,然后,依次执行指定的Shell脚本文件san.sh中的所有语句。这些语句将在当前父Shell脚本father.sh进程中运行(其他几种模式都会启动新的进程执行子脚本)复制代码source或“.”命令的功能是:在当前Shell中执行source或“.”加载并执行的相关脚本文件中的命令及语句,而不是产生一个子Shell来执行文件中的命令。注意“.”和后面的脚本名之间要有空格。因此,使用source或“.”可以将自身脚本中的变量值或函数等的返回值传递到当前父Shell脚本father.sh中使用。这是它和其他几种方法最大的区别`创建sh文件 `[root@localhost ~]# cd /opt[root@localhost opt]# mkdir scripts[root@localhost opt]# cd scripts/[root@localhost scripts]# vim hello.sh#! /bin/bashecho "hello world!"`bash hello.sh`[root@localhost scripts]# bash hello.sh hello world!`./hello.sh`[root@localhost scripts]# ./hello.sh-bash: ./hello.sh: 权限不够[root@localhost scripts]# ls -l总用量 4-rw-r--r--. 1 root root 33 7月 5 22:45 hello.sh`添加执行权限`[root@localhost scripts]# chmod +x hello.sh [root@localhost scripts]# ./hello.shhello world!`直接输入 会被当作命令 命令没有写进文件`[root@localhost scripts]# hello.sh-bash: hello.sh: 未找到命令`source . 执行脚本`[root@localhost scripts]# source hello.sh hello world![root@localhost scripts]# . hello.sh hello world!`source . 执行脚本会在当前shell进程执行 而上面两种会开辟一个子shell进程去执行脚本`复制代码
1.变量的基本概念 变量用于存储程序中使用的数据,所存储的数据存在于内存空间中,通过变量的名字就可以取出与变量 对应的数据,变量定义的语法:变量名称=值复制代码注意”=“的两侧无空格,否则变量名称会被识别为命令,变量的内容一般要加双引号,以防止出错,特别 是当值里的内容之间有空格时。默认情况下,在bash Shell中是不会区分变量类型的,例如:常见的变量类型为整数、字符串、小数等。这和其他强类型语言(例如:Java/C语言)是有区别的。 定义变量,并输入变量的值a=5echo $a #通过echo命令加上$即可输出变量的值复制代码2. 子进程Shell与变量的可见性`查看当前和终端相关的进程信息,可以看到只有一个“-bash”进程,此进程也是目前正在使用的bash shell进程。通过执行 bash命令可以基于当前的shell进程再开启一个新的bash shell进程,既子shell进程`[root@localhost scripts]# ps -fUID PID PPID C STIME TTY TIME CMDroot 1375 1371 0 7月05 pts/0 00:00:00 -bashroot 1598 1375 0 00:07 pts/0 00:00:00 ps -f[root@localhost scripts]# bash[root@localhost scripts]# ps -fUID PID PPID C STIME TTY TIME CMDroot 1375 1371 0 7月05 pts/0 00:00:00 -bashroot 1600 1375 0 00:09 pts/0 00:00:00 bashroot 1612 1600 0 00:09 pts/0 00:00:00 ps -f`可以看到bash进程的父进程(PPID)是 -bash 1375`[root@localhost scripts]# exitexit[root@localhost scripts]# ps -fUID PID PPID C STIME TTY TIME CMDroot 1375 1371 0 7月05 pts/0 00:00:00 -bashroot 1614 1375 0 00:14 pts/0 00:00:00 ps -f`在子Shell中创建的变量上一级Shell是看不到的(显示空的),反之也一样`[root@localhost scripts]# a=1[root@localhost scripts]# echo $a1[root@localhost scripts]# bash[root@localhost scripts]# echo $a[root@localhost scripts]# b=2[root@localhost scripts]# echo $b2[root@localhost scripts]# exitexit[root@localhost scripts]# echo $b[root@localhost scripts]# `上节所述:``source . 执行脚本会在当前shell进程执行 而上面两种会开辟一个子shell进程去执行脚本``继续测试``默认环境我们定义了变量a,我们再写一个.sh文件 让它直接echo $a 在不同shell环境下执行试试`[root@localhost scripts]# vim a.sh#! /bin/bashecho $a[root@localhost scripts]# ps -fUID PID PPID C STIME TTY TIME CMDroot 1375 1371 0 7月05 pts/0 00:00:00 -bashroot 1654 1375 0 00:26 pts/0 00:00:00 ps -f[root@localhost scripts]# echo $a1[root@localhost scripts]# bash a.sh [root@localhost scripts]# chmod +x a.sh [root@localhost scripts]# ./a.sh[root@localhost scripts]# source a.sh 1[root@localhost scripts]# . a.sh 1[root@localhost scripts]# 复制代码3.变量的类型 变量可分为两类:环境变量(全局变量)和普通变量(局部变量)。 环境变量也可称为全局变量,可以在创建它们的Shell及其派生出来的任意子进程Shell中使用,环境变量又可分为自定义环境变量和bash内置的环境变量。 普通变量也可称为局部变量,只能在创建它们的Shell函数或Shell脚本中使用。普通变量一般由开发者在开发脚本程序时创建。 4.环境变量 如何让局部变量(普通变量)变为环境变量呢? 在前面加export 环境变量一般是指用export内置命令导出的变量,用于定义Shell的运行环境,保证Shell命令的正确执行。 Shell通过环境变量来确定登录用户名、命令路径、终端类型、登录目录等,所有的环境变量都是系统全局变量,可用于所有子进程中,这包括编辑器、Shell脚本和各类应用。 5.系统环境变量 环境变量可以在命令行中设置和创建,但用户退出命令行时这些变量值就会丢失,因此,如果希望永久保存环境变量,可在以下位置配置: 用户家目录下的.bash_profile或.bashrc(非用户登录模式特有,例如远程SSH)文件中 全局配置/etc/bashrc(非用户登录模式特有,例如远程SSH)或/etc/profile文件中定义 在将环境变量放入上述的文件中后,每次用户登录时这些变量都将被初始化。 按照系统规范,所有环境变量的名字均采用大写形式。在将环境变量应用于用户进程程序之前,都应该用export命令导出定义,例如:正确的环境变量定义方法为export FLAG=1复制代码测试:[root@localhost scripts]# ps -fUID PID PPID C STIME TTY TIME CMDroot 1375 1371 0 7月05 pts/0 00:00:00 -bashroot 1776 1375 0 01:17 pts/0 00:00:00 ps -f[root@localhost scripts]# export A=300[root@localhost scripts]# echo $A300[root@localhost scripts]# bash[root@localhost scripts]# echo $A300`查看环境变量`[root@localhost ~]# envXDG_SESSION_ID=2HOSTNAME=localhost.localdomainSELINUX_ROLE_REQUESTED=TERM=xterm-256colorSHELL=/bin/bashHISTSIZE=1000SSH_CLIENT=192.168.70.1 60151 22SELINUX_USE_CURRENT_RANGE=SSH_TTY=/dev/pts/0USER=root`显示当前Shell中所有变量`[root@localhost ~]# set`如果想要设置环境变量,就要在给变量赋值之后或在设置变量时使用export命令,此处不要在变量名前面加$`export A=100A=100export A对于用户的环境变量设置,比较常见的是用户家目录下的.bashrc和.bash_profile。全局环境变量的配置文件,一般放在/etc/bashrc,/etc/profile中复制代码6.显示与取消环境变量`通过echo打印环境变量,常见系统环境变量:` $HOME:用户登录时进入的目录。 $UID:当前用户的UID(用户标识) $PWD:当前工作目录的绝对路径名 $SHELL:当前SHELL。 USER:当前用户 [root@localhost ~]# echo $HOME/root`用unset消除本地变量和环境变量`echo $USERunset USER #可以看到变量的内容显示为空。复制代码7.普通变量为普通变量的定义赋值,一般有以下3种写法: 变量=value 变量='value 变量="value" 变量的内容可以用单引号或双引号引起来,也可不加引号,但是这三者的含义是不同的,运行如下脚本#! /bin/basha=192.168.1.10-$ab='192.168.1.10-$a'c="192.168.1.10-$a"echo "a=$a"echo "b=$b"echo "c=${c}"[root@localhost scripts]# vim test.sh`复制上面脚本内容`[root@localhost scripts]# source test.sh a=192.168.1.10-b=192.168.1.10-$ac=192.168.1.10-192.168.1.10-`我们可以发现`不加引号时,值里有变量的会被解析后再输出单引号,单引号里是什么就输出什么双引号,输出变量内容时引号里的变量及命令会经过解析后再输出内容==通常,数字内容的变量定义可以不加引号,其他没有特别要求的字符串等定义最好都加上双引号==复制代码
1.将命令结果赋值给变量变量=`ls`变量=$(ls)[root@localhost scripts]# a=`hostname`[root@localhost scripts]# echo $alocalhost.localdomain[root@localhost scripts]# a=$(pwd)[root@localhost scripts]# echo $a/opt/scripts`在变量名前加$可以取得该变量的值,使用echo命令可以显示变量的值,$A和${A}的写法不同,但效果是一样的`==当变量后面连接有其他字符的时候,必须给变量加上大括号{}==[root@localhost scripts]# a='zhangsan'[root@localhost scripts]# echo $a_xiaozhang[root@localhost scripts]# echo ${a}_xiaozhangzhangsan_xiaozhang复制代码2.特殊变量 在Shell中存在一些特殊且重要的变量,例如:$0、$1、$#,我们称之为特殊位置参数变量。 $n`要从命令行、函数或脚本执行等处传递参数时,就需要在Shell脚本中使用位置参数变量。`[root@localhost scripts]# vim p.sh[root@localhost scripts]# cat p.sh #! /bin/bashecho $1[root@localhost scripts]# bash p.sh [root@localhost scripts]# bash p.sh xuxuxuxu[root@localhost scripts]# vim p.sh [root@localhost scripts]# cat p.sh #! /bin/bashecho $1 $2[root@localhost scripts]# bash p.sh xuxu xuxuxuxuxu xuxuxu`在脚本中快速生成多个变量`echo \${1..15} #相当于 echo $1 ... $15 [root@localhost scripts]# echo \${1..15}$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15[root@localhost scripts]# echo \${1..15} > x.sh[root@localhost scripts]# vim x.sh [root@localhost scripts]# cat x.sh echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15[root@localhost scripts]# bash x.sh zhangsan lisi wangwuzhangsan lisi wangwu zhangsan0 zhangsan1 zhangsan2 zhangsan3 zhangsan4 zhangsan5`当位置参数数字大于9时,需要用大括号将数字括起来,如:${10},否则会出现异常`复制代码$0 $0的作用为取出执行脚本的名称(包括路径)root@localhost scripts]# vim n.sh[root@localhost /]# cat /opt/scripts/n.sh echo $0[root@localhost scripts]# bash n.sh n.sh[root@localhost scripts]# cd /[root@localhost /]# bash /opt/scripts/n.sh /opt/scripts/n.sh复制代码时如果希望单独获取名称或路径,则可用dirname及basename命令dirname /opt/server/a.txtbasename /opt/server/a.txt复制代码利用$0和上述命令(dirname、basename)分别取出脚本名称和脚本路径。[root@localhost scripts]# vim n.sh [root@localhost /]# cat /opt/scripts/n.sh dirname $0basename $0[root@localhost scripts]# cd /[root@localhost /]# bash /opt/scripts/n.sh /opt/scriptsn.sh复制代码$# 通过$#获取脚本传参的个数[root@localhost scripts]# vim q.sh [root@localhost scripts]# cat q.sh echo $1 $2 $3 $4 $5 $6 $7 $8 $9echo $#[root@localhost scripts]# bash q.sh {a..z}a b c d e f g h i26`可以看到$#输出的26 因为传递的是a-z 26字母 打印的是前9个`复制代码$* $@ 利用set设置位置参数 表示清除所有的参数变量,重新设置后面的参数变量[root@localhost scripts]# set -- zhangsan lisi wangwu[root@localhost scripts]# echo $1zhangsan[root@localhost scripts]# echo $3wangwu[root@localhost scripts]# echo $*zhangsan lisi wangwu[root@localhost scripts]# echo $@zhangsan lisi wangwu复制代码测试\(*和\)@,注意,此时不带双引号:[root@localhost scripts]# echo $*zhangsan lisi wangwu[root@localhost scripts]# echo $@zhangsan lisi wangwu[root@localhost scripts]# for i in $*;do echo $i;donezhangsanlisiwangwu[root@localhost scripts]# for i in $@;do echo $i;donezhangsanlisiwangwu复制代码测试"\(*"和"\)@",注意,此时带有双引号:[root@localhost scripts]# echo "$*"zhangsan lisi wangwu[root@localhost scripts]# echo "$@"zhangsan lisi wangwu`主要区别 $*会把所有参数当作一个整体`[root@localhost scripts]# for i in "$*";do echo $i;donezhangsan lisi wangwu[root@localhost scripts]# for i in "$@";do echo $i;donezhangsanlisiwangwu复制代码$? $?用于获取执行上一个指令的执行状态返回值,0表示成功,非0表示失败[root@localhost scripts]# [root@localhost scripts]# pwd/opt/scripts[root@localhost scripts]# echo $?0复制代码3.内置变量命令 bash Shell包含一些内置命令。这些内置命令在目录列表里是看不见的,它们由Shell本身提供。常用的内部命令有:echo、eval、exec、export、read、shift。下面简单介绍几个最常用的内置命令的格式和功能。 eval eval,当Shell程序执行到eval语句时,Shell读入参数args,并将它们组合成一个新的命令,然后执行[root@localhost scripts]# vim noeval.sh[root@localhost scripts]# cat noeval.sh echo \$$#[root@localhost scripts]# bash noeval.sh a1 a2$2[root@localhost scripts]# vim noeval.sh [root@localhost scripts]# cat noeval.sh eval echo \$$#[root@localhost scripts]# bash noeval.sh a1 a2a2`相当于echo $2`复制代码
1.算术运算符 算术运算符号均适用于常见的运算命令,常见算术运算命令如下 ”(())”****数值运算 双小括号“(())”的作用是进行数值运算与数值比较 利用“(())”进行简单的数值计算[root@localhost scripts]# a=1+1[root@localhost scripts]# echo $a1+1[root@localhost scripts]# echo $((a))2[root@localhost scripts]# echo $((1+1))2复制代码利用“(())”双括号进行比较及判断[root@localhost scripts]# echo $((1>2))0[root@localhost scripts]# echo $((1<2))1复制代码在[]中一般用-a、-o、-gt(用于整数)、-lt(用于整数)代替上述操作符[root@localhost scripts]# echo $((1+1))2[root@localhost scripts]# echo $[1+1]2复制代码文件测试表达式 这些操作符号对于[[]]、[]、test的测试表达式是通用的 字符串测试操作符 字符串测试操作符的作用包括:比较两个字符串是否相同、测试字符串的长度是否为零、字符串是否为NULL等 对于字符串的测试,一定要将字符串加双引号之后再进行比较 比较符号(例如=和!=)的两端一定要有空格[root@localhost scripts]# i=2[root@localhost scripts]# i=i+8[root@localhost scripts]# echo $ii+8[root@localhost scripts]# i=2[root@localhost scripts]# let i=i+8[root@localhost scripts]# echo $i10复制代码整数二元比较操作符 在书写测试表达式时,可以使用表中的整数二元比较操作符。 =”和“! =”也可在[]中做比较使用,但在[]中使用包含“>”和“<”的符号时,需要用反斜线转义,有时不转义虽然语法不会报错,但是结果可能会不对。 也可以在[[]]中使用包含“-gt”和“-lt”的符号,但是不建议这样使用。[root@localhost scripts]# expr 2 + 24[root@localhost scripts]# expr 2+22+2[root@localhost scripts]# name=zhangsan[root@localhost scripts]# expr length $name8复制代码二元数字在(())中的比较[root@localhost scripts]# echo "7.5 2.5" | awk '{print ($1-$2)}'5复制代码逻辑操作符 测试表达式test、[]、[[]]、(())的区别总结
1.if语句基本用法 单分支结构test <测试表达式>[root@localhost ~]# test -f /tmp/xx.txt && echo 1 || echo 00[root@localhost ~]# [ -f /tmp/xx.txt ] && echo 1 || echo 00复制代码双分支结构[root@localhost ~]# [[ 2 > 1 && 3 > 2 ]] && echo 1 || echo 01复制代码多分支结构[root@localhost ~]# [ 2 > 1 -a 3 > 2 ] && echo 1 || echo 01[root@localhost ~]# [ 2 > 1 && 3 > 2 ] && echo 1 || echo 0-bash: [: 缺少 `]'0[root@localhost ~]# [ 2 -gt 1 && 3 -lt^C ] && echo 1 || echo 2复制代码2.read命令 Shell变量除了可以直接赋值或脚本传参外,还可以使用read命令从标准输入中获得 -p prompt:设置提示信息。 -t timeout:设置输入等待的时间,单位默认为秒。[root@localhost ~]# name=zhangsan[root@localhost ~]# [ -n "$name" ] && echo 1 || echo 01[root@localhost ~]# [ "abc" = "ab" ] && echo 1 || echo 00[root@localhost ~]# [ "abc" == "ab" ] && echo 1 || echo 00复制代码[root@localhost ~]# [ 2 < 1 ] && echo 1 || echo 21[root@localhost ~]# [ 2 -lt 1 ] && echo 1 || echo 22复制代码3.case语句 支持正则[root@localhost ~]# ((2>1)) && echo 1 || echo 01[root@localhost ~]# ((2==1)) && echo 1 || echo 00复制代码
您需要 登录 才可以下载或查看,没有账号?立即注册
上一篇: openssl: error while loading shared libraries: libssl.so.3: cannot ope
下一篇: Linux下alternatives命令学习总结
举报 回复 使用道具 分享