linux shell基本语法

引用教程

菜鸟教程
https://www.runoob.com/linux/linux-shell.html

https://github.com/bobbyiliev/introduction-to-bash-scripting


1. 变量

1.1 定义和使用

  • 定义:由英文字母,数字和下划线组成,且首个字符不能是数字。例如:var
  • 使用:在变量名前加上 $ 符号,一般建议再给变量名加上 {}。
name='test' #注意等号两边不要留空格
echo $name 
echo ${name}
ehco $name+$name

好的编程习惯:
1. 变量名用{}括起来
  echo ${name}

2. 变量的取值应该放到双引号中。
  VAR=abc
  [ -d Desktop -a "$VAR" = 'abc' ]
  echo $?
  0

   

1.2 分类

环境变量: 环境变量可以从父进程传给子进程,因此 Shell 进程的环境变量可以从当前 Shell 进程传给 fork
出来的子进程。用 printenv 命令可以显示当前 Shell 进程的环境变量。

本地变量:只存在于当前 Shell 进程,用 set 命令可以显示当前 Shell 进程中定义的所有变量(包括本地变
量和环境变量)和函数。

局部变量:只在代码块或者函数中可见

字符串:字符串可以用单引号,也可以用双引号,也可以不用引号

数组:bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
类似于 C 语言,数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。

1. 导出为环境变量
export VARNAME=value

2. 删除变量
unset VARNAME

3. 只读变量
myUrl="http://www.google.com"
readonly myUrl

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


双引号:
    str="Hello, I know you are \"$your_name\"! \n"
    优点:
    1. 双引号里可以有变量
    2. 双引号里可以出现转义字符

拼接字符串:
your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
# 使用单引号拼接
greeting_2='hello, '$your_name' !'

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

提取子字符串
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo

-----------------------------------------------------------------------------------------
5. 数组
定义:在Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。
array_name=(value0 value1 value2)
修改:array_name[0]=value0
读取:valuen=${array_name[n]}
获取全部元素:echo ${array_name[@]}
获取数组长度:
    # 取得数组元素的个数
    length=${#array_name[@]}
    length=${#array_name[*]}

    # 取得数组单个元素的长度
    lengthn=${#array_name[n]}

遍历数组:
1. 标准for循环
for((i=0;i<${#array[@]};i++))
do
    echo ${array[i]}
done;

2. for ... in
for element in "${array[@]}"
do
    echo $element
done

for i in "${!array[@]}"
do
    printf "%s\t%s\n" "$i" "${array[$i]}"
done

3. while
i=0
while [ $i -lt ${#array[@]} ]
do
    echo ${array[$i]}
    let i++
done 

-----------------------------------------------------------------------------------------
6. 转义字符 \
\在 Shell 中被用作转义字符,用于去除紧跟其后的单个字符的特殊意义(回车
除外),换句话说,紧跟其后的字符取字面值。

echo $SHELL
/bin/bash

echo \$SHELL
$SHELL

echo \\
\

1.4 变量代换

1. 命令代换: `` 或者 $()
先执行``或者$()中的命令,再把命令结果赋值给变量

DATA=`date`
DATA=$(date)

2. 算术士换: $(()) 或者 $[]
先将变量取值转换为整数,再运算, 只能进行 +-*/和()运算符,且只能做整数运算。
$[base#n],其中 base 表示进制,n 按照 base 进制解释,后面再有运算数,按十进制解释。

VAR=10
echo $(($VAR+3))
echo $[2#10+11]

3. 文件名代换(globbing):*?[]
这些用于匹配的字符称为通配符。
* --匹配 0 个或多个任意字符
? --匹配一个任意字符
[若干字符] --匹配方括号中任意一个字符的一次出现
注:
Globbing 所匹配的文件名是由 Shell 展开的,也就是说在参数还没传给程序之前已经展
开了,比如上述 ls ch0[012].doc 命令,如果当前目录下有 ch00.doc 和 ch02.doc,则传给 ls 命
令的参数实际上是这两个文件名,而不是一个匹配字符串。

ls /dev/ttyS*
ls ch0?.doc
ls ch0[0-2].doc
ls ch[012] [0-9].doc

1.5 基本运算符 

https://www.runoob.com/linux/linux-shell-basic-operators.html

  • 算数运算符
  • 关系运算符
  • 布尔运算符
  • 字符串运算符
  • 文件测试运算符
  • 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

2.控制流程

2.1 条件语句

一般condition用 [ 或者 test的形成的条件测试语句:
    命令 test 或[可以测试一个条件是否成立,如果测试结果为真,则该命令的 Exit Status 为 0,如
果测试结果为假,则命令的 Exit Status 为 1(注意与 C 语言的逻辑表示正好相反)。

1. [ 命令
虽然看起来很奇怪,但左方括号[确实是一个命令的名字,传给命令的各参数之间应该用空格隔
开,比如, $VAR、 -gt、 3、 ]是[命令的四个参数,它们之间必须用空格隔开。

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

多个判断条件两种方式:
if [[ "aa" == "bb" && "cc" == "dd" ]]
then
    echo "fail"
fi


if [ "a" == "b" -a "c" == "d" -a "e" == "f" ]
then
    echon "test"
fi

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

num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
    echo '两个数字相等!'
else
    echo '两个数字不相等!'
fi

------------------------------------------------------------------------------
3. && 和 || 语法
&&: 相当于 "if...then..."。
||: 相当于 "if not...then.."。
用于连接两个命令。

------------------------------------------------------------------------------
4. -a, -o
用于连接两个测试条件

------------------------------------------------------------------------------
5. if语句实例
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

其实是三条命令:
if [ -f ~/.bashrc ]是第一条,
then . ~/.bashrc 是第二条,
fi 是第三条。

如果两条命令写在同一行则需要用;号隔开,一行只写一条命令就不需要写;号了,另外, then 后面有
换行,但这条命令没写完, Shell 会自动续行,把下一行接在 then 后面当作一条命令处理。和
[命令一样,要注意命令和各参数之间必须用空格隔开。 if 命令的参数组成一条子命令,如果该
子命令的 Exit Status 为 0(表示真),则执行 then 后面的子命令,如果 Exit Status 非 0(表
示假),则执行 elif、 else 或者 fi 后面的子命令。 if 后面的子命令通常是测试命令,但也可以是
其它命令。 Shell 脚本没有{}括号,所以用 fi 表示 if 语句块的结束。

2.2 循环语句

1. ############### for #####################
# 字符型
for str in 'This is a string'
do
    echo $str
done

for i in f1 f2 f3 ;  
do  
echo $i is appoint ;  
done

# 数字型
for((i=1;i<=10;i++));  
do   
echo $(expr $i \* 3 + 1);  
done

for i in $(seq 1 10)  
do   
echo $(expr $i \* 3 + 1);  
done

for i in {1..10}  
do  
echo $(expr $i \* 3 + 1);  
done

# 路径查找
for file in /proc/*;  
do  
echo $file is file path \! ;  
done

for file in $(ls *.sh)  
do  
echo $file is file path \! ;  
done

2. ##################### while ##########################
int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done

3. ################### 无限循环 ###########################
while :
do
    command
done

while true
do
    command
done

for (( ; ; ))

4. #################### until ################################
a=0
until [ ! $a -lt 10 ]
do
   echo $a
   a=`expr $a + 1`
done

5. ################# break ######################################
while :
do
    echo -n "输入 1 到 5 之间的数字:"
    read aNum
    case $aNum in
        1|2|3|4|5) echo "你输入的数字为 $aNum!"
        ;;
        *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
            break
        ;;
    esac
done

6. ################# continue#####################################
while :
do
    echo -n "输入 1 到 5 之间的数字: "
    read aNum
    case $aNum in
        1|2|3|4|5) echo "你输入的数字为 $aNum!"
        ;;
        *) echo "你输入的数字不是 1 到 5 之间的!"
            continue
            echo "游戏结束"
        ;;
    esac
done

2.3 case语句

echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
    1)  echo '你选择了 1'
    ;;
    2)  echo '你选择了 2'
    ;;
    3)  echo '你选择了 3'
    ;;
    4)  echo '你选择了 4'
    ;;
    *)  echo '你没有输入 1 到 4 之间的数字'
    ;;
esac

3.函数

3.1 定义

1. 函数体无参数使用

funWithReturn(){
    echo "just a function test"
    return 1
}
funWithReturn
echo "the function return $? !"

注:
1. 函数的返回值 在调用该函数后通过 $? 来获取。
2. 所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,
直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

2. 函数体有函数参数使用
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,
例如,$1表示第一个参数,$2表示第二个参数...

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
注意:
$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。

4. shell的输入输出

1. echo
echo 显示文本行或变量,或者把字符串输入到文件。
echo [option] string
-e 解析转义字符
-n 不回车换行。默认情况 echo 回显的内容后面跟一个回车换行。
echo "hello\n\n"
echo -e "hello\n\n"
echo "hello"
echo -n "hello

2. 管道 |
可以通过管道把一个命令的输出传递给另一个命令做输入。管道用竖线表示。
cat myfile | more
ls -l | grep "myfile"
df -k | awk '{print $1}' | grep -v "文件系统"
df -k 查看磁盘空间,找到第一列,去除“文件系统”,并输出

3. tee 
tee 命令把结果输出到标准输出,另一个副本输出到相应文件。
df -k | awk '{print $1}' | grep -v "文件系统" | tee a.txt
tee -a a.txt 表示追加操作。
df -k | awk '{print $1}' | grep -v "文件系统" | tee -a a.txt

4. 文件重定向
cmd > file 把标准输出重定向到新文件中
cmd >> file 追加
cmd < file1 > file2 输入输出都定向到文件里
cmd < &fd 把文件描述符 fd 作为标准输入
cmd > &fd 把文件描述符 fd 作为标准输出
cmd < &- 关闭标准输入

cmd > file 2>&1 标准出错也重定向到 1 所指向的 file 里
cmd >> file 2>&1

0:标准输入 stdin
1: 标准输出 stdout
2:标准错误 stderr
2>&1: 表示把标准错误重定向到标准输出。
/dev/null: 
可以看做是“黑洞”,它等价于一个只写文件,所有写入它的内容都会永远的丢失,读不到。

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null。
command > /dev/null

如果希望屏蔽 stdout 和 stderr:
command > /dev/null 2>&1

 

5. 调试方法

5.1 注释

1. 单行注释
# 这只是一个注释

2. 多行注释
:<<EOF
注释内容...
注释内容...
注释内容...
EOF

EOF 也可以使用其他符号:
:<<'
注释内容...
注释内容...
注释内容...
'

:<<!
注释内容...
注释内容...
注释内容...
!

5.2 调试

  • -n:读一遍脚本中的命令但不执行,用于检查脚本中的语法错误。
  • -v:边执行脚本,一边将执行过的脚本命令打印到标准错误输出
  • -x:提供跟踪执行信息,将执行的每一条命令和结果依次打印出来

使用这些选项有三种方法:

1. 在命令行提供参数
$ sh -x ./script.sh


2. 在脚本开头提供参数
#! /bin/sh -x

3. 在脚本中用 set 命令启用或禁用参数
#! /bin/sh
if [ -z "$1" ]; then
    set -x
    echo "ERROR: Insufficient Args."
    exit 1
    set +x
fi

set -x 和 set +x 分别表示启用和禁用-x 参数,
这样可以只对脚本中的某一段进行跟踪调试表示启用和禁用-x 参数,
这样可以只对脚本中的某一段进行跟踪调试

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值