Shell脚本基础知识-初步版

cnblogs 2024-09-30 17:15:00 阅读 51

本文是笔者研究生期间在阅读《Linux命令行与shell脚本编程大全》之后总结出来的一些重点知识的记录,在此重新整理输出。以便在给上个帖子 涉及到的相关知识点进行一下讲解,帮助自己复习

shell脚本的首行规范化应该是

<code>#!/bin/bash

# function description

其中第一行必须如此,#后面的惊叹号会告诉shell用哪个shell来运行脚本,第二行是本脚本的功能说明。

一. 引用变量与数组

● 当进行变量赋值后,要引用这个变量,则要用 $符号,而如果要某个命令的结果进行赋值则要用 $()

● 变量名称区分大小写,赋值的=前后不能有空格

days=10

guest="Katie"code>

echo "$guest checked in $days days ago"

#!/bin/bash

testing=$(date)

echo "The date and time are: " $testing

● 一维数组,即向量,空格隔开,下标读取, */@读取所有元素

array_name=(value0 value2 value3)

# 数组使用

my_array=(A B C D)

echo "数组的元素为: ${my_array[*]}

echo "数组的元素为: ${my_array[@]}

echo "数组的元素个数为: ${#my_array[@]}"

● 重定向输入输出

#### 输出重定向

> # 保存

>> # 追加保存,不覆盖

#### 输入重定向,也就是将 file 作为参数 发给这个命令,比如下面,

# wc命令可以对对数据中的文本进行计数

wc < file1

● 管道 | :一个命令的输出作为另一个命令的输入

rpm -qa | sort > rpm.list

● 其他

# 命令替换

for i in `seq 1 10`

`expr 2+2`

#### echo read printf test命令

echo "It is a test"

echo "\"It is a test\"" # 转义

#!/bin/sh

read name # 从标准输入中读取参数赋给name变量

echo "$name It is a test"

echo -e "OK! \n" # -e 开启转义

echo "It is a dog" > myfile

printf "%-10s %-8s %-4s.2f\n" 郭靖 男 66.1234

二. 流程控制

2.1 for循环

## for循环

for loop in `seq 1 5` # 命令替换

do

echo "The value is: $loop"

done

#或者一条命令

for var in item1 item2 item3;do echo $var;done

# while循环

while condition

do

command

done

#### 示例小脚本

for i in (seq 1 22) X Y M;do cat chr{i}.fa >>hg38.fa;done # () 都是做命令替换的 {}是做变量替换的

for i in `seq 1 12`;do cut -f 6,9 w${i}_transcript.gtfs >w${i}.txt;done

for i in `seq 1 12`;do sort w${i}.txt >w${i}.gtf;done

for i in `cat list.txt`;do grep -w $i whole.gff3|awk '$3=="gene"' >>result.txt;done

2.2 if-else类

### shell流程控制

# 判断 只有第一个 command正常成功执行,返回退出码0的语句中的then的 command2才会被执行

if command1

then

command2

command3

fi

# 另一种形式

if command; then

commands

fi

# if-then-else 语句

if command

then

command2

else

command3

fi

# 嵌套if

if grep $testuser /etc/passwd

then

echo "The user $testuser exists on this system."

else

echo "The user $testuser does not exist on this system."

if ls -d /home/$testuser/

then

echo "However, $testuser has a directory."

fi

fi

# elif

if command1

then

commands

elif command2

then

more commands

fi

2.3 if中对条件的判断

除了 正常执行某个命令之外,还可以用 test 和 [ condation ] 两种形式来判断,判断条件有数值比较 字符串比较 文件比较

### 更一般性的判断语句,而不只是以command是否成功执行为判断依据

# test condition # 检查某个表达式是否成立;test可以判断 数值比较 字符串比较 文件比较

if test conditon #

then

fi

if [ condition ] # 另一种方式

then

fi

● 数值比较 左边 对于右边的关系

-eq相等

-ge大于或等于

-gt 大于

-le小于或等于

-lt小于

-ne 不等于

● 字符串比较

-n长度非0

-z长度为0

=相同

!=不同

>大

<小

