Shell语法

Shell

命令

ls = list
cd = change directory
cp = copy
mv = move
rm = remove
ps = process status
pwd = print work directory
du = disk usage
df = disk free
mkdir = make directory
rmdir = remove directory
su = switch user
chown = change owner
chmod = change mode

参数

-a = all
-l = list
-f = force
-n = number
-u = user
-z = zip
which python3 = 查看库依赖的路径
env = 查看环境变量
image-20211218223922241
  • 关于shell

shell本身是一个进程,shell命令也会产生其他进程(除shell内建命令外)。调用shell内建命令相当于调用shell进程中的一个函数,并不创建新的进程。凡是which 命令查不到程序文件所在位置的命令都是内建函数。或者:

man bash-builtins
  • 查看shell类型
echo $SHELL
查看passwd文件用户的启动和命令
  • 执行脚本

cmdTest.sh

#!/bin/sh                - 注释,指定是shell脚本
echo "hello world"        - 在屏幕上输出hello world
cd ..                    
ls
chmod a+x cmdTest.sh
./cmdTest.sh

执行之前需要改变文件可执行权限,执行该脚本相当于新建一个进程,但是当前工作的路径不会改变

cmdTest.py

#!/usr/bin/python3
if __name__ == '__main__':
 print("hello world")
chmod a+x cmdTest.py
./cmdTest.py

执行:

./test.sh
/bin/sh test.sh
(cd..; ls -l)
source test.h

变量命名:基本和C语言命名变量一样

赋值:等号前后不能有空格,否则会被当成一个命令和被执行两个的文件

使用变量:

$varname
${varname}

使用{}是为了区分类似于aaa这种变量。

变量测试

varTest.sh

#!/bin/bash
globalvar1="hello"

function test(){
 globalvar2="world"
}

#调用函数
test
echo $globalvar1 $globalvar2

除非变量名前面加上local等限定词,不管是函数内部还是外面都默认为全局变量。该进程中还可以嵌套其他的脚本,在执行的时候会另开一个进程,这些变量不会跨进程,只是单纯的另开一个新的进程。除非是source ./subScripe.sh 或者是环境变量export限定。局部变量只能定义在函数内部

环境变量

每一个进程中都有系统下的参数,当启动一个子进程,父进程的环境变量会拷贝到子进程中,但仅仅是拷贝,在子进程中修改环境变量之后返回父进程,父进程中该环境变量不会改变。即环境变量可以跨进程,但是是单向传递。

删除变量:相当于置空

uset varname

通配符*?[]

ls ~/*.test.txt

dirTest.c

#include <stdio.h>
int main(int argc, char **argv )
{
  for(int i = 0; i < argc; ++i){
          printf("argv[%d]:%s\n", i, argv[i]);
  }

  return 0;
}
touch 1.txt 2.txt 3.txt
touch {1,2,3}.txt
./a.out *.txt
./a.out [1-3].txt
./a.out {1..3}.txt

输出

$ argv[0]:./a.out
$ argv[1]:1.txt
$ argv[2]:2.txt
$ argv[3]:3.txt

代换成功的前提是存在。

  • 命令代换:
DATE=`date`            - 反引号
DATE=$(data)        - $()

test.sh

#!/bin/bash
datetime=`date`
echo "date is : " $datetime

执行的命令也是在当前文件夹下,所以不同的文件夹下执行可能是不同的。

算数代换

使用$(())用于算数运算,(())中的shell变量取值将转换成整数,或者$[]

var=45
echo $(($var + 3))  #等价于$((var+3)) 或 echo $[var+3]或$[$var+3]

注意:$(())中只能使用+-*/()运算符,并且==只能做整数运算==。

进制转换

