33

shell语法练习

 4 years ago
source link: https://www.tuicool.com/articles/2qQ3Yrv
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

shell语法练习

变量的定义和使用

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

输入参数:

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

先来一个简单的输出shell

#!/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 之后输出如下

[root@cdh-master test]# ./demo.sh haha hehe
haha
./demo.sh
haha
hehe
this $? is 0
this \*? is haha hehe
this \#? is 2

循环

for循环:

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

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

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

使用for循环求和:

#!/bin/bash
j=0
for((i=0;i<=100;i++))
do
	j=`expr $i + $j`
done
echo $j

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

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

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

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

while循环:

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

也可以使用下面的方式

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

使用while读取文件

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

条件

if语句:

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

#!/bin/bash
a=300
b=200
if (($a<$b));then
	echo "a<b"
else 
	echo "a>b"
fi

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

#!/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”,想要得到结果有四种方式,建议使用第四种

$(( 4 + 5 ))
$[ 4 + 5 ]
n=10 let n=n+1
命令 描述 例子 -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

方法函数

定义一个函数

第一种:

name()
{
    
}

第二种:

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

例子:

#!/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
#!/bin/bash
a=1;
factorial(){
#此处$1是西面调用的时候传过来的参数
for i in `seq $1`
do
	let a*=$i
done
echo  "$1 的阶乘 $a "
}
#此处$1是外部传入的参数
factorial $1

函数的返回值

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

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

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

#!/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下载:

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

下载完NDK配置环境变量

vim /etc/profile

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

sorce /etc/profile

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

[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 报错

[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,给它安装

yum install bzip2

在解压OK

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

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

#!/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目录,里面就是编译完成的文件。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK