shell.md 8.7 KB

shell

变量

your_name="runoob"

echo ${your_name}

for file in `ls /etc`
或
for file in $(ls /etc)

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,推荐给所有变量加上花括号,这是个好的编程习惯。

使用 unset 命令可以删除变量 unset variable

for ff in week?? # week 以开头的文件
do
echo $ff

数组 my_array=(1 2 3 4 5)

单引号字符串的限制: 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的; 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

双引号的优点: 双引号里可以有变量 双引号里可以出现转义字符

拼接字符串 your_name="runoob"

使用双引号拼接

greeting="hello, "$your_name" !" greeting_1="hello, ${your_name} !" echo $greeting $greeting_1

获取字符串长度 实例 string="abcd" echo ${#string} # 输出 4

提取子字符串 以下实例从字符串第 2 个字符开始截取 4 个字符: 实例 string="runoob is a great site" echo ${string:1:4} # 输出 unoo

注释

#

shell传递参数

echo "Shell 传递参数实例!"; echo "执行的文件名:$0"; echo "第一个参数为:$1"; echo "第二个参数为:$2"; echo "第三个参数为:$3";

$ ./test.sh 1 2 3 Shell 传递参数实例! 执行的文件名:./test.sh 第一个参数为:1 第二个参数为:2 第三个参数为:3

echo "参数个数为:$#";

参数个数为:3 传递的参数作为一个字符串显示:1 2 3

$* 与 $@ 区别:

相同点:都是引用所有参数。 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。

数组

bash支持一维数组(不支持多维数组)

array_name=(value0 value1 value2 value3)

${数组名[下标]}

使用 @ 符号可以获取数组中的所有元素,例如:

echo ${array_name[@]}

my_array=(A B "C" D)

echo "第一个元素为: ${my_array[0]}" echo "第二个元素为: ${my_array[1]}" echo "第三个元素为: ${my_array[2]}" echo "第四个元素为: ${my_array[3]}"

关联数组 declare -A site=(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["taobao"]="www.taobao.com")

先声明后设置

declare -A site
site["google"]="www.google.com"
site["runoob"]="www.runoob.com"
site["taobao"]="www.taobao.com"

访问 echo ${site["runoob"]} 数组的元素为: www.google.com www.runoob.com www.taobao.com echo "数组的键为: ${!site[*]}" 数组的键为: google runoob taobao

运算符

简单的计算


a=10
b=20

val=`expr $a + $b`
echo "a + b : $val"

val=`expr $a - $b`
echo "a - b : $val"

val=`expr $a \* $b`
echo "a * b : $val"

val=`expr $b / $a`
echo "b / a : $val"

val=`expr $b % $a`
echo "b % a : $val"

if [ $a == $b ]
then
   echo "a 等于 b"
fi
if [ $a != $b ]
then
   echo "a 不等于 b"
fi


运算符 说明 -eq equal -ne no equal -gt getter than -lt letter than -ge getter than -le less than

ex

if [ $a -eq $b ]
then
   echo " a 等于 b"

echo

显示转义字符

echo "\"It is a test\"" 结果将是: "It is a test"

换行

echo -e "OK! \n" # -e 开启转义 echo "It is a test"

不换行

echo -e "OK! \c" # -e 开启转义 \c 不换行 echo "It is a test"

定向到文件

echo "It is a test" > myfile

原样输出

单引号 echo '$name\"'

显示命令

echo `date`

printf

printf "Hello, Shell\n" 类似c语言

格式化输出

printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543 printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876

执行脚本,输出结果如下所示:

姓名 性别 体重kg 郭靖 男 66.12 杨过 男 48.65 郭芙 女 47.99

test

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

数值

num1=100
num2=100
if test $[num1] -eq $[num2]
then
    echo '两个数相等!'
else
    echo '两个数不相等!'
fi

字符串

num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
    echo '两个字符串相等!'
else
    echo '两个字符串不相等!'
fi

参数 说明 = 等于则为真 != 不相等则为真 -z 字符串 字符串的长度为零则为真 -n 字符串 字符串的长度不为零则为真

文件

文件测试 参数 说明 -e 文件名 如果文件存在则为真 -r 文件名 如果文件存在且可读则为真 -w 文件名 如果文件存在且可写则为真 -x 文件名 如果文件存在且可执行则为真 -s 文件名 如果文件存在且至少有一个字符则为真 -d 文件名 如果文件存在且为目录则为真 -f 文件名 如果文件存在且为普通文件则为真 -c 文件名 如果文件存在且为字符型特殊文件则为真 -b 文件名 如果文件存在且为块特殊文件则为真


cd /bin
if test -e ./bash
then
    echo '文件已存在!'
else
    echo '文件不存在!'
fi

流程控制

a=10
b=20
if [ $a == $b ]
then
   echo "a 等于 b"
elif [ $a -gt $b ]
then
   echo "a 大于 b"
elif [ $a -lt $b ]
then
   echo "a 小于 b"
else
   echo "没有符合的条件"
fi

函数

demoFun(){
    echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"


funWithReturn(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum 和 $anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"




函数参数

funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73


第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !





输入输出重定向

command1 > file1

command1 < file1

bug

等号两侧避免使用空格:

正确的赋值 variable_name=value 有可能会导致错误 variable_name = value

附加文档

运行 Shell 脚本有两种方法:

1、作为可执行程序

将上面的代码保存为 test.sh,并 cd 到相应目录:

chmod +x ./test.sh #使脚本具有执行权限 ./test.sh #执行脚本 注意,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找。

2、作为解释器参数

这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:

/bin/sh test.sh /bin/php test.php 这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

只读

myUrl="https://www.google.com" readonly myUrl

获取数组的长度

  1. 取得数组元素的个数 length=${#array_name[@]}
  2. 或者 length=${#array_name[*]}
  3. 取得数组单个元素的长度 length=${#array_name[n]}

灯笼哥哥

.sh ls cal date sh txt.sh a=10 echo $a echo "HELLO WORLD" $a echo HELLO WORLD 不推荐 c=expr $a + $b 空格是强制的 echo $c c=expr $a \* $b

  • - * / if[...] then else fi

if[$a > $b] then echo $a else echo $b fi

-gt greater than < -lt less than = -ge greater equal <= -le less equal = -eq equal != -ne not equal

for x in 1 2 3 4 5 6 7 8 9 10 do done

while[$ -le 10] do echo $x x=expr $x + 1 done

read 读入 echo "please enter a:" read a echo "please enter b:" read b c=expr $a + $b echo $c

password = "hello123" echo "please enter a password" read userPassword if[ $password -eq $userPassword] then echo "pass" else echo "wrong" fi

字符串拼接

$str1 = "HELLO" $str2 = "WORLD" $str3 = "$str1 $str2" if[-z $str1] 长度为0的字符串 -n 不为零 -z 为0 then echo "str1 is empty" else echo "str1 is not empty" fi

含str的用bash 不用sh sh text.sh bash text.sh