$[base#n]其中base表示进制,n按照base进行解释,,后面再有运算数,按十进制解释。

echo $[8#10+11]             #将10以8进制来解析,得到的是10进制的8,加上11---》19
echo $[16#10+11]

转义字符

反斜杠\表示后面取字面值,相当于后面就是字符串而不是什么变量

echo $SHELL
/bin/bash
echo \$SHELL
$SHELL

创建一个$ $的dir

mkdir \$\ $

创建一个带-的文件:加上当前的路径,但不建议。

touch ./-hello

单引号:保持字符串的字面值,即便有特殊符号。

C中单引号是字符,Shell脚本中的单引号和双引号都是字符串的界定符,而不是字符的界定符。

echo 'aaaa' # 输出aaaa
echo 'aaaa
>bbbb'
# 输出
aaaa
bbbb

双引号经常作为参数

var="a b"
touch $var          # 创建两个文件
touch "$var"        # 创建一个文件

有些文件名中间存在空格

使用变量之前,如果变量是作为一个参数来传递,应该要习惯性加上双引号。

算术代换:最基本的整数运算

var=45
$[45+1]
$((var+3))

变量的分类

Shell内变量:在Shell解析环境中存在变量

默认全都是全局变量,作用域和生命周期都是到整个脚本结束

局部变量:使用local修饰,只能声明在函数内部

Shell内变量只能在当前Shell进程中使用,跨进程不能使用

环境变量:子进程会拷贝父进程的环境变量,单向传递

export varname=value或者:

varname=val;``export varname;

文件名替换

*匹配0个或多个任意字符

?匹配任意一个字符

[若干字符]匹配方括号中任意一个字符的一次出现

参数拓展

touch 1.txt 2.txt 3.txt 4.txt
touch {1,2,3,4}.txt
touch {1..4}.txt
touch {1..4}_{5..6}.txt

命令代换

执行某一条命令,将这个命令的标准输出的内容存到某个变量

varname=`cmd arg1 arg2`

$(cmd)和`cmd`等价

条件测试

使用test或者[可以测试一条语句是否为真,真的返回值为0

var=2
test $var -gt 1        #检测var变量是否greater than 1
echo $?                #显示上一条命令的执行结果 ---》1
[ $var -gt 3 ]         #和上述test语句一样
echo $?                #---》0 n
[ EXPRESION ]
! EXPRESION                    #取反
EXPRESION1 -a EXPRESION2       #逻辑与
EXPRESION1 -o EXPRESION2       #逻辑或
-n STRING                      #判断字符串不是空串
-z STRING                      #判断字符串长度为0
STRING1 != STRING2             #判断字符串是否相等
STRING1 = STRING2              #判断字符串相等
INTEGER1 -eq INTEGER2          #判断整数相等
INTEGER1 -ge INTEGER2          #判断greater equal
INTEGER1 -le INTEGER2
INTEGER1 -lt INTEGER2
INTEGER1 -ne INTEGER2
文件
FILE1 -nt FILE2                #new than
FILE1 -ot FILE2                #old than
-b FILE                        #块设备
-c FILE                        #字符设备
-d FILE                        #目录
-e FILE                        #是否存在
-f FILE                        #普通文件
-s FILE                        #存在且大小大于0字节
-S FILE                        #是socket文件
-r FILE                        #有读权限
-w FILE                        #有写权限
-x FILE                        #可执行权限

if分支语句

if 命令1|条件测试1
then 
    xxxxx
elif 命令2|条件测试2;then    #
    xxxxx
else                       #else不用加then
    xxxxx
fi
#!/bin/bash

if [ -f /bin/bash ]
then
        echo "/bin/bash is a file"
else
        echo "/bin/bash is not a file"
fi

if :
then
echo "always true"
fi
#!/bin/bash

echo "Is it morning? Please answer yes or no."
read YES_OR_NO
if [ "$YES_OR_NO" = "yes" ]
then
        echo "Good morning!"
elif ["$YES_OR_NO" = "no" ]; then
        echo "Good afternoon!"
else
        echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
fi
# 如果make命令失败就不会执行后面的sudo make install
make && sudo make install
# 如果前面的命令执行失败,就执行后面的命令
echo xxx || exit 1
#!/bin/bash

var=1
var2=2

if [ $var -eq $var2 ] && [ $var2 -eq 2 ]
then
        echo "yes"
else
        echo "no"
fi

特殊变量

$0            # 相当于C语言的main函数的argv[0]
$1、$2...     # 相当于C语言中的 argv[1]、argv[2]
$#            # argc - 1
$*            # 表示参数列表 $1 $2
$?            # 上一条命令的退出状态
$$            # 当前进程号

for循环

#!/bin/bash

for FRUIT in apple banana pear
do
        echo "I like $FRUIT"
done

sum=0
for i in {1..100}
do
        sum=$[$sum+$i]
done
echo $sum

case命令

#!/bin/bash

echo "Is it morning? Please answer yes or no."
read YES_OR_NO

case "$YES_OR_NO" in
yes|y|Yes|YES)
        echo "Good Morning!";;
[nN][oO])
        echo "Good Afternoon!";;
*)
        echo "Sorry,$YES_OR_NO not recognized. Enter yes or no.";;
esac
case 表达式 in
val1|pattern1)
    xxxxx
    ;;
