shell - 注释

单行注释使用:#。

多行注释:在被注释的内容端加上: <<<EOF 被注释的内容 EOF 或者 <<! 被注释的内容 !。

shell - 变量、大括号{}、小括号()

在shell脚本中,使用变量时可以不加大括号($变量名),但是最好加上(${变量名})。

示例:使用变量名

测试脚本文件test.sh内容如下:


#!/bin/bash
VAR="hello"
echo "line1: $VAR"
echo "line2: $VARlinuxbar"
echo "line3: ${VAR}"
echo "line4: ${VAR}linuxbar"
                                    

测试操作:


$ ./test.sh
line1: hello
line2:
line3: hello
line4: hellolinuxbar
                                    

line2这一行,由于变量两侧没有加大括号,导致shell认为VARlinuxbar整体是一个变量。

因为我们并没有定义这个变量,所以输出为空。

小括号用来执行一条指令。

示例:打印当前的执行路径

测试脚本文件test.sh内容如下:


#!/bin/sh
PATH=$(pwd)
echo "PATH = ${PATH}"
                                    

意思是:先执行pwd这条指令,然后把执行结果赋值给变量PATH。

测试操作:


$ ./test.sh
PATH = /home/captain/tmp
                                    

除了使用$()之外,还可以使用键盘上ESC键下面的 ` 来执行一条指令。

shell - 单引号、双引号

示例:单引号中的变量不会扩展,双引号中的变量会进行扩展。

测试脚本文件test.sh内容如下:


#!/bin/bash

NAME="www.linuxbar.net"
echo 'my name is ${NAME}'
echo "my name is ${NAME}"
                                    

测试操作:


$ ./test.sh
my name is ${NAME}
my name is www.linuxbar.net
                                    

因为第一个echo语句中,使用的是单引号,所以变量没有扩展。

shell - 命令参数传递
  • $# 命令行传入的参数个数
  • $0 所执行脚本的文件名
  • $1 命令行传入的第 1 个参数
  • $N 命令行传入的第 N 个参数
  • $$ 所执行脚本的进程号
  • $? 上一条命令的执行结果
  • $* 输出除了 $0 之外的其他所有参数
  • $@ 与 $* 相同,要加上引号

传入参数个数不足时,后面的参数内容为空。

示例:接收命令行参数

测试脚本文件test.sh内容如下:


#!/bin/bash

echo "param num is: $#"

echo "param_0 = $0"
echo "param_1 = $1"
echo "param_2 = $2"
echo "param_3 = $3"

echo "pid = $$"
echo "params = $*"
echo "params = $@"
                                    

测试操作:


$ ./test2.sh aa bb
param num is: 2
param_0 = ./test2.sh
param_1 = aa
param_2 = bb
param_3 =
pid = 31747
params = aa bb
params = aa bb
                                    

因为测试指令中只传入了2个参数,所以$3为空。

shell - 数值计算

示例:计算数字的加减乘除。

测试脚本文件test.sh内容如下:


#!/bin/bash

NUM=4

val1=`expr ${NUM} + 2`
val2=$((${NUM} + 2))
val3=$((${NUM} * 2))

echo "val1 = ${val1}"
echo "val2 = ${val2}"
echo "val3 = ${val3}"
                                    

测试操作:


$ ./test.sh
val1 = 6
val2 = 6
val3 = 8
                                    
shell - 字符串操作
  • = 检查两个字符串是否相等,相等返回真;
  • != 检查两个字符串是否相等,不相等返回真;
  • -z 检查字符串的长度是否为 0,为 0 返回真;
  • -n 检查字符串的长度是否大于 0,大于 0 返回真;
  • $ 检查字符串是否为空,不为空返回真;

示例:获取字符串的长度,提取字符串

测试脚本文件test.sh内容如下:


#!/bin/bash

NAME="linuxbar"

echo "length is: ${#NAME}"
echo "first 5 chars: ${NAME::5}"
echo "last  3 chars: ${NAME:5:3}"
                                    

测试操作:


$ ./test.sh
length is: 8
first 5 chars: linux
last  3 chars: bar
                                    
shell - if...else... 中的数字比较

if中的条件判断:

  • -eq 是否相等(equal)
  • -ne 是否不相等(not equal)
  • -lt 小于(less than)
  • -le 小于等于(less equal)
  • -gt 大于(greater than)
  • -ge 大于等于(greater eqal)

示例:数字比较

测试脚本文件test.sh内容如下


#!/bin/bash

NUM=$1

if [ ${NUM} -lt 5 ]; then
  echo "${NUM} is less than 5"
elif [ ${NUM} -eq 5 ]; then
  echo "${NUM} is equal 5"
elif [ ${NUM} -gt 5 ]; then
  echo "${NUM} is greater than 5"
fi
                                    

测试操作:


$ ./test.sh 1
1 is less than 5
$ ./test.sh 5
5 is equal 5
$ ./test.sh 8
8 is greater than 5
                                    

如果在变量两侧加上双引号也是可以的("$NUM");

但是数字字面量的两侧不要加引号;

注意:对于数字和字符串的判断是不同的,比如判断是否“相等”:

  • -eq 用于数字,不能用于字符串之间的比较;
  • = 可以用于数字,也用于字符串;
shell - if...else... 中的字符串比较

示例:比较字符串

测试脚本文件test.sh内容如下


#!/bin/bash

NAME=$1

if [ "${NAME}" = "linux" ]; then
  echo "name matched!"
else
  echo "name does not matched!"
fi
                                    

测试操作:


$ ./test.sh hello
name does not matched!
$ ./test.sh linux
name matched!
                                    
shell - if...else... 中的逻辑操作

示例:多个条件判断结果的逻辑操作

测试脚本文件test.sh内容如下:


#!/bin/bash

NUM=10
if [ ${NUM} -gt 5 ] && [ ${NUM} -lt 100 ]; then
  echo "aaa"
else
  echo "bbb"
fi

if [ ${NUM} -gt 5 ] || [ ${NUM} -gt 100 ]; then
  echo "ccc"
else
  echo "ddd"
fi
                                    

测试操作:


$ ./test.sh
aaa
ccc
                                    

可以看出:逻辑操作符&& 、 || 是放在中括号的外面的。

也可以使用双中括号的形式,此时逻辑操作符&& 、 || 就放在中括号的里面,如下:


#!/bin/bash

NUM=10
if [[ ${NUM} -gt 5 && ${NUM} -lt 100 ]]; then
  echo "aaa"
else
  echo "bbb"
fi

if [[ ${NUM} -gt 5 || ${NUM} -gt 100 ]]; then
  echo "ccc"
else
  echo "ddd"
fi
                                    
shell - 文件或目录状态

文件相关的判断条件有:

  • -f 检查某文件是否存在,且为普通文件;
  • -c 检查某文件是否存在,且为字符设备;
  • -b 检查某文件是否存在,且为块设备;
  • -z 检查某文件或目录是否存在;
  • -d 检查某文件是否为目录;
  • -r 检查某文件是否可读;
  • -w 检查某文件是否可写;
  • -x 检查某文件是否可执行;

测试脚本文件test.sh内容如下:


#!/bin/sh

if [ -d /home/captain/tmp ]; then
  echo "dir exists"
  if [ -f /home/captain/tmp/test.sh ]; then
      echo "file exists"
    else
      echo "file does not exists"
    fi
else
  echo "dir does not exixt"
fi
                                    

测试操作:


$ ./test.sh
dir exists
file exists
                                    
shell - 文件操作

示例:对某个目录下的文件进行批量重命名(加上后缀)。

测试脚本文件test.sh内容如下:


#!/bin/sh

DIR=${1}
SUFFIX=${2}

for f in `ls ${DIR}`
do
  mv "${DIR}${f}" "${DIR}${f}.${SUFFIX}"
done
                                    

测试操作:


$ ls tmp/images/
t1  t2  t3  t4  t5
$
$ ./test.sh /tmp/images/ png
$
$ $ ls /tmp/images/
t1.png  t2.png  t3.png  t4.png  t5.png
                                    
shell - for 循环

在循环语句中,可以使用break和continue来控制循环操作,含义与 C 语言中的相同:

  • break: 用来结束循环语句;
  • continue: 用来跳过本次循环中的剩余指令,进入下一次循环。

示例:枚举所有字符串

测试脚本文件test.sh内容如下:


#!/bin/bash

FILE_LIST="aaa bbb ccc"
for name in ${FILE_LIST}
do
  echo "${name}"
done

echo "--------------"

for name in ${FILE_LIST}; do
  echo "${name}"
done
                                    

测试操作:


$ ./test.sh
aaa
bbb
ccc
--------------
aaa
bbb
ccc
                                    

示例:计算数字1 到 10的累加结果。

测试脚本文件test.sh内容如下:


#!/bin/bash

sum=0
for i in $(seq 10)
do
  let sum=$sum+$i
done
echo "sum = ${sum}"
                                    

测试操作:


$ ./test.sh
sum = 55
                                    

示例:另外一种for形式来计算数字累加结果:


#!/bin/bash

sum=0
for ((i=1;i<=10;i++))
do
  let sum=$sum+$i
  # sum=$[$sum+$i]    另一种写法
done
echo "sum=${sum}"
                                    

测试操作:


$ ./test.sh
sum = 55
                                    
shell - while 循环

示例:计算数字1 到 10的累加结果。

测试脚本文件test.sh内容如下:


#!/bin/bash

i=1
sum=0
#while [ ${i} -le 10 ]    也可以
while [[ ${i} -le 10 ]]
  do
  sum=$[$sum+$i]
  i=$[$i+1]
done
echo "sum=${sum}"
                                    

测试结果:


$ ./test.sh
sum=55
                                    
shell - until 循环

示例:计算数字1 到 10的累加结果。

测试脚本文件test.sh内容如下:


#!/bin/bash

i=1
sum=0
until [[ ${i} -gt 10 ]]
do
  sum=$[$sum+$i]
  i=$[$i+1]
done
echo "sum=${sum}"
                                    

测试结果:


$ ./test.sh
sum=55
                                    
shell - 函数

测试脚本文件test.sh内容如下:


#!/bin/bash

function MySum()
{
  echo "param1 = $1"
  echo "param2 = $2"
  val=$(($1 + $2))
  return ${val}
}

MySum 10 20
echo "result = $?"
                                    

测试结果:


$ ./test.sh
param1 = 10
param2 = 20
result = 30
                                    

函数的定义中,function可以省略不写。

在函数体中,函数的返回值只能是0 ~ 255。

如果函数中没有明确的return语句,那么函数中最后一条语句的执行结果就是返回值。

调用者通过$?来获取函数的返回结果。

shell - 其它常用命令

示例:获取当前所执行脚本的绝对路径:


MYDIR=$(cd $(dirname $0); pwd)
                                    

示例:输出结果重定向:


./xxxx.sh >/dev/null 2>&1
                                    

示例:获取进程的PID


ps -x | grep 程序名称 | grep -v grep | awk '{print $1}'
                                    
Card image cap
Linux 茶馆
Card image cap
物联网小镇