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-namechmod 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_HOMEPANHOME,在变量使用时使用{}将变量括起或"${PAN_HOME}"

b.脚本中局部变量定义:存在于脚本函数(function)中的变量称为局部变量,要以local方式进行声明,使之只在本函数作用域内有效,防止变量在函数中命名与变量外部程序中变量重名造成程序异常。

6)变量合并

当某些变量或配置项要组合起来才有意义时,如文件的路径和文件名称,建议将要组合的变量合并到一起赋值给一个新的变量,这样既方便之后调用,也为以后进行修改提供了方便。

Shell特殊变量

位置变量

s-1

提示:如果希望单独获取名称或路径可以使用dirname及basename命令。

[root@pan scripts]# cat n.sh
dirname $0
basename $0
[root@pan scripts]# sh /server/scripts/n.sh
/server/scripts
n.sh

进程状态变量

s-2

$?返回值参考:

s-3

例:

[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语句,都使所有的位置参数依次向左移动一个位置,并使位置参数$#

变量子串的常用操作

常见操作如下表:

s-4

依次举例说明:

定义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特殊扩展变量

s-5

依次举例说明:
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
声明:如无特别声明本文即为原创文章仅代表个人观点,版权归《废权的博客》所有,欢迎转载,转载请保留原文链接。
THE END
分享
二维码
Shell学习笔记(一):基础知识篇
初识脚本 脚本的建立 shell脚本通常是在编译器(如vi/vim)中编写,由unix/linux命令、bash shell命令、程序结构控制语句和注释等内容组成。 1)脚本开头(第……
<<上一篇
下一篇>>
文章目录
关闭
目 录