基础
只读变量
var=3readonly varreadonly var=3
- 不可修改
- 不可删除
删除变量
unset var# unset -f f1 删除f1函数
字符串
定义形式
'this is a string'"double quote string"
- 单引号字符串中无法解析转义字符和变量,双引号可以
获取字符串长度
string="hello"echo ${#string}
截取字符串
#!/bin/bash#字符串截取var=http://www.aaa.com/123.htmecho ${var#*//} #从左边开始删除第一个//及左边的字符echo ${var##*/} #从左边开始删除最后一个字符echo ${var%/*} #从右边开始删除第一个, 保留左边内容echo ${var%%/*} #从右边开始删除最后一个echo ${var:0:5} #左边开始保留字符个数echo ${var:7} #从左边第7个开始,保留到结尾的字符echo ${var:0-7:3} #从右边开始,保留的字符个数echo ${var:0-7} #从右边开始,保留到结束echo $var
查找字符串
string="runoob is a great site"echo `expr index "$string" io` # 输出 4
scope
三种作用域的变量
只能在函数内部使用的变量称为局部变量
#!/bin/bashfunc1(){local var1="str"echo $var1# "str"}func1echo $var1# ""
可以在当前会话中使用的变量称为全局变量, 一般在shell或命令行中定义的变量
在脚本中使用其它脚本文件需使用”. 文件名”或”export 文件名”, 这样其它脚本文件中的变量才会在当前进程中有效;这是因为脚本中嵌套脚本相当于开子进程运行其它脚本文件。
对当前进程和子进程有效的变量称为环境变量
export var可以将变量导出为环境变量,对当前进程和子进程都有效 注意子进程修改变量对父进程变量无效
要想变量对所有进程都有效,可以将其写入到配置文件当中,所有进程在启动时都会读取该配置文件。
环境变量
在内存中存储数据, 分为全局变量和局部变量
全局变量:
所有shell会话可见
printenv查看全部
env 查看全部
printenv HOME 查看单个变量
局部变量:
set命令查看所有的环境变量,包括局部变量,全局变量和用户定义变量
设置用户定义变量
局部变量 : 直接 var=value
有效期: 当前shell会话
全局变量:
var=value
export value
有效期: shell和shell子会话
注: 修改子shell中全局变量不会影响到父shell全局变量的值
删除环境变量
unset var
子shell中删除全局环境变量不会影响父全局变量
设置PATH环境变量
描述: 在启动shell时会加载若干个文件,这里面对环境变量的设置一直有效
查看 echo $PATH
添加: PATH=$PATH:/usr/bin
环境变量持久化,在文件中增加环境变量, 检查的启动文件与启动bash shell的方式有关
- 登录时默认shell
- 非登录shell的交互式shell
- 运行脚本的非交互式shell
登录shell
检查的文件一般有:
- /etc/profile
- $HOME/.bash_profile
- $HOME/.bashrc
- $HOME/.bash_login
- $HOME/.profile
解释: /etc/profile为每个用户登录都会执行的文件
# /etc/profile# System wide environment and startup programs, for login setup# Functions and aliases go in /etc/bashrc# It's NOT a good idea to change this file unless you know what you# are doing. It's much better to create a custom.sh shell script in# /etc/profile.d/ to make custom changes to your environment, as this# will prevent the need for merging in future updates.pathmunge () {#case语句匹配case ":${PATH}:" in*:"$1":*);;*)if [ "$2" = "after" ] ; thenPATH=$PATH:$1elsePATH=$1:$PATHfiesac}if [ -x /usr/bin/id ]; thenif [ -z "$EUID" ]; then# ksh workaroundEUID=`/usr/bin/id -u`UID=`/usr/bin/id -ru`fiUSER="`/usr/bin/id -un`"LOGNAME=$USERMAIL="/var/spool/mail/$USER"fi# Path manipulation root用户加上以下变量if [ "$EUID" = "0" ]; thenpathmunge /usr/sbinpathmunge /usr/local/sbinelsepathmunge /usr/local/sbin afterpathmunge /usr/sbin afterfiHOSTNAME=`/usr/bin/hostname 2>/dev/null`HISTSIZE=1000 #命令历史记录if [ "$HISTCONTROL" = "ignorespace" ] ; thenexport HISTCONTROL=ignorebothelseexport HISTCONTROL=ignoredupsfiexport PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL# By default, we want umask to get set. This sets it for login shell# Current threshold for system reserved uid/gids is 200# You could check uidgid reservation validity in# /usr/share/doc/setup-*/uidgid file# 设定文件权限掩码if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; thenumask 002elseumask 022fifor i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; doif [ -r "$i" ]; thenif [ "${-#*i}" != "$-" ]; then. "$i"else. "$i" >/dev/nullfifidoneunset iunset -f pathmunge
if [ “${-#i}” != “$-“ ]; 解释如下: $- 表示shell标志如himBH ${-#i} 在$-中去掉*i的最小前缀 举例 如 x=$HOME/src/cmd; echo “${x#$HOME}” #返回/src/cmd 于是该语句的含义表示当环境是在登录shell当中则执行 因为$- 为himBH
整理一下: 导出各种环境变量和设置文件权限掩码, 读取/etc/profile.d中sh文件执行
$HOME/.bash_profile
# .bash_profile# Get the aliases and functionsif [ -f ~/.bashrc ]; then. ~/.bashrc #加载.bashrc文件fi# User specific environment and startup programsPATH=$PATH:$HOME/binexport PATH
$HOME/.bashrc
# .bashrc# User specific aliases and functionsalias rm='rm -i'alias cp='cp -i'alias mv='mv -i'# Source global definitionsif [ -f /etc/bashrc ]; then. /etc/bashrcfi
总结:
- 首先系统加载/etc/profile文件, 设置基本的环境变量和加载/etc/profile.d/中的shell文件
- 系统按顺序查找$HOME/.bash_profile, $HOME/.bash_login和$HOME/.profile文件, 并执行第一个找到的文件并执行$HOME/.bashrc文件
- $HOME/.bashrc文件设置命令别名并执行/etc/bashrc文件
交互式shell进程
非登录系统启动如bash启动时该shell称为交互式shell, 交互式shell会加载$HOME/.bashrc文件
非交互式shell
执行脚本使用的shell.关键是BASH_ENV环境变量检测启动的文件
变量属性
变量属性 i r a x f
- i 声明整型变量, 可直接用于加减
- r readonly只读变量
- a 数组
- f 函数
语法:
declare [+/-][rxi][变量名称=设置值] 或declare -f
- +/- “-“设置变量的属性, “+”取消变量的属性
- -f 仅显示函数(不理解)
- r 只读变量
- x 变量成为环境变量
- i [设置值]数值, 字符串或运算式
示例:
#!/bin/bashdeclare -i abab=56echo $ab #56ab="ef"echo $ab #0declare +i abab="ef"echo $ab #efdeclare -r ab=77ab=88 # 不可修改echo $ab #77declare -a cd='([0]="a" [1]="b" [2]="c")'echo "${cd[@]}" # a b c# declare -f f1# f1=3# echo $f1declare -ff1(){echo '123'}f1f2=3echo $f2
