shell语法练习

shell语法练习

变量的定义和使用

编写shell脚本,第一行是#!/bin/bash代表是个shell脚本

输入参数:

形式 说明
$0 当前程序的名称
$n 程序的输入参数n=1 第一个参数n2 第二个参数1..n
$* 所有输入的参数
$# 输入参数的个数
$? 命令执行的状态,一般返回0代表成功

先来一个简单的输出shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
echo "haha"

A=10
#代表输出自己
echo $0
#代表输出第一个参数
echo $1
#代表输出第二个参数
echo $2
#$?表示执行是否成功 0代表成功 非0代表失败
echo "this \$? is $?"
#$* 列出所有传入的参数
echo "this \*? is $*"
#$# 代表输入了几个参数
echo "this \#? is $#"

执行./demo.sh haha hehe之后输出如下

1
2
3
4
5
6
7
8
[root@cdh-master test]# ./demo.sh haha hehe
haha
./demo.sh
haha
hehe
this $? is 0
this \*? is haha hehe
this \#? is 2

循环

for循环:

1
2
3
4
5
#!/bin/bash
for i in `seq 1 15`
do
echo "数字 $i"
done

seq代表取值,上面代码就是取1-15的值

for循环中的逻辑放在do和done的中间,运行上面的代码就会输出1-15之间的数字。

使用for循环求和:

1
2
3
4
5
6
7
#!/bin/bash
j=0
for((i=0;i<=100;i++))
do
j=`expr $i + $j`
done
echo $j

使用加号需要用expr关键字来修饰

使用for循环,循环压缩文件

1
2
3
4
5
6
#!/bin/bash
j=0
for i in `find /app/bigdata/test -name "*.sh"`
do
tar -cvf chs.tgz $i
done

通过find命令找到某个文件夹下的所有.sh结尾的文件,然后通过tar命令来压缩。

while循环:

1
2
3
4
5
6
7
#!/bin/bash
i=0
while((i<100))
do
echo "数字 $i"
i=`expr $i + 1`
done

也可以使用下面的方式

1
2
3
4
5
6
7
#!/bin/bash
i=0
while [[ $i -lt 100 ]]
do
echo "数字 $i"
i=`expr $i + 1`
done

使用while读取文件

1
2
3
4
5
6
7
#!/bin/bash
i=0
while read line
do
echo $line
#小于号代表读取出来的内容指向哪里
done</app/bigdata/test/text.txt

条件

if语句:

if语句后面不需要{},只需要;,语句的第一样一定要使用tab键输入,不能使用空格。空格在shell中不能随便写,代表一个特殊的分割符

1
2
3
4
5
6
7
8
#!/bin/bash
a=300
b=200
if (($a<$b));then
echo "a<b"
else
echo "a>b"
fi

例子: -d是判断目录是否存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
if [[ ! -d /app/bigdata/hello ]];then
mkdir -p /app/bigdata/hello
else
echo "目录已经存在"
fi
-------------------
#!/bin/bash
dir=/app/bigdata/test/haha.txt
if [[ ! -d $dir ]];then
vi $dir
else
echo "文件经存在"
cat $dir
fi

算数运算

  • 算数运算符
  • 关系运算符
  • 布尔运算符
  • 字符串运算符
  • 文件测试运算符

算数运算符

运算符 说明 例子
+ 加法 `expr $a + $b`
- 减法 `expr $a - $b`
* 乘法 `expr $a * $b`
/ 除法 `expr $a / $b`
% 取余 `expr $a % $b`
= 赋值 a=$b
== 相等 [ $a==$b ]
!= 不相等 [ $a!=$b ]

注意:条件表达式要放在中括号内,并且要有空格!

算数运算符中我们不能直接使用运算符得到结果比如1+1,只会输出一个字符串“1+1”,想要得到结果有四种方式,建议使用第四种

  1. 使用$(()) $(( 4 + 5 ))
  2. 使用$[] $[ 4 + 5 ]
  3. 使用let命令 n=10 let n=n+1
  4. 使用expr外部程式 a=`expr 4 + 5`
命令 描述 例子
-eq 等于 [ $a -eq $b ]
-ne 不等于 [ $a -ne $b ]
-gt 大于 [ $a -gt $b ]
-lt 小于 [ $a -lt $b ]
-ge 大于等于 [ $a -ge $b ]
-le 小于等于 [ $a -le $b ]

布尔运算符:

命令 描述 例子
! 非运算 [ !false ]
-a 与运算 [ $a -lt 20 -a $b -gt 100 ]
-o 或运算 [$a -lt 20 -o $b -gt 100]

逻辑运算符

命令 描述 例子
&& 逻辑中的and [[ $a -lt 100 && $b -gt 200]]
` ` 逻辑中的or [[ $a -lt 100 ` ` $b -gt 200]]

字符串运算符

命令 描述 例子
= 两个字符串相等 [ $a=$b ]
!= 两个字符串不等 [ $a!=$b ]
-z 字符串长度是否为0 0返回true [ -z $a ]
-n 字符串长度是否为0 非0返回true [ -n “$a” ]
$ 字符串是否为空 非空返回true [ $a ]

文件测试运算符

$file代表文件的路径

命令 描述 例子
-b 文件是否是块设备文件 [ -f $file ]
-c 文件是否是字符设备文件 [ -f $file ]
-d 目录是否存在 [ -d $file ]
-f 文件是否存在 [ -f $file ]
-g 文件是否设置了SGID位 [ -f $file ]
-k 文件是否设置粘着(Sticky Bit)位 [ -f $file ]
-p 文件是否有名管道 [ -f $file ]
-u 文件是否置了SUID位 [ -f $file ]
-r 文件是否可读 [ -f $file ]
-w 文件是否可写 [ -f $file ]
-x 文件是否可执行 [ -f $file ]
-s 文件是否为空 [ -f $file ]
-e 文件(包括目录)是否存在 [ -f $file ]

