shell简易入门指南

Posted 如何在5年薪百万

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell简易入门指南相关的知识,希望对你有一定的参考价值。

二、基础语法

2.1 变量

  1. 不能以数字开头
  2. 区分大小写
  3. 变量、等号、值不能有空格。
  4. 值的内部有空格可以用引号括起来,例如 var1=“a 2 c”
  5. #!/bin/bash指的是当前脚本通过bash命令解释和执行

shell中不加local修饰的变量都是全局变量,比如函数内部声明的变量,其他函数中也可以使用

2.2 位置变量

位置变量参数含义
$nn是数字,$0代表脚本本身,$0$9代表第19个参数。10个以上的参数用大括号包含 $10
$@接收所有参数
$*接收所有参数作为一个整体
$#参数个数

变量之间用空格分隔

#!/bin/bash

echo "The First Para:$1"
echo "The 2nd Para:$2"
echo "The 3rd Para:$3"
echo "The 4  Para:$4"
echo "The 5   Para:$5"


echo '$*='  $*
echo '$@='  $@
echo '$#='  $#

测试结果

[root@server1 shell]# sh location_var.sh  1 2 3 4 5 6 7 8 9 
The First Para:1
The 2nd Para:2
The 3rd Para:3
The 4  Para:4
The 5   Para:5
$*= 1 2 3 4 5 6 7 8 9
$@= 1 2 3 4 5 6 7 8 9
$#= 9

环境变量

linxu是一个多租户的操作系统,针对不同用户有专有的运行环境。

  1. 对所有用户生效 /etc/profile
  2. 对特定用户生效,当前用户私有环境变量,其他用户无法获取 /.bashrc或者/.bash_profile
  3. 临时有效的环境变量 使用export命令声明的临时环境变量

进阶:不同配置文件对比https://www.cnblogs.com/cwp-bg/p/8257843.html

系统默认的环境变量

环境变量含义
PATH命令搜索的路径
LOGNAME用户登录名
PWD当前所在绝对路径
HOME用户家目录
HISTFILE历史命令保存文件
HISTSIZE历史命令保存大小
SHELL用户当前使用shell类型
HOSTNAME主机名
TMOUT用户和系统交互过程超时
IFS/OFS系统输入输出分隔符

环境变量建议全部大写。掌握上面变量对于脚本书写很有帮助

[] 补充mac上几个file的用法

管道 |

  1. 将前面命令的输出作为后面命令的输入。
  2. 管道可以层层过滤
# 统计输出结果
rpm -qa | grep pyton | wc -l

# 输出结果用less打开 
rpm -qa | grep python | less

退出状态码

  1. 0~255的整数值
  2. 使用退出状态码告知shell执行完毕
  3. 通过$? 获取上一个命令的退出状态码
状态码含义
0上命令成功结束
非0上一个命令不成功

#!/bin/bash

date

if [ $? -eq 0 ];then
        echo "sucess ...."
else
        echo "faild"
fi

测试结果

[root@server1 shell]# sh exit_code.sh 
Tue Nov  2 00:21:15 CST 2021
sucess ....

Tips1 获取grep是否有结果

ps -ef | grep "/usr/bin/sshd" | grep -v grep

echo $?时,返回的不是命令本身是否执行成功,而是grep是否获取到。用于脚本书写

Tips2 如何修改退出状态码

exit 正数 改变当前脚本执行结果

# 当前脚本执行后 $?为上述指定值

三、if条件语句

if else语法

if command | condition
then
    commands
elif command | condition    
then
    commands
else
    commands
fi    

if commond

如果if命令后commond退出状态码==0时为真

#/!bin/bash
if pwd
then
        echo "It workds"
fi

&> /dev/null 将结果输出到垃圾箱,不会改版命令退出状态码,避免命令行在页面打印log

#/!bin/bash

if ps -ef | grep mysqld | grep -v grep &> /dev/null
then
        echo "mysql is running "
