Shell初步学习

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

打开文本编辑器(可以使用 vi/vim 命令来创建文件),新建一个文件 test.sh,扩展名为 sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用 php 写 shell 脚本,扩展名就用 php 好了

#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。

定义变量时,变量名不加美元符号,引用时直接用$引用,注意加上{}确定引用的变量
变量名的命名须遵循如下规则:
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
中间不能有空格,可以使用下划线(_)。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。

readonly 命令可以将变量定义为只读变量
使用 unset 命令可以删除变量

变量类型
运行shell时,会同时存在三种变量:

  1. 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
  2. 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
  3. shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

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

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

获取字符串长度

string="abcd"
echo ${#string} #输出 4

提取子字符串

string="runoob is a great site"
echo ${string:1:4} # 输出 unoo

查找子字符串

string="runoob is a great site"
echo `expr index "$string" io`  # 输出 4

定义数组
在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。
用下标直接获取数组元素,使用 @ 符号可以获取数组中的所有元素

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

单行注释使用#,多行可以用多个#或者定义成不调用的函数,或者使用

:<<EOF
注释内容...
注释内容...
EOF

:<<'
注释内容...
注释内容...
'

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

算术运算符

使用expr能完成表达式的求值操作。(注意使用的是反引号 ` 而不是单引号 ')

#!/bin/bash
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

关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。

布尔运算符

下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。

逻辑运算符

以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
&& 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true

字符串运算符

下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:

运算符 说明 举例
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z a ] 返 回 f a l s e 。 − n 检 测 字 符 串 长 度 是 否 不 为 0 , 不 为 0 返 回 t r u e 。 [ − n " a ] 返回 false。 -n 检测字符串长度是否不为 0,不为 0 返回 true。 [ -n " a]falsen00true[n"a" ] 返回 true。
$ 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。

read 命令一个一个词组地接收输入的参数,每个词组需要使用空格进行分隔;如果输入的词组个数大于需要的参数个数,则多出的词组将被作为整体为最后一个参数接收。
参数说明:
-p 输入提示文字
-n 输入字符长度限制(达到6位,自动结束)
-t 输入限时
-s 隐藏输入内容

将结果重定向到文件

> 			重定向输出到某个位置,替换原有文件的所有内容。
>> 			重定向追加到某个位置,在原有文件的末尾添加内容。
< 			重定向输入某个位置文件。
2> 			重定向错误输出。
2>> 		重定向错误追加输出到文件末尾。
&> 			混合输出错误的和正确的都输出。

printf命令

%s %c %d %f都是格式替代符
%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-4.2f 指格式化为小数,其中.2指保留2位小数。

#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
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

# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n" 
脚本输出: and 0

循环

for 循环
与其他编程语言类似,Shell支持for循环。
for循环一般格式为:

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done
实例:
for loop in 1 2 3 4 5
do
    echo "The value is: $loop"
done

While循环
while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:

while condition
do
    command
done
实例:
#!/bin/bash
int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done

until 循环
until 循环执行一系列命令直至条件为 true 时停止。

until condition
do
    command
done

跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。
break命令
break命令允许跳出所有循环(终止执行后面的所有循环)

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

continue
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。

case选择
Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。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

函数定义

shell中函数的定义格式如下:

[ function ] funname [()]
{
    action;
    [return int;]
}

说明:

1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
3.函数返回值在调用该函数后通过 ? 来 获 得 ( ? 来获得( ?(? 仅对其上一条指令负责,一旦函数返回后其返回值没有立即保存入参数,那么其返回值将不再能通过 $? 获得。)。调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分

参数处理

$#		传递到脚本或函数的参数个数
$*		以一个单字符串显示所有向脚本传递的参数
$$		脚本运行的当前进程ID号
$!		后台运行的最后一个进程的ID号
$@		与$*相同,但是使用时加引号,并在引号中返回每个参数。
$-		显示Shell使用的当前选项,与set命令功能相同。
$?		显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

当n>=10时,需要使用${n}来获取参数。

输入\输出重定向

	命令					说明
command > file		将输出重定向到 file。
command < file		将输入重定向到 file。
command >> file		将输出以追加的方式重定向到 file。
n > file			将文件描述符为 n 的文件重定向到 file。
n >> file			将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m				将输出文件 m 和 n 合并。
n <& m				将输入文件 m 和 n 合并。
<< tag				将开始标记 tag 和结束标记 tag 之间的内容作为输入。

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;将命令的输出重定向到它,会起到"禁止输出"的效果。比如:
如果希望屏蔽 stdout 和 stderr,可以这样写:

$ command > /dev/null 2>&1

运行一个shell脚本

sh  test.sh
.  test.sh
source test.sh

写入文本内容;
sed 的一些命令
sed的一些命令2

在每行的头添加字符,比如"HEAD",命令如下:
sed 's/^/HEAD&/g' test.file

在每行的行尾添加字符,比如“TAIL”,命令如下:
sed 's/$/&TAIL/g' test.file

1."^"代表行首,"$"代表行尾
2.'s/$/&TAIL/g'中的字符g代表每行出现的字符全部替换,如果想在特定字符处添加,g就有用了,否则只会替换每行第一个,而不继续往后找了
例子:
$ sed '/^server.*$/s//& test/g' sheet  :如果文件这样也可的,因为 /^server/ 限定了 只是行头是server 才在行尾插入字符
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值