Linux学习笔记之<Shell编程初入门>

本文深入探讨Linux Shell编程的基础概念,包括Shell的用途、语法、变量、环境变量、条件控制、函数及命令等核心元素。通过实际示例,详细阐述了管道、重定向输出、输入、以及作为程序设计语言的特性。文章旨在为读者提供一个全面且易于理解的Shell编程入门指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

薄雾浓云愁永昼,瑞脑消金兽。
佳节又重阳,玉枕纱橱,半夜凉初透

东篱把酒黄昏后,有暗香盈袖。
莫道不消魂,帘卷西风,人比黄花瘦。

本文的参考文档主要出自《Linux程序设计》第四版第二章。
可以看做是更符合国人思路的精简版。
本文不会很长,建议全篇阅读。

什么是Shell

shell是人和linux操作系统进行交互的工具。本质上也是一个跑在linux上的程序罢了。除此之外,它还可以执行脚本文件,从文件而不是人这里获取指令。

管道和重定向

重定向输出

一个简单的例子

ls -l > `lsout`.txt

默认情况下,上面这个命令会覆盖lsout.txt
若想在文件上追加

ls -l >> lsout.txt

更多的内容:其实一个程序的输出不止一个。比如还有标准错误输出。(也许你之前没有接触到过,但是这点也很重要)

kill -HUP 1234 >killout.txt 2>killerr.txt

kill如果给一个已经结束的进程发送HUP信号,那么将会报错。
>killout.txt表示将标准输出重定向到killout.txt这个文件。
2>killerr.txt表示将标准错误输出定向到killerr.txt这个文件。
2代表的是标准错误输出。
如果将两者都输出到同一个文件,那么可以这样写

kill -HUP 1234 >killout.txt 2>&1

&1的含义是标准输出的指向。

我们也可以丢弃掉输出的信息:

kill -1 1234 >/dev/null 2>&1

重定向输入

例如:

 #more自身也可以直接读取文件
 more < killout.txt

管道

有些时候使用管道明显更方便:

ps|sort|more

注意不要这样

cat mydata.txt|sort|uniq>mydata.txt

管道构建时,这些命令是同时进行的,uniq>mydata.txt会清空掉mydata.txt

作为程序设计语言的shell

和python等比较相似,比较简单的shell语句是可以直接在bash上运行的。
例如:

#!/bin/sh
#称之为glob通配符
for file in *
do 
    #如果在file中找到了'include'
    if grep -l include $file 
    then 
        echo $file
    fi
done
#退出 返回一个有意义的退出码
exit 0

接下来需要把脚本设置为可执行权限:

chmod +x mysh.sh

然后

./mysh.sh

加上.是因为bash的环境变量PATH中没有当前路径。

shell的语法

变量

shit=shitshit
fuck="fuckfuck"
you=1+3
echo $shit,$fuck,$you

这就是shell的命名方法,创建变量时不需要
上面三种变量都是多少?
都是字符串:

shitshit,fuckfuck,1+3

读取输入赋值

read shit 

环境变量

变量名说明
$HOME当前用户家目录
$PATHshell用来搜索命令的目录
$0当前shell脚本名称
$#传递给脚本的参数个数
$$进程PID

参数变量

变量名说明
$1,$2,$3脚本程序的参数
$@一个分割开的字符串

一个应用实例是:
打印出所有的参数名称:

#!/bin/bash
for i in $@
do
    echo $i
done
exit 0

./my.sh 1 2 3
1
2
3

条件

判断某一个文件是否存在:

 if test -f mysh.sh
 then 
 echo shit you are here
 fi

或者这种:

if [ -f mysh.sh ]
then
echo shit
fi

(是不是shell编程很累啊?相比之下python的方式就要友好得多,靠缩进来说明结构,不需要then fi do done这些语句。但是这么做肯定是由当年的一些限制在里边。python要到1989年才能发明出来~)

[ -f mysh.sh ]可以看做test命令的变种。除了进行文件测试外:
还可以有字符串、算术等。具体可以看这里

控制结构

我们之前已经有提及到其控制结构了:

if condition
then
    statements
elif
    statements
else 
    statements
fi

for循环一般是字符串

for variable in values
do
    statements
done

但是这样很明显太弱了,for还可以用通配符来拓展:

#!/bin/bash
for file in $(ls f*.sh)
do 
    #打印文件
    lpr $file
done
exit 0

需要特别注意的是在ls f*.sh上加上$()

while语句:

while condition do
    statement
done

朴素的密码验证

#!/bin/bash
echo "print your password"
read word

while [ "$word" != "secret" ]
do
    echo "Sorry,try again"
    read word
done
exit 0

你会注意到$word加了一个引号,这么做是为了防止如下情形:
当word为空时,则变成了[ !=”secret” ]

case语句:

case  variable in
    pattern[|pattern]...) statements;;
    pattern[|pattern]...) statements;;
esac

一个小栗子:

#!/bin/bash

echo "yes or no?(y/n)"
read  yn
case "$yn" in
    y|yes|ok) echo "confirmed!"
              echo "successfully";;
    n|no|n*)  echo "canceled";;
    *) echo "you say what?";;
esac
    exit 0

1.注意pattern其实是支持通配符的,*代表了一个字符串
2.注意一个case下可以有多条语句

函数

shell的函数可能看起来不怎么严谨。

function_name(){
    statements
}

没有返回类型,没有参数类型。
我们只谈两三个简单的例子:

捕获返回结果

foo(){echo JAY;}
...
result="$(foo)"

一个复杂的点的返回0或1的函数

#!/bin/bash
yesno(){
    echo "is your name $* ?"
    while true
    do 
        echo -n "Enter yes or no:"
        read x
        case $x in
            y*) return 0;;   
            n*) return 1;;
            *) echo "you say what ?"
        esac
    done
}

echo "原始参数是: $*"
if yesno "$1"
then 
    echo "OK"
else 
    echo "Well..."
fi
exit 0

命令

我认为比较重要的有:
exec命令
exit n命令
expr命令
之前说过,无论是单引号双引号还是都是字符串。
类似于s=1+2这样得到的结果只是一个字符串1+2
正确的用法是:

x=`expr 1 + 2`
#或者
x=$(expr 1 + 2)

你是否注意到这个$的作用?我们之前在for的用法中也用到过,如果忘记了请往回看看。
需要注意的是expr是一个命令,后面这个表达式每一个之间都有一个空格,这样命令才能正确识别。
如果我们要实现x的自加

x=$(expr $x + 1)

printf命令
基本形式是:

printf "format string" parameter1 parameter2...

示例

printf "%s %d \t%s" "Hi There" 15 people 

“Hi There”之所以也有双引号是因为需要将其看做一个整体。这一技巧还会在很多地方看到。
trap

在Shell编程中比较常用的两个外部命令:
find

find [path] [options] [test] [actions]

find的具体指令请看这里

另一个是grep

grep [options] PATTERN [FILES]

例如之前我们提到过的

grep -l include *
#搜索当前目录下的所有带有"include"的文件名

具体用法看这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值