elif  ps -ef | grep httpd | grep -v grep
then   echo "httpd is running"
else
        echo  "mysql stoped"
fi

tips

if可以和then放在一行,中间用分号分割

#/!bin/bash
if pwd;then
    echo "It workds"
fi

条件比较

  1. command执行退出状态码==0
  2. 返回布尔值为ture

数值比较

符号含义
-eq等于
-ne不等于

字符串比较

符号含义
==等于
!=不等于
>大于 小于
-n strstr的长度不为零则true
-z strstr为zero时为true

判断字符串空或非空

#!/bin/bash
var1="tes"
if [ -n "$var1"  ];then
        echo "var1 is not null"
else
        echo " var1 is null"
fi

文件比较

语法含义
-d filefile是否为directory
-f file是否是文件
-e filefile是否exist
-r/w/xfile是否能读写执行
-s file存在且非空
file1 -nt filefile1 is newer than file2
#!/bin/bash

if [ -d /usr/local ];then
        echo "user/local is a directory"
else
        echo "user/local is not a diretory"
fi

-d 表达存在且为目录。如果不存在也会返回false。

复合条件

  • && and
  • || or
  • [] 方括号处理优先级
if [a > b] && [ b == c]
then
fi

(()) 双括号做算数运算

if ((expersion))
then
    commands
fi

双括号内

  1. value++,value–,!,==,>,<,>=
    &&,|| 等算数运算符都可以使用
  2. 运算符可以有空格,也可以没有
  3. 可用于if、for、while等循环
  4. 变量名引用可以不加$符号

[]内有诸多限制,比如&&不能下载方括号内部,只能连接方括号

#!/bin/bash

a=10
((a++))
echo "a=$a"
echo 'a=$a'


b=$1
c=$2

if (( $1 > $2 && $2 > 10)); then
        echo "$1 > $2"
else
        echo "$1 < $2"
fi

# 输出结果
[root@server1 shell]# sh double_bracket.sh 12 13
a=11
a=$a
12 < 13

[[]] 双方括号

# 单括号

if [condition1] && [conditon 2]
then

# 双括号
if [condition1 && condition2]

和单方括号相比

  1. 双括号内可以写多个表达式
  2. 可以支持类C语言运算符

和双括号相比

  1. 前后必须有空格
  2. 变量必须使用 符 号 ( 推 荐 变 量 都 是 用 符号(推荐变量都是用 符号)
#!/bin/bash

# 单方括号
if [a > b];then
        echo "yes"
else
        echo "no"
fi
# 双方括号
if [[  a > b && b <c   ]];then
        echo "yes"
else
        echo "no"
fi

其实shell不是严格语法,上面单括号的示例,单括号和变量没有空格,shell不会报错,而是把[和变量a当成一个字符,比较的实际内容是 [ab],所以不要太相信shell,通过测试来发现问题。

case用法

  1. 双份好做条件分割
    • 代表兜底逻辑
#!/bin/bash

case $1 in
        jack )
        echo "hello jack"
        ;;
        mike )
        echo "hello mike"
        ;;
        * )
        echo "every one"
        ;;
esac

测试结果

[root@server1 shell]# sh case.sh mike
hello mike
[root@server1 shell]# sh case.sh dd
every one

四、循环遍历for/while

for循环

  • var是一个变量,即当前集合中遍历的对象
  • list代表集合,可以使某个命令结果
  • 集合元素默认使用空格分割,而不是逗号
for var in list
do
    commands
done

shell中默认分隔符是空格或者tab或者/n换行符,两个都作为元素之间分割。
可以使用IFS指定默认分隔符

#!/bin/bash
# 分隔符是空格,逗号会被认为是一个字符串
for i in beijing shangai dongjing suzhu henan
do
        echo "your city is  $i"
done


for i in 1..5
do
        echo "num is $i"
