Linux Bash编程超详细语法总结

在 Linux 学习过程中,我们无可避免的会碰到一个既让人喜欢,又令人头疼的神奇的东西——bash 编程,即 shell 脚本。那么什么是 shell 脚本呢?shell 是一个命令语言解释器,而 shell 脚本则是 Linux 命令的集合,按照预设的顺序依次解释执行,来完成特定的、较复杂的系统管理任务,类似于 Windows 中的批处理文件。本文带来的是 bash 编程的基础语法讲解。

bash 编程之变量

bash 变量类别

本地变量:只对当前 shell 进程有效的变量,对其它 shell 进程无效,包当前 shell 进程的子进程

VAR_NAME=VALUE

变量赋值:向变量的存储空间保存数据

变量引用${VAR_NAME} 

"":弱引用,里面的变量会被替换'':强引用,里面的所有字符都是字面量,直接输出

环境变量:对当前 shell 进程及其子 shell 有效,对其它的 shell 进程无效

定义:export VAR_NAME=VALUE导出:export VAR_NAME撤消变量:unset VAR_NAME只读变量:readonly VAR_NAME

局部变量: 对 shell 脚本中某代码片断有效,通常用于函数本地

local VAR_NAME=VALUE

位置变量用来接受变量指定位置的参数

$1,$2...,${10}

特殊变量shell 对一些参数做特殊处理,这些参数只能被引用而不能被赋值

$#  传递到脚本的参数个数$*  显示所有向脚本传递的参数                  #与位置变量不同,此选项参数可超过 9 个$$  获取当前 shell 的进程号$!  执行上一个指令的进程号$?  获取执行的上一个指令的返回值              #0 为执行成功,非零为执行失败$-  显示 shell 使用的当前选项,与set命令功能相同$@  与$*相同,但是使用时加引号,并在引号中返回每个参数

查看变量:

set:查看当前 shell 进程中的所有变量export, printenv, env:查看当前 shell 进程中的所有环境变量

变量命名:

  • 1、不能使用程序中的关键字(保留字)
  • 2、只能使用数字、字母和下划线,且不能以数字开头
  • 3、要见名知义

 

变量类型:

数值型:精确数值(整数),近似数值(浮点型)字符型:char,string布尔型:true, false

类型转换:

显式转换隐式转换

bash 的配置文件:

功能:设定本地变量,定义命令别名

  • profile 类:为交互式登录的用户提供配置
全局:/etc/profile、/etc/profile.d/*.sh用户:~/.bash_profile
  • bashrc 类:为非交互式的用户提供配置
全局:/etc/bashrc用户:~/.bashrc

bash 编程之编写格式及执行方式

  • 编写格式:shell 脚本第一行必须顶格写,用 shebang 定义指定的解释器来解释该脚本。
#!/bin/bash       #!即为 shebang# 其它的以#开头的行均为注释,会被解释器忽略,可用来注释脚本用途及版本,方便使用管理。
  • 执行方式:bash 编程属于面向过程编程,执行方式如下:
顺序执行:按命令先后顺寻依次执行选择执行:测试条件,可能会多个测试条件,某条件满足时,则执行对应的分支循环执行:将同一段代码反复执行多次,因此,循环必须有退出条件;否则,则陷入死循环
  • bash 执行选项:

bash -n SHELLNAME  #语法测试,测试是否存在语法错误bash -x SHELLNAME  #模拟单步执行,显示每一步执行过程

bash 之算数运算与逻辑运算

  • 算数运算

定义整型变量:

let VAR_NAME=INTEGER_VALUE            #例如:let a=3declare -i VAR_NAME=INTEGER_VALUE     #declare -i a=3

实现算术运算的方式:

let VAR_NAME=ARITHMATIC_EXPRESSIONVAR_NAME=$[ARITHMATIC_EXRESSION]VAR_NAME=$((EXPRESSION))VAR_NAME=$(expr $num1 + $num2)

算术运算符:

+:加法-:减法*:乘法/:整除%:取余数**:乘幂
注意:即使没有定义为整型变量,字符型的数字依然可以参与算术运算,bash 会执行变量类型的隐式类型转换。
  • 逻辑运算
布尔运算:真,假与运算:真 && 真 = 真        真 && 假 = 假        假 && 真 = 假        假 && 假 = 假或运算:真 || 真 = 真|| 假 = 真|| 真 = 真|| 假 = 假非运算:!真=假        !假=真

bash 编程之条件测试语句

bash 条件测试

整型测试:整数比较

例如 [ $num1 -gt $num2 ]
-gt: 大于则为真-lt: 小于则为真-ge: 大于等于则为真-le: 小于等于则为真-eq: 等于则为真-ne: 不等于则为真

字符测试:字符串比较

 

双目:例如[[ "$str1" > "$str2" ]]
>: 大于则为真<: 小于则为真>=:大于等于则为真<=:小于等于则为真==:等于则为真!=:不等于则为真

单目:-n String: 是否不空,不空则为真,空则为假-z String: 是否为空,空则为真,不空则假
文件测试:判断文件的存在性及属性等
-a FILE:存在则为真;否则则为假;-e FILE: 存在则为真;否则则为假;-f FILE: 存在并且为普通文件,则为真;否则为假;-d FILE: 存在并且为目录文件,则为真;否则为假;-L/-h FILE: 存在并且为符号链接文件,则为真;否则为假;-b: 存在并且为块设备,则为真;否则为假;-c: 存在并且为字符设备,则为真;否则为假-S: 存在并且为套接字文件,则为真;否则为假-p: 存在并且为命名管道,则为真;否则为假-s FILE: 存在并且为非空文件则为值,否则为假;-r FILE:文件可读为真,否则为假-w FILE:文件可写为真,否则为假-x FILE:文件可执行为真,否则为假file1 -nt file2: file1 的 mtime 新于 file2 则为真,否则为假;file1 -ot file2:file1 的 mtime 旧于 file2 则为真,否则为假;
组合条件测试:在多个条件间实现逻辑运算
与:[ condition1 -a condition2 ]  condition1 && condition2或:[ condition1 -o condition2 ]  condition1 || condition2非:[ -not condition ]  ! condition与:COMMAND1 && COMMAND2COMMAND1 如果为假,则 COMMAND2 不执行或:COMMAND1 || COMMAND2COMMAND1 如果为真,则 COMMAND2 不执行非:! COMMAND

条件测试之 if 语句

 

1、if语句之单分支语句结构:if 测试条件;then   选择分支fi表示条件测试状态返回值为值,则执行选择分支例:写一个脚本,接受一个参数,这个参数是用户名;如果此用户不存在,则创建该用户;
#!/bin/bashif ! id $1 &> /dev/null;then  useradd $1fi
2、if语句之双分支语句结构:if 测试条件;then   选择分支 1else   选择分支 2fi
两个分支仅执行其中之一例:通过命令行给定一个文件路径,而后判断:如果此文件中存在空白行,则显示其空白行的总数;否则,则显示无空白行;#!/bin/bashif grep "^[[:space]]*$" $1 &> /dev/null; then  echo "$1 has $(grep "^[[:space]]*$" $1 | wc -l) blank lines."else  echo "No blank lines"fi
注意:如果把命令执行成功与否当作条件,则if语句后必须只跟命令本身,而不能引用。
3、if语句之多分支语句结构:if 条件 1;then     分支 1elif 条件 2;then     分支 2elif 条件 3;then     分支 3      ...else     分支 nfi
例:传递一个用户名给脚本:如果此用户的 id 号为 0,则显示说这是管理员;如果此用户的 id 号大于等于 500,则显示说这是普通用户;否则,则说这是系统用户。#!/bin/bashif [ $# -lt 1 ]; then  echo "Usage: `basename $0` username"  exit 1fiif ! id -u $1 &> /dev/null; then  echo "Usage: `basename $0` username"  echo "No this user $1."  exit 2fi
if [ $(id -u $1) -eq 0 ]; then  echo "Admin"elif [ $(id -u $1) -ge 500 ]; then  echo "Common user."else  echo "System user."fi

bash 交互式编程

read [option] “prompt”-p:直接指定一个变量接受参数-t timaout:指定等待接受参数的时间-n:表示不换行
例:输入用户名,可返回其 shell
#!/bin/bashread -p "Plz input a username: " userNameif id $userName &> /dev/null; then    echo "The shell of $userName is `grep "^$userName>" /etc/passwd | cut -d: -f7`."else    echo "No such user. stupid."fi    

条件测试之 case 语句

case语句:有多个测试条件时,case语句会使得语法结构更明晰语句结构:
case 变量引用 inPATTERN1)  分支 1;;PATTERN2)  分支 2;;...*)  分支 n;;esac

PATTERN:类同于文件名通配机制,但支持使用|表示或者

 a|b:  a 或者 b*:匹配任意长度的任意字符?: 匹配任意单个字符[]: 指定范围内的任意单个字符
例:写一个脚本,完成如下任务,其使用形式如下所示:script.sh {start|stop|restart|status}
其中:如果参数为空,则显示帮助信息,并退出脚本;如果参数为 start,则创建空文件/var/lock/subsys/script,并显示“starting script successfully.”如果参数为 stop,则删除文件/var/lock/subsys/script,并显示“Stop script successfully.”如果参数为 restart,则删除文件/var/locksubsys/script 并重新创建,而后显示“Restarting script successfully.”如果参数为 status,那么:如果文件/var/lock/subsys/script 存在,则显示“Script is running…”,否则,则显示“Script is stopped.”
#!/bin/bashfile='/var/lock/subsys/script'case $1 instart)  if [ -f $file ];then  echo "Script is running..."    exit 3  else  touch $file  [ $? -eq 0 ] && echo "Starting script successfully."  fi  ;;stop)  if [ -f $file ];then  rm -rf $file  [ $? -eq 0 ] && echo "Stop script successfully."  else  echo "Script is stopped..."  exit 4  fi  ;;restart)  if [ -f $file ];then  rm -rf $file  [ $? -eq 0 ] && echo "Stop script successfully"  else   echo "Script is stopped..."  exit 5  fi  touch $file  [ $? -eq 0 ] && echo "Starting script successfully"  ;;status)  if [ -f $file ];then  echo "Script is running..."  else  echo "Script is stopped."  fi  ;;*)  echo "`basename $0` {start|stop|restart|status}"  exit 2  ;; esac

bash 编程之循环语句

循环之 for 循环

1、for语句格式一语句结构:for 变量名 in 列表; do    循环体done列表:可包含一个或多个元素循环体:依赖于调用变量来实现其变化循环可嵌套退出条件:遍历元素列表结束例:求 100 以内所有正整数之和
#!/bin/bashdeclare -i sum=0for i in {1..100}; do    let sum+=$idoneecho $sum
2、for语句格式二for ((初始条件;测试条件;修改表达式)); do      循环体done先用初始条件和测试条件做判断,如果符合测试条件则执行循环体,再修改表达式,否则直接跳出循环。
例:求 100 以内所有正整数之和(for二实现)#!/bin/bashdeclare -i sum=0for ((counter=1;$counter <= 100; counter++)); do  let sum+=$counterdoneecho $sum

循环之 while 语句

while 适用于循环次数未知,或不便用 for 直接生成较大的列表时

语句结构:while 测试条件; do  循环体done测试条件为真,进入循环;测试条件为假,退出循环例 1:求 100 以内所有偶数之和,要求使用取模方法#!/bin/bashdeclare -i counter=1declare -i sum=0while [ $counter -le 100 ]; do  if [ $[$counter%2] -eq 0 ]; then     let sum+=$counter  fi  let counter++ doneecho $sum
例 2:提示用户输入一个用户名,如果用户存在,就显示用户的 ID 号和 shell;否则显示用户不存在;显示完成之后不退出,再次重复前面的操作,直到用户输入 q 或 quit 为止#!/bin/bashread -p "Plz enter a username: " userNamewhile [ "$userName" != 'q' -a "$userName" != 'quit' ]; do  if id $userName &> /dev/null; then     grep "^$userName>" /etc/passwd | cut -d: -f3,7  else    echo "No such user."  firead -p "Plz enter a username again: " userNamedone
while特殊用法:遍历文本文件语句结构:while read 变量名; do  循环体done < /path/to/somefile变量名,每循环一次,记忆了文件中一行文本
例:显示 ID 号为偶数,且 ID 号同 GID 的用户的用户名、ID 和 SHELLwhile read line; do  userID=`echo $line | cut -d: -f3`  groupID=`echo $line | cut -d: -f4`  if [ $[$userID%2] -eq 0 -a $userID -eq $groupID ]; then     echo $line | cut -d: -f1,3,7  fidone < /etc/passwd

循环之 until 语句

语句结构:until 测试条件; do      循环体done测试条件为假,进入循环;测试条件为真,退出循环
例:求 100 以内所有偶数之和,要求使用取模方法(until 实现)
#!/bin/bashdeclare -i counter=1declare -i sum=0until [ $counter -gt 100 ]; do  if [ $[$counter%2] -eq 0 ]; then     let sum+=$counter  fi  let counter++doneecho $sum例:提示用户输入一个用户名,如果用户存在,就显示用户的 ID 号和 shell;否则显示用户不存在;显示完成之后不退出,再次重复前面的操作,直到用户输入 q 或 quit 为止(until 实现)

#!/bin/bashread -p "Plz enter a username: " userNameuntil [ "$userName" = 'q' -a "$userName" = 'quit' ]; do  if id $userName &> /dev/null; then   grep "^$userName>" /etc/passwd | cut -d: -f3,7elseecho "No such user."firead -p "Plz enter a username again: " userNamedone

循环之循环控制和 shift

循环控制命令:break:提前退出循环break [N]: 退出 N 层循环;N 省略时表示退出break语句所在的循环continue: 提前结束本轮循环,而直接进入下轮循环continue [N]:提前第 N 层的循环的本轮循环,而直接进入下轮循环

死循环:

#while 体 while true; do      循环体done#until 体until false; do      循环体done
例 1:写一个脚本,判断给定的用户是否登录了当前系统(1) 如果登录了,则脚本终止;(2) 每 5 秒种,查看一次用户是否登录;#!/bin/bashwhile true; do    who | grep "gentoo" &> /dev/null    if [ $? -eq 0 ];thenbreak    fi    sleep 5doneecho "gentoo is logged."

shift:

如果没有数字,只有shift 就是跳过一个参数获取下一个参数,如果加上数字,比如shift 2 ,跳过两个参数获取下一个参数。例:写一个脚本,使用形式如下所示    showifinfo.sh [-i INTERFACE|-a] [-v]要求:1、-i 或-a 不可同时使用,-i 用于指定特定网卡接口,-a 用于指定所有接口显示接口的 ip 地址2、使用-v,则表示显示详细信息,显示接口的 ip 地址、子网掩码、广播地址;3、默认表示仅使用-a 选项;
#!/bin/bashallinterface=0ifflag=0verbose=0interface=0if [ $# -eq 0 ];then  ifconfig | grep "inet addr:" | awk '{print $2}'fiwhile [ $# -ge 1 ];do  case $1 in -a) allinterface=1 shift 1  ;;-i)  ifflag=1  interface=$2  shift 2  ;;-v)  verbose=1  shift 1  ;;  *)echo "error option"exit 2  ;;  esacdoneif [ $allinterface -eq 1 ];then  if [ $ifflag -eq 1 ];then   echo "command not found"    exit 5  fi  if [ $verbose -eq 1 ];then    ifconfig | grep "inet addr:"  else    ifconfig | grep "inet addr:" | awk '{print $2}'  fifiif [ $ifflag -eq 1 ];then  if [ $allinterface -eq 1 ];then        echo "command not found"        exit 5  fi if [ $verbose -eq 1 ];then    ifconfig $interface | grep "inet addr:"  else    ifconfig $interface | grep "inet addr:" | awk '{print $2}'  fifi

bash 编程之函数

语法结构:

function F_NAME {       函数体  }
  F_NAME() {    函数体  }

可调用:使用函数名,函数名出现的地方,会被自动替换为函数

函数的返回值:

函数的执行结果返回值:代码的输出

函数中使用打印语句:echo, printf

函数中调用的系统命令执行后返回的结果

执行状态返回值:

默认取决于函数体执行的最后一个命令状态结果

自定义退出状态码:return [0-255]

注意:函数体运行时,一旦遇到 return 语句,函数即返回;

函数可以接受参数:

在函数体中调用函数参数的方式同脚本中调用脚本参数的方式:

 

位置参数$1, $2, …$#, $*, $@

例:写一个脚本,完成如下功能(使用函数):

1、提示用户输入一个可执行命令;

2、获取这个命令所依赖的所有库文件(使用 ldd 命令);

3、复制命令至/mnt/sysroot/对应的目录中

解释:假设,如果复制的是 cat 命令,其可执行程序的路径是/bin/cat,那么就要将/bin/cat 复到/mnt/sysroot/bin/目录中,如果复制的是 useradd 命令,而 useradd 的可执行文件路径为/usr/sbin/useradd,那么就要将其复制到/mnt/sysroot/usr/sbin/目录中;

4、复制各库文件至/mnt/sysroot/对应的目录中;

 

#!/bin/bashtarget=/mnt/sysroot/[ -d $target ] || mkdir $targetpreCommand() {    if which $1 &> /dev/null; then  commandPath=`which --skip-alias $1`  return 0    else  echo "No such command."  return 1    fi}
commandCopy() {    commandDir=`dirname $1`    [ -d ${target}${commandDir} ] || mkdir -p ${target}${commandDir}    [ -f ${target}${commandPath} ] || cp $1 ${target}${commandDir}}
libCopy() {    for lib in `ldd $1 | egrep -o "/[^[:space:]]+"`; dolibDir=`dirname $lib`[ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}[ -f ${target}${lib} ] || cp $lib ${target}${libDir}    done} read -p "Plz enter a command: " command
until [ "$command" == 'quit' ]; do
  if preCommand $command &> /dev/null; then    commandCopy $commandPath    libCopy $commandPath  fi
  read -p "Plz enter a command: " commanddone

bash 编程之信号捕捉

trap 命令用于在 shell 程序中捕捉到信号,之后可以有三种反应方式:

  • (1)执行一段程序来处理这一信号
  • (2)接受信号的默认操作
  • (3)忽视这一信号

trap 对上面三种方式提供了三种基本形式:

第一种形式的 trap 命令在 shell 接收到 signal list 清单中数值相同的信号时,将执行双引号中的命令串。

trap 'commands' signal-listtrap "commands" signal-list

第二种形式的 trap 命令恢复信号的默认操作:

trap signal-list

第三种形式的 trap 命令允许忽视信号:

trap " " signal-listtrap 'COMMAND' SIGINT(表示关闭进程)

例:写一个脚本,能够 ping 探测指定网络内的所有主机是否在线,当没有执行完时可接收 ctrl+c 命令退出。

#!/bin/bashquitScript() {   echo "Quit..."}    trap 'quitScript; exit 5' SIGINT
cnetPing() {  for i in {1..254}; do    if ping -c 1 -W 1 $1.$i &> /dev/null; then      echo "$1.$i is up."     else      echo "$1.$i is down."    fi    done}
bnetPing() {  for j in {0..255}; do    cnetPing $1.$j   done}anetPing() {for m in {0..255}; dobnetPing $1.$mdone}
netType=`echo $1 | cut -d"." -f1`
if [ $netType -ge 1 -a $netType -le 126 ]; thenanetPing $netTypeelif [ $netType -ge 128 -a $netType -le 191 ]; thenbnetPing $(echo $1 | cut -d'.' -f1,2)elif [ $netType -ge 192 -a $netType -le 223 ]; thencnetPing $(echo $1 | cut -d'.' -f1-3)elseecho "Wrong"exit 2fi

bash 编程之数组

数组连续的多个独立内存空间,每个内存空间相当于一个变量

数组元素数组名+索引(从 0 开始编号)

索引的表示方式a[0], a[1]

声明数组

declare -a ARRAR_NAME

关联数组

declare -A ARRAY_NAME

支持稀疏格式:仅一维数组  

数组元素的赋值:

(1) 一次只赋值一个元素

a[0]=$RANDOM

(2) 一次赋值全部元素

a=(red blue yellow green)

(3) 指定索引进行赋值

a=([0]=green [3]=red [2]=blue [6]=yellow)

(4) 用户输入

read -a ARRAY

数组的访问:

用索引访问:

ARRAY[index]

数组的长度:

${#ARRAY[*]}${#ARRAY[@]}

例:写一个脚本,生成 10 个随机数,保存至数组中;而后显示数组下标为偶数的元素

#!/bin/bashfor i in {0..9}; do    rand[$i]=$RANDOM    [ $[$i%2] -eq 0 ] && echo "$i:${rand[$i]}"done

从数组中挑选某元素:

${ARRAY[@]:offset:number}

切片:

offset: 偏移的元素个数number: 取出的元素的个数${ARRAY[@]:offset}:取出偏移量后的所有元素${ARRAY[@]}: 取出所有元素

数组复制:要使用${ARRAY[@]}

$@: 每个参数是一个独立的串$*: 所有参数是一个串

向数组中追加元素:非稀疏格式

week, week[${#week[@]}]

从数组中删除元素:

unset ARRAY[index]

例:复制一个数组中下标为偶数的元素至一个新数组中

#!/bin/bashdeclare -a mylogslogs=(/var/log/*.log)echo ${logs[@]}for i in `seq 0 ${#logs[@]}`; do  if [ $[$i%2] -eq 0 ];then    index=${#mylogs[@]}     mylogs[$index]=${logs[$i]}  fidoneecho ${mylogs[@]}

例 2:生成 10 个随机数,升序排序

#!/bin/bashfor((i=0;i<10;i++))do  rnd[$i]=$RANDOMdoneecho -e "total=${#rnd[@]}n${rnd[@]}nBegin to sort"for((i=9;i>=1;i--))do        for((j=0;j<i;j++))  do  if [ ${rnd[$j]} -gt ${rnd[$[$j+1]]} ] ;then    swapValue=${rnd[$j]}    rnd[$j]=${rnd[$[$j+1]]}    rnd[$[$j+1]]=$swapValue  fi  donedoneecho ${rnd[@]}

例 3:打印九九乘法表

#!/bin/bashfor((i=1;i<=9;i++))do strLine=""  for((j=1;i<=9;j++))  do    strLine=$strLine"$i*$j="$[$i*$j]"t"    [ $i -eq $j ] && echo -e $strLine && break  donedone

bash 编程之字符串操作

字符串切片:

${string:offset:length}[root@scholar scripts]# string='hello word'[root@scholar scripts]# echo ${string:2:4}llo
取尾部的指定个数的字符:${string: -length}[root@scholar scripts]# echo ${string-2}rd

取子串:基于模式

  • ${variable#*word}:在 variable 中存储字串上,自左而右,查找第一次出现 word,删除字符开始至此 word 处的所有内容;
  • ${variable##*word}:在 variable 中存储字串上,自左而右,查找最后一次出现 word,删除字符开始至此 word 处的所有内容;
file='/var/log/messages'${file#*/}: 返回的结果是 var/log/messages${file##*/}: 返回 messages
  • ${variable%word*}: 在 variable 中存储字串上,自右而左,查找第一次出现 word,删除此 word 处至字串尾部的所有内容;

  • ${variable%%world*}:在 variable 中存储字串上,自右而左,查找最后一次出现 word,删除此 word 处至字串尾部的所有内容;
file='/var/log/messages'${file%*/}: 返回的结果是/var/log${file%%*/}: 返回结果为空
例:url="http://www.redhat.com:80"取端口:${url##*:}取协议:${url%%:*}

查找替换:

${variable/pattern/substi}: 替换第一次出现

#userinfo=`tail -1 /etc/passwd#echo $userinfoscholar:x:500:500:scholar:/home/scholar:/bin/bash#echo ${userinfo/scholar/redhat}redhat:x:500:500:scholar:/home/scholar:/bin/bash

${variable//pattern/substi}:替换所有的出现

#echo ${userinfo//scholar/redhat}redhat:x:500:500:redhat:/home/redhat:/bin/bash

${variable/#pattern/substi}:替换行首被 pattern 匹配到的内容

#echo ${userinfo/#scholar/redhat}redhat:x:500:500:scholar:/home/scholar:/bin/bash

${variable/%pattern/substi}:替换行尾被 pattern 匹配到的内容

#echo ${userinfo/%bash/redhat}scholar:x:500:500:scholar:/home/scholar:/bin/redhat

pattern 可以使用 globbing 中的元字符:* ?

查找删除:

${variable/pattern}:删除第一次出现

#echo ${userinfo/scholar}:x:500:500:scholar:/home/scholar:/bin/bash

${variable//pattern}:删除所有的出现

#echo ${userinfo//scholar}:x:500:500::/home/:/bin/bash

${variable/#pattern}:删除行首被 pattern 匹配到的内容

#echo ${userinfo/#scholar}:x:500:500:scholar:/home/scholar:/bin/bash

${variable/%pattern}:删除行尾被 pattern 匹配到的内容

#echo ${userinfo/%bash}scholar:x:500:500:scholar:/home/scholar:/bin/

大小写转换:

小–>大:${variable^^}

#echo ${userinfo^^}SCHOLAR:X:500:500:SCHOLAR:/HOME/SCHOLAR:/BIN/BASH

大–>小:${variable,,}

#name="SCHOLAR"#echo ${name,,}scholar

变量赋值操作:

${variable:-string}:variable 为空或未设定,那么返回 string,否则,返回 variable 变量的值;

${variable:=string}:variable 为空或未设定,则返回 string,且将 string 赋值给变量 variable,否则,返回 variable 的值;

为脚本使用配置文件,并确保某变量有可用值的方式

variable=${variable:-default vaule}

写个脚本,配置 etc 目录;

(1) 在配置文件中定义变量;

(2) 在脚本中 source 配置文件;

#!/bin/bash[ -f /etc/sysconfig/network ] && source /etc/network/network[-z "$HOSTAME" -o "$HOSTNAME" = '(none)' ] || HOSTNAME ='localhost'/bin/hostname $HOSTNAME/bin/hostname

mktemp 命令:

mktemp [OPTIONS] filename.XXX

-d: 创建临时目录--tmpdir=/path/to/somewhere :指定临时文件所在的目录
mktemp /tmp/tmp.XXX                    #XXX 生成相同数量随机字符mktemp --tmpdir=/var/tmp tmp.XXX       #指定目录创建临时文件mktemp --tmpdir=/var/tmp -d tmp.XXX    #指定目录创建临时目录

install 命令:

install [OPTIONS] SOURCE DEST

install [OPTIONS] SOURCE… DIR

install [OPTIONS] -d DIR …

 

增强型的复制命令:-o OWNER-g GROUP-m MODE-d : 创建目录
install /etc/fstab /tmp                 #复制文件到指定目录install --mode=644 /etc/fstab /tmp/     #复制时指定权限install --owner=scholar /etc/fstab /tmp #复制时指定属主install --group=scholar /etc/fstab /tmp #复制时指定属组install -d /tmp/install                 #创建目录

 

© 版权声明

☆ END ☆
喜欢就点个赞吧
点赞0 分享
图片正在生成中,请稍后...