val2|pattern2)
    xxxxx
    ;;
*)
    xxxxx
    ;;
esac

while循环

#!/bin/bash

echo "Enter password:"
read TRY
while [ "$TRY" != "8520" ]
do
        echo "Sorry, try again"
        read TRY
done

输入输出

echo [option] string
-n                        #表示不换行
-e                        #解析转义字符
echo -e "hello\tworld"

管道

通过|把一个命令的输出传递给另一个命令做输入

cat myfile | more
df -k

tee命令

tee命令把结果输出到标准输出

ls | tee a.txt                #把ls的结果输入到a.txt
ls | tee -a a.txt             #把ls的结果追加到a.txt

文件重定向

cmd > file            #标准输出重定向到file
cmd >> file           #标准输出追加到file
cmd < file1 > file2   #输入输出都定向到文件里
#include <stdio.h>
#include <ctype.h>
int main()
{
        int ch = getchar();
        while (ch != EOF) {
                putchar(toupper(ch));
                ch = getchar();
        }
        return 0;
}
gcc main.c -o upper
cat main.c | ./upper | tee upper.txt

函数

function 函数名() {       #function 和 ()至少保留一个
    local var=value
    return 1;            #只能返回整数
}
#!/bin/bash
text (){
        echo "test"
        return 1;
}
text
echo $?

function text2 {
        echo "aaaa"
        return 0
}
var=`text2`
echo $var
#!/bin/bash

function visit {
        dir="$1"
        for f in `ls $1`
        do
                if [ -f "$f" ]
                then
                        echo "$f is a file"
                elif [ -d "$f" ]
                then
                        echo "$f is a dir"
                        visit "$f"
                else
                        echo "$f is not recognized."
                fi
        done
}
visit

脚本调试

-n 遍历一个脚本,检查语法错误

-v 一边执行脚本一边解析到脚本的输出

-x 执行脚本的同时打印每一句指令

打开调试方法

bash -x 脚本.sh
脚本开头  #!/bin/bash -x

正则表达式

1.以S开头的字符串
^S                    #^表示开始, $表示结束
2.以数字结尾的字符串
[0..9]
\d
[0123456789]

[1-9]$            # $匹配最后一个字符
3.匹配空串
^$
4.字符串只包含三个数字
^\d\d\d$
^\d{3}$            # {n}表示前面的单元重复n次
5.字符串中只有3到5个字母
    控制最少重复次数和最大重复次数
{m,n}              # m表示前面单元重复最少的次数,n表示前面单元重复的最大次数
[a-zA-Z]           # 表示大小写字母
^[a-zA-Z]{3,5}$
6.匹配不是a-z的任意字符
[^a-z]             #中括号中第一个字符如果是^,表示区间取反
^[^a-z]$           
7.字符串只有0到1个数字或者字母或者下划线
{0,1}   #表示重复0到1次
?       #也可以表示0到1次的重复
^[a-z_A-Z0-9]?$
^\w?$
8.字符串有一个或者多个空白字符(\t\n\r等)
^\s{1,}$
^\s+$
9.字符串有0个或者若干个任意字符(除了\n)
.  #表示任意字符,除了\n
?  #0-1
+  #1-n
*  #0-n
^.{,}$
^.*$            # *表示前面的单元重复0到n次
10.匹配0或者任意多组ABC、比如ABC,ABCABC
使用小括号来将多个单元重新组合成为一个单元
^(ABC)*$
11.字符串要么是123要么是ABC
| 表示选择两边的正则匹配其中一个
^ABC|123$
^(ABC|123)$
12.字符串只有一个点号
^\.$
13.匹配十进制数的三位整数
^[1-9][0-9][0-9]$
^[1-9][0-9]{2}$
14.匹配0-255的整数

基础的正则:+?*是普通字符

扩展的正则:+?*是特殊字符

perl的正则:

全部评论

相关推荐

许愿ssp的咸鱼很不想泡池子:import python as pyhton
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客企业服务