test比较数值用 文本代码(eq,lt)来比较,而比较字符串用 标准数学符号(>=)来比较,比较字符串使用标准的ASCII码顺序,数值< 大写字母< 小写字母

# 节选自 《linux命令行与shell脚本大全》第三版 P245

# -n -z 检查一个变量是否含有数据 可以用来判断 自己写的shell程序的命令行参数是否完备

cat test10.sh

$ cat test10.sh

#!/bin/bash

# testing string length

val1=testing

val2=''code>

#

if [ -n $val1 ]

then

echo "The string '$val1' is not empty"

else

echo "The string '$val1' is empty"

fi

#

if [ -z $val2 ]

then

echo "The string '$val2' is empty"

else

echo "The string '$val2' is not empty"

fi

#

if [ -z $val3 ]

then

echo "The string '$val3' is empty"

else

echo "The string '$val3' is not empty"

fi

$

$ ./test10.sh

The string 'testing' is not empty

The string '' is empty

The string '' is empty

$

● 文件比较

-d file 检查file是否存在并是一个目录

-e file 检查file是否存在

-f file 检查file是否存在并是一个文件

file1 -nt file2 检查file1是否比file2新

file1 -ot file2 检查file1是否比file2旧

更多参见 P246 12.4.3

● 复合条件测试

[ condtion1 ] && [ condtion2 ]

[ condtion1 ] || [ condtion2 ]

2.4 Case

# case

case variable in

pattern1 | pattern2) commands1;;

pattern3) commands2;;

*) default commands;;

esac

例子

case $USER in

rich | barbara)

echo "Welcome, $USER"

echo "Please enjoy your visit";;

testing)

echo "Special testing account";;

jessica)

echo "Do not forget to log off when you're done";;

*)

echo "Sorry, you are not allowed here";;

esac

三.处理命令行输入参数

在命令行获取参数,默认的 执行脚本被认为是 $0,那么 后面每隔一个空格 的参数就依次是 $1, $2 ......。

# 1.命令行参数 位置参数 parameters

(basename $0), $1 ~ $9 ${10} (参数检测 -n -z )

# 2.特殊参数变量

$# : 命令行参数总和 最后一个参数 ${!#} $* $@ 所有的参数

# 3.移动变量

shift n

## 4.处理选项options -a getopt/getopts

case --双破折线 区分 parameter -- option -a num1 -c num2

# getopt / getopts 格式化命令行或参数 P300

getopt ab:cd -a -b test1 -c -d test2 test3

# 5. 选项标准化 默认的选项表示的意思

-c 计数 -r 递归 -q 安静

### 6.获得用户输入

echo -n "Enter your name: " # 用户输入与提示文字 在一行,类似表单

read name # read 将输入结果放进一个变量中

echo "Hello $name, welcome to my program. "

# 或者 一行搞定

read -p "Please enter your age: " age

# 超时 -t

if read -t 5 -p "Please enter your name: " name

then

echo "Hello $name, welcome to my script"

else

echo

echo "Sorry, too slow! "

fi

# -s 隐藏读取 比如密码 实际上,数据会被显示,只是 read命令会将文本颜色设成跟背景色一样

read -s -p "Enter your password: " pass

## 从文件读取 实用

count=1

cat test | while read line

do

echo "Line $count: $line"

count=$[ $count + 1]

done

echo "Finished processing the file"

四.重定向深入理解

### 1.输入与输出

#文件描述符 非负整数 0标准输入 1标准输出 2标准错误

< > 2> 1> &>

### 2.脚本重定向

## 临时重定向

cat test8

#!/bin/bash

# testing STDERR messages

echo "This is an error" >&2

echo "This is normal output"

$

$./test8 2>test9 # 错误的信息被重定向

## 永久重定向

$ cat test10

#!/bin/bash

# redirecting all output to a file

exec 1>testout # or exec 2>testerror

echo "This is a test of redirecting all output"

echo "from a script to another file."

echo "without having to redirect every individual line"

### 3.重定向输入

exec 0< testfile

while read line

BTW:

阅读完上面的内容,基本上就能看懂上期我发的 简单可靠的SpringBoot Jar包启动脚本了。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。