done
# 指定默认分隔符
IFS=":"
list="zhangsan lisi wangwu linliu       fenge"
for j in $list
do echo $j
done

执行结果

[root@server1 shell]# sh for_01.sh 
your city is  beijing
your city is  shangai
your city is  dongjing
your city is  suzhu
your city is  henan
num is 1
num is 2
num is 3
num is 4
num is 5
zhangsan lisi wangwu linliu 	fenge

for读取命令结果值

打印当前目录下所有文件,并判断是否为文件

#!/bin/bash
i=0
for var in `ls $PWD`
do
        ((i++))
        if [ -d $var ];then
                echo "$i $var is dictory"
        else
                echo "$i $var is a file "
        fi
done

C语言风格for循环

需要模仿下面写for循环即可

#!/bin/bash

for (( i=0; i<10; i++ ))
do
        echo $i
done

可以使用 for var in 0…9替换

while循环

while condition
do 
    commands
done

break 中止内部循环

break 看到就停止内部for循环

  • 默认break 1
  • 通过break n 可以跳出N层循环

continue

跳过当前循环,进入下一个循环

#!/bin/bash

for i in 1..10
do
        if ((i==5));then
                break
        else
                echo $i
        fi
done

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

for i in 1..10
do
        if ((i==5));then
                continue
        else
                echo $i
        fi

五、函数

基础语法

# 格式1

name()
   body 


# 格式2 不需要括号
function name
    body


如何调用

  • 直接使用函数名就可以调用,可以把函数理解为一个shell命令
  • 函数诶不直接使用参数 $1 $2 … $n

如何传参

shell中不用括号传参,通过$n直接获取参数

n代表调用改函数时传入的参数位置,通过参数偏移可以改变n的位置

function name

    echo "hello $1"
    echo "hello $2"

示例

#!/bin/bash


function calcu 
        case $2 in
                +)
                        echo `expr $1 + $3`
                        ;;
                -)

                        echo `expr $1 - $3`
                        ;;
                \\\\*)
                        echo  `expr $1 \\* $3`
                        ;;
                \\/)
                        echo `expr $1 \\/ $3`
                        ;;
        esac


calcu $1 $2 $3

注意乘法的测试需要两次转义

[root@server1 shell]# sh calcu.sh 30 \\\\* 20
600

函数返回值

  • return 1~255的正数,只是供其他函数获取调用状态,0代表成功 1代表失败
  • echo 返回任何字符串或者值列表
# 返回数字代表返回执行结果状态
#!/bin/bash

#返回当前脚本的进程id,用于过滤
this_pid=$$


function is_nginx_running

        ps -ef | grep nginx | grep -v grep | grep -v $this_pid $> /dev/null

        if [ $? -eq 0 ];then
                return 0 # return default 0
        else
                return 1 # fail
        fi




is_nginx_running


# echo方式返回
#!/bin/bash

function get_sys_users


    echo `cat /etc/passwd | cut -d: -f1`



user_list=`get_sys_users`

for u in $user_list

        echo $u


局部变量和全局变量

shell变量都是全局变量,某个函数中声明的变量,也可能被访问。慎用全局变量,对全局变量要求统一规划命名。

local修饰变量时局部变量

封装函数文件库

将尝试用的函数封装函数文件

定义函数库文件

#!/bin/bash

function add

        echo `expr  $1 + $2`


function reduce

        echo `expr $1 - $2`



function multiple


        echo `expr $1 \\\\* $2`


function divide

        echo `expr $2 / $2`


使用函数库文件
使用点+空格+绝对路径

#!/bin/bash

. /root/shell/library.sh

add 33 44
~              

以上是关于shell简易入门指南的主要内容,如果未能解决你的问题,请参考以下文章

Shell编程入门

手动实现一个简易linux中shell

手动实现一个简易linux中shell

手动实现一个简易linux中shell

手动实现一个简易linux中shell

Linux实现简易的Shell命令行解释器