重定向

Linux中一切皆文件

描述符:

  • 标准输入standard input0 (默认设备键盘)
  • 标准输出standard input1 (默认设备显示器)
  • 错误输出error input2 (默认设备显示器)

输出重定向>比如cat 0< text.txt

输出重定向< 比如echo hello > filename

方法函数

定义一个函数

第一种:

1
2
3
4
name()
{

}

第二种:

1
2
3
4
5
[ function ] funname [()]
{
action;
[return int;]
}

例子:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
aa="this is aa"
bb="this is bb"
function test(){
echo $1
cc="this. is cc"
dd="this is dd"
echo $cc
echo "我是一个函数"
}
#调用函数并传参
test 10

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
a=1;
factorial(){
#此处$1是西面调用的时候传过来的参数
for i in `seq $1`
do
let a*=$i
done
echo "$1 的阶乘 $a "
}
#此处$1是外部传入的参数
factorial $1

函数的返回值

1
2
3
4
5
6
7
#!/bin/bash
fun2(){
read -p "请输入数值" num
let 2*num
}
fun2
echo "fun2 return value: $?"

$?代表取上一条指令的返回值,上面的函数返回值为0。0代表执行成功,非0表执行失败(数值在0-255之间)

可以通过echo的方法返回一个数值

1
2
3
4
5
6
7
#!/bin/bash
fun2(){
read -p "请输入数值" num
echo $[2*$num]
}
result=`fun2`
echo "fun2 return value: $result"

使用shell脚本编译FFmpeg

  • FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。
  • FFmpeg是一个多媒体视频处理工具,具有非常强大的功能,包括视频采集功能,视频格式转换,视频抓图,给视频添加水印等。

FFmpeg组成部分

FFmpeg工具:1.FFmpeg 2.FFplay 3.FFprobe

FFmpeg开发库:

  1. Libavcdec
  2. Libavutil
  3. Libavfrmat
  4. Libavdebice
  5. Libavfilter
  6. Libswscale
  7. Libswresample

FFmpeg下载地址:http://www.ffmpeg.org/download.html

如果我们编译到Android中使用,需要用到Android的NDK

NDK下载:

1
wget https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip

下载完NDK配置环境变量

vim /etc/profile

1
2
NDKROOT=/app/bigdata/test/android-ndk-r17c
export PATH=$NDKROOT:$PATH

sorce /etc/profile

然后执行ndk-build如果打印下面的信息就说明配置OK

1
2
3
[root@cdh-master android-ndk-r17c]# ndk-build
Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.

把下载的ffmpeg的压缩包上传到服务器

解压tar -xjf ffmpeg-4.1.3.tar.bz2报错

1
2
3
4
5
[root@cdh-master test]# tar -xjf ffmpeg-4.1.3.tar.bz2 
tar (child): bzip2: Cannot exec: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now

因为没有安装bzip2,给它安装

1
yum install bzip2

在解压OK

下面开始编译ffmpeg,因为编译的时候需要指定很多参数,所以把它们写到一个shell脚本中方便查看和执行。

进入到ffmpeg-4.1.3的解压目录中,新建一个build.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/bin/bash
#NDK的安装目录
NDK_ROOT=/root/ndk/android-ndk-r17c
#TOOLCHAIN 变量指向ndk中的交叉编译gcc所在的目录
TOOLCHAIN=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/
#FLAGS与INCLUDES变量 可以从AS ndk工程的.externativeBuild/cmake/debug/armeabi-v7a/build.ninja中拷贝,需要注意的是**地址**
FLAGS="-isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -O0 -fPIC"
INCLUDES="-isystem $NDK_ROOT/sources/cxx-stl/llvm-libc++/include -isystem $NDK_ROOT/sources/android/support/include -isystem $NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include"

#执行configure脚本,用于生成makefile
#--prefix : 安装目录
#--enable-small : 优化大小
#--disable-programs : 不编译ffmpeg程序(命令行工具),我们是需要获得静态(动态)库。
#--disable-avdevice : 关闭avdevice模块,此模块在android中无用
#--disable-encoders : 关闭所有编码器 (播放不需要编码)
#--disable-muxers : 关闭所有复用器(封装器),不需要生成mp4这样的文件,所以关闭
#--disable-filters :关闭视频滤镜
#--enable-cross-compile : 开启交叉编译(ffmpeg比较**跨平台**,并不是所有库都有这么happy的选项 )
#--cross-prefix: 看右边的值应该就知道是干嘛的,gcc的前缀 xxx/xxx/xxx-gcc 则给xxx/xxx/xxx-
#disable-shared enable-static 不写也可以,默认就是这样的。
#--sysroot:
#--extra-cflags: 会传给gcc的参数
#--arch --target-os :
PREFIX=./android/armeabi-v7a2
./configure \
--prefix=$PREFIX \
--prefix=$PREFIX \
--enable-small \
--disable-programs \
--disable-avdevice \
--disable-encoders \
--disable-muxers \
--disable-filters \
--enable-cross-compile \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--disable-shared \
--enable-static \
--sysroot=$NDK_ROOT/platforms/android-21/arch-arm \
--extra-cflags="$FLAGS $INCLUDES" \
--extra-cflags="-isysroot $NDK_ROOT/sysroot" \
--arch=arm \
--target-os=android

make clean
make install

保存执行几分钟后,会看到生成了一个andorid目录,里面就是编译完成的文件。

# c/c++

コメント

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×