Shell学习笔记(一):基础知识篇
初识脚本
脚本的建立
shell脚本通常是在编译器(如vi/vim)中编写,由unix/linux命令、bash shell命令、程序结构控制语句和注释等内容组成。
1)脚本开头(第一行)
一个规范的shell脚本的第一行会指出由那个程序(解释器)来执行脚本中的内容,在linux bash编程中一般为;
#!/bin/bash
或
#!/bin/sh
"#!
"又称为幻数,在执行bash脚本的时候,内核会根据它来确定该用那个程序来解释脚本内容。这一行必须在脚本顶端的第一行,如果不是第一行则为注释。
2)sh和bash的区别
[root@pan ~]# ll /bin/sh
lrwxrwxrwx. 1 root root 4 Jun 5 03:39 /bin/sh -> bash
提示:sh为bash的软链接,这里推荐用标准写法#!/bin/bash
下面是linux中常用脚本语言开头的编码写法,不同语言脚本的开头一般都要加上如下相应语言的开头标识内容。
1、#!/bin/sh
2、#!/bin/bash
3、#!/usr/bin/awk
4、#!/bin/sed
5、#!usr/bin/tcl
6、#!/usr/bin/expect
7、#!/usr/bin/perl
8、#!/usr/bin/env python
3)脚本注释
在shell脚本中,跟在(#)井号后面的内容表示注释,用来对脚本进行注释说明,注释部分不会被执行,仅仅是给人看的注释可自成一行,也可以跟在脚本命令后面与命令在同一行。我们在写脚本的时候要养成写注释的好习惯!
shell脚本的执行
当shell脚本以非交互方式运行时,它会查找环境变量ENV,该变量指定了一个环境文件(通常是.bashrc),然后从该环境变量文件开始执行,当读取了ENV文件后,shell才开始执行shell脚本的内容。shell脚本的执行通常可以采用以下三种方式:
1)bash script-name或 sh script-name(推荐使用)
2)path/script-name或 ./script-name(当前路径下执行脚本)
3)source script-name或 . script-name #注意 "." 点号
执行说明:
第一种方法是在当前脚本文件本身有没有可执行权限(即文件x位为 - 号)是常用使用的方法里推荐使用bash执行,或者文件开头没有指定解释器。
第二种方法需要将脚本文件的权限改为可执行(即文件加x位),具体方法:chmod script-name
或chmod 755 script-name
。然后通过脚本路径就可以直接执行脚本了。
第三种方法通常是使用source
或者 ".
"点号读入或加载指定的shell脚本文件的命令语句,而不是产生一个子shell来执行文件中的命令。注意"."和后面的脚本名直接要有空格。
shell的变量
变量类型
变量可分为两类:环境变量(全局变量)和局部变量
环境变量也可称为全局变量,可以在创建他们的shell及其派生出来的任意子进程shell中使用。局部变量只能在创建他们的shell函数或脚本中使用。还有一些变量是用户创建的,其它的则是专用shell变量。
环境变量
环境变量用于定义shell的运行环境,保证shell命令的正确执行,shell通过环境变量来确定登陆用户名、命令路径、终端类型、登陆目录等,所有的环境变量都是系统全局变量,可用于所有子进程中,这包括编辑器、shell脚本和各类应用。
环境变量可以在命令行中设置,但用户退出时这些变量值也会丢失,因此最好在用户家目录下的.bash_profile
文件中或全局配置/etc/profile
文件或者/etc/profile.d/
中定义。将环境变量放入profile文件中,每次用户登录时这些变量值都将被初始化。
传统上,所有环境变量均为大写。环境变量应用与用户进程前,必须用export命令导出。
有些环境变量,比如HOME、PATH、SHELL、UID、USER等,在用户登录之前就已经被/bin/login
程序设置好了,通常环境变量定义并保存在用户家目录下的.bash_profile文件中。
自定义环境变量(全局变量)
如果想设置环境变量,就要在给变量赋值之后或设置变量时使用export命令。带-x选项的declare
内置命令也可完成同样的功能。(注意:输出变量时不要在变量名前加$
)
- export 变量名=value
- 变量名=value ;export 变量名
- declare -x 变量名=value
提示:以上为三种设置环境变量的方法
例:
export NAME=pan
declare -x NAME=pan
NAME=oldboy;export NAME
举例:(自定义全局环境变量)
[root@pan ~]# grep XWQ /etc/profile
export XWQ='pan' #编辑/etc/profile在末行输出内容并保存
[root@pan ~]# source /etc/profile #使定义的内容生效
[root@pan ~]# echo $XWQ #打印变量值
pan
[root@pan ~]# env|grep XWQ #查看定义结果
XWQ=pan
1)常见的全局环境变量的配置:
/etc/profile
/etc/bashrc #推荐在此文件中优先设置
/etc/profile.d/
若在登录后初始化或者显示加载内容,则把脚本文件放在/etc/profile.d/
下即可(无需加执行限)
2)设置登录提示的两种方式
第一种是在/etc/motd
里增加提示的字符串,如下:
[root@pan ]# cat /etc/motd
welcome to pan linux shell training.
登录后显示如下:
Last login: Tue Jun 12 14:46:50 2018 from 192.168.0.1
welcome to pan linux shell training.
第二种是在/etc/profile.d/
下面增加如下脚本
[root@pan ~]# cat /etc/profile.d/pan.sh
echo "Here is pan blog" #脚本内容
登录后显示如下:
Last login: Tue Jun 12 16:00:48 2018 from 192.168.0.1
Here is pan blog
显示与取消环境变量
1)通过echo 命令打印环境变量
$HOME
用户登录时进入的目录
$UID
当前用户的UID(用户标识)相当与id-u
$PWD
当前工作目录的绝对路径名
$SHELL
当前SHELL
$USER
当前用户
........
2)用env(printenv)或set显示默认的环境变量
3)用unset消除本地变量和环境变量
例:
[pan@pan ~]$ echo $USER
pan
[pan@pan ~]$ unset USER
[pan@pan ~]$ echo $USER
#此处输出为空
局部变量
1)定义本地变量
本地变量在用户当前的shell生存期的脚本中使用。例如,本地变量 XWQ取值为pan,这个值只要在用户当前shell生存期中有意义。如果在shell中启动另一个进程或退出,本地变量XWQ值将无效。
1.普通字符串变量定义
变量名=value
变量名='value'
变量名="value"
shell中变量名的要求:一般是字母,数字。下划线组成。
2)自定义变量建议
纯数字(不带空格),定义方式可以不加引号(单或双),例如:
PanAge=23
NETWORKING=yes
没有特殊情况,字符串一般用双引号定义,特别是多个字符串中有空格时,例如:
NFSD_MODULE="no load"
MyName="Pan is a handsome boy"
变量内容需要原样输出时,要用单引号('')
PAN_NAME='PAN'
3)变量命名规范
变量命令要统一,使用全部大写字母,如MARKDOWN_HASH14c61c762dff9204407cd959b4c7b7d1MARKDOWNHASH
;语义要清晰,能够正确表达变量内容的含义,过长的英文单词可采用前几个字符代替。多个单词连接使用“”号连接,引用时,最好以${APACHE_ERR_NUM}
加大括号或者"${APACHE_ERR_NUM}
"外面加双引号方式引用变量;
4)避免无含义字符或数字
5)全局变量和局部变量命令
a.脚本中的全局变量定义,如PAN_HOME
或PANHOME
,在变量使用时使用{}将变量括起或"${PAN_HOME}"
b.脚本中局部变量定义:存在于脚本函数(function)中的变量称为局部变量,要以local方式进行声明,使之只在本函数作用域内有效,防止变量在函数中命名与变量外部程序中变量重名造成程序异常。
6)变量合并
当某些变量或配置项要组合起来才有意义时,如文件的路径和文件名称,建议将要组合的变量合并到一起赋值给一个新的变量,这样既方便之后调用,也为以后进行修改提供了方便。
Shell特殊变量
位置变量
提示:如果希望单独获取名称或路径可以使用dirname及basename命令。
[root@pan scripts]# cat n.sh
dirname $0
basename $0
[root@pan scripts]# sh /server/scripts/n.sh
/server/scripts
n.sh
进程状态变量
$?
返回值参考:
例:
[root@pan scripts]# cat all.sh
echo '$0 获取当前执行的shell脚本的文件名:' $0
echo '$n 获取当前执行的shell脚本的第n个参数值,n=1...9:' '$1'=$1 '$2'=$2 "\ $3=$3"
echo '$* 获取当前shell的所有参数“$1 $2 $3...注意与$#的区别”:' $*
echo '$# 获取当前shell命令行中参数的总个数:' $#
echo '$$ 获取当前shell的进程号(PID):' $$
sleep 2 &
echo '$! 执行上一个指令的PID:' $!
echo '$? 获取执行的上一个指令的返回值:' $?
echo '$@ 这个程序的所有参数"$1" "$2" "$3" "..." :' $@
echo '$_ 在此之前执行的命令或脚本的最后一个参数:' $_
[root@pan scripts]# sh all.sh xwq pan xdf
$0 获取当前执行的shell脚本的文件名: all.sh
$n 获取当前执行的shell脚本的第n个参数值,n=1...9: $1=xwq $2=pan $3=xdf
$* 获取当前shell的所有参数“$1 $2 $3...注意与$#的区别”: xwq pan xdf
$# 获取当前shell命令行中参数的总个数: 3
$$ 获取当前shell的进程号(PID): 3873
$! 执行上一个指令的PID: 3874
$? 获取执行的上一个指令的返回值: 0
$@ 这个程序的所有参数"$1" "$2" "$3" "..." : xwq pan xdf
$_ 在此之前执行的命令或脚本的最后一个参数: xdf
bash内部变量
有些内部命令在目录表时是看不见的,它们由shell本身提供,常用的内部命令有:
echo,eval,exec,export,readonly,read,shift,wait,exit和点(.)
- echo 变量表名
将变量名表指定的变量显示到标准输出。
- eval args
读入参数args,并它们组合成一个新的命令,然后执行。
- exec命令参数
当shell执行到exec语句时,不会去创建新的子进程,而是转去执行指定的命令,当指令的命令执行完时,该进程(也就最初的shell)就终止了,所以shell程序中exec后面的语句将不再被执行。
- export 变量名=value
shell可以用export把它的变量向下带入子shell,从而让子进程继承父进程中的环境变量。但是shell不能用export把它的变量向上带入父shell
- readonly 变量名
只读变量 用readonly 显示所有只读变量
-
read 变量名表
从标准输入读字符串,传给指定变量。可以在函数中用local变量名的方式申明局部变量 -
shift语句
shift语句按如下方式重新命名所有的位置参数变量,即$2
成为$1
,$3
成为$2...
在程序中每使用一次shift语句,都使所有的位置参数依次向左移动一个位置,并使位置参数$#
减
变量子串的常用操作
常见操作如下表:
依次举例说明:
定义PAN 变量,内容为"I am pan"
[root@pan ~]# PAN="I am pan"
[root@pan ~]# echo ${PAN}
I am pan
1)返回字符串PAN 变量字符串的长度
[root@pan ~]# echo ${#PAN}
8
2)截取PAN变量字符串从第2个字符之后开始取,默认取后面字符的全部,第2个字符不包含在内。也可理解为删除前面的多少个字符。
[root@pan ~]# echo ${PAN:2}
am pan
3)截取PAN变量字符串从第2个字符之后开始取,取两个字符。
[root@pan ~]# echo ${PAN:2:2}
am
提示:类似cut -c参数
[root@pan ~]# echo ${PAN}|cut -c 1-4
I am
[root@pan ~]# echo ${PAN}|cut -c 3-4
am
4)从变量$PAN
开头开始删除最短匹配“I am”子串
[root@pan ~]# echo ${PAN#I am}
pan
5)从变量$PAN
开头开始删除最长匹配“I am p”
[root@pan ~]# echo ${PAN##I am p}
an
6)从变量$PAN
结尾开始删除最短匹配pan子串
[root@pan ~]# echo ${PAN%pan}
I am
7)使用etiantian字符串,来代替变量$PAN
第一匹配的pan字符串
[root@pan ~]# echo ${PAN/pan/etiantian}
I am etiantian
8)使用etiantian字符串,来代替从变量$PAN
结尾开始匹配pan字符串
[root@pan ~]# echo ${PAN/%pan/etiantian}
I am etiantian
9)使用He is 字符串,来代替从变量$PAN
开头开始匹配的 I am 字符串
[root@pan ~]# echo ${PAN/#I am/He is}
He is pan
提示:统一规律#
从开头开始,%
从结尾开始
Shell特殊扩展变量
依次举例说明:
1)${value:-word}
当变量未定义或者值为空时,返回值为word内容,否则返回变量的值。
举例:
[root@pan ~]# result=${test:-UNSET}
[root@pan ~]# echo $result
UNSET
[root@pan ~]# echo $test
#返回空值
结论:当test变量没内容时,就返回了后面的UNSET
[root@pan ~]# test='pan'
[root@pan ~]# result=${test:-UNSET}
[root@pan ~]# echo $result
pan
提示:这个变量功能可以用来判断变量是否没有定义。
结论:当test变量有内容时,就返回了test的内容
2)${value:=word}
[root@pan ~]# unset result
[root@pan ~]# echo $result
[root@pan ~]# unset test
[root@pan ~]# echo $test
[root@pan ~]# result=${test:=UNSET}
[root@pan ~]# echo $result
UNSET
[root@pan ~]# echo $test
UNSET
3)${vlaue:?message}
若变量已赋值的话,正常替换。否则将消息message送到标准错误输出(若此替换出现在shell程序中,那么该程序将终止运行)
4)${value-word}
去掉冒号
[root@pan ~]# httpd=${HTTP-/usr/sbin/httpd}
[root@pan ~]# pidfile=${PIDFILE-/var/run/httpd.pid}
[root@pan ~]# echo $httpd $pidfile
/usr/sbin/httpd /var/run/httpd.pid
[root@pan ~]# echo $HTTPD $PIDFILE
#此处输出为空
结论:变量没有定义就用-号后面的替代
作者:废权
链接:https://blog.yjscloud.com/archives/75
声明:如无特别声明本文即为原创文章仅代表个人观点,版权归《废权的博客》所有,欢迎转载,转载请保留原文链接。


共有 0 条评论