linux+shell+func,《Linux Shell 脚本攻略》 01 小试牛刀

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

打开终端后,就会出现一个提示符号,# 表示超级用户 (root user) ,$ 表示普通用户,超级用户是 Linux 系统中权限最高的用户

shell脚本通常以 #! 起始,如1

/bin/bash 是Bash的路径

运行脚本的两种方式:将脚本作为命令行参数

将脚本作为具有执行权限的可执行文件1

2

3

4

5

6

7$ sh script.sh

# 2

$ chmod a+x script.sh

$ ./script.sh # 使用相对路径

$ /root/home/script.sh # 使用绝对路径

最终执行的逻辑会查找文件中的 /bin/bash ,并在内部执行如下1$ /bin/bash script.sh~/.bashrc 文件:包含定义诸如提示文本、颜色等各类设置的一组命令

~/.bash_history 文件:用于保存用户执行过的命令

在 Bash 中使用分号或换行符来分隔每个命令,如1

2

3

4

5

6

7

8cmd1; cmd2

# 2

cmd1

cmd2

使用 # 用于注释

终端打印

echo、printf

echo

终端作为交互式工具,用户可以通过它与shell环境进行交互,echo 命令用于终端打印的基本命令1

2

3

4

5

6

7

8

9

10

11# 使用双引号,OK

$ echo "hello world"

hello world

# 不使用双引号,OK

$ echo hello world

hello world

# 使用单引号,OK

$ echo 'hello world'

hello world

在双引号中打印特殊字符需要在字符前加转义字符 ,如1

2$ echo "hello world!"

hello world

在shell脚本中,可通过设置 set +H 来显示 !,如1

2

3

4

5# set_h.sh

set +H

echo "hello world!"

在使用单引号的情况下,若字符串包含变量 $var,则原样打印,如1

2$ echo 'hello world $var'

hello world $var

printf

printf 使用的参数和C语言中的 printf 函数一样

格式:printf FOMART_STR STR1$ printf "hello world"

可用于格式化输出,如1

2

3

4

5# printf.sh

printf "%-5s %-10s %-4sn" No Name Mark

printf "%-5s %-10s %-4.2fn" 1 John 89.999

执行输出1

2

3$ ./printf.sh

No Name Mark

1 John 90.00

变量和环境变量

在 Bash 中,每一个变量都是字符串

使用 env 命令查看当前终端进程所使用到的环境变量,如1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20$ env

TMPDIR=/var/folders/1n/8t5fdjrd4mj1qn_13qwzcny80000gn/T/

__CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0

SHELL=/bin/zsh

HOME=/Users/a2htray

PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

LOGNAME=a2htray

XPC_SERVICE_NAME=0

USER=a2htray

XPC_FLAGS=0x0

LC_CTYPE=en_US.UTF-8

LESS=-R

LSCOLORS=Gxfxcxdxbxegedabagacad

SHLVL=1

ZSH=/Users/a2htray/.oh-my-zsh

TERM_PROGRAM=vscode

TERM_PROGRAM_VERSION=1.30.1

LANG=en_US.UTF-8

TERM=xterm-256color

_=/usr/bin/env

一个变量可通过以下方式进行赋值,如1

2

3

4# 等号两边不能有空格,正确

var=value # 赋值操作

# 错误

var = value # 判断相等操作

如需打印变量,在变量名前加 $,如1

2

3

4

5

6

7

8

9$ var=value

$ echo $var

# 或者

$ echo ${var}

# 在打印命令中引用该变量

$ echo "the ${var} of world is the $var"

the value of world is the value

额外

使用 #,可获取字符串的长度1

2

3

4

5

6

7

8

9

10

11

12# 获取字符串长度

$ var=value

$ length=${#var}

$ echo ${#var} $length

5 5

# 识别当前的shell版本

$ echo $SHELL

/bin/zsh

# 或者

$ echo $0

/bin/zsh

根据 root 用户的 UID 为 0 可判断当前用户是否为 root用户1

2

3

4

5

6

7

8

9

10

11# is_root.sh

set +H

if [ $UID -ne 0 ]; then

echo "non root"

else

echo "root"

fi

echo "$UID"

执行输出1

2

3$ ./is_root.sh

non root

501

通过shell进行数学运算

可以使用 let、(())、[] 执行基本的算数操作,进行高级运算时,可使用expr或bc1

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#operation.sh

#!/bin/bash

# nu1与nu2均为字符串

nu1=5

nu2=6

let nu1++ # nu1自加1

let nu2-- # nu2自减1

echo $nu1 $nu2

# let简写形式

let nu1+=7 # nu1加7

let nu2-=2 # nu2减2

echo $nu1 $nu2

# 使用[]

result1=$[ nu1 + nu2 ]

echo $result1

# 使用(())

result2=$(( nu1 + nu2 ))

echo $result2

# 使用expr

result3=$(expr $nu1 + $nu2)

result4=`expr 3 + 4`

echo $result3 $result4

上述操作只适用于整数,若需浮点数支持,则使用bc

文件描述符和重定向

>、>>

文件描述符是与文件输入、输出相关联的整数,最常见的文件描述符是标准输入stdin、标准输出stdout与标准错误stderr数值描述符说明0stdin标准输入

1stdout标准输出

2stderr标准错误

使用>,通过截取的方式,将输出文本存储到文件tmp.txt中,tmp.txt文件中的内容将被清空1$ echo "hello world" > tmp.txt

使用>>,tmp.txt文件不会被清空,而是以追加到现有文件的尾部1$ echo "hello world" >> tmp.txt

当使用重定向操作符时,重定向的内容不会出现在终端,而是直接导入文件

重定向操作符的默认是标准输出,若希望使用特定的描述符,必须将描述符置于操作符之前1

2

3

41> # 等价于 >

2>

1>> # 等价于 >>

2>>

成功与不成功命令的区别在于是否返回 0 :成功返回 0 ,不成功返回非 0 ,返回值可通过特殊变量 $? 获得1

2

3

4

5$ ls +

ls: +: No such file or directory

$ echo $?

1

$ ls + 2> tmp.txt # 使用描述符将标准错误导入tmp.txt1

2

3

4# 可以将stderr单独导入到一个文件,stdin单独导入到另一个文件

$ cmd 1> in.txt 2> err.txt

# 将stderr转换成stdout,导入到同一个文件

$ cmd 2>&1 all.txt

常用作法是将stderr重定向到 /dev/null 设备文件,该文件收到的任何数据都将丢弃

管道符|

使用 tee 命令结合管道符|,一方面可以将数据重定向到文件,另一方面还可以提供一份重定向数据的副本作为后续命令的 stdin ,如1

2

3# tee 接受stdout的作为输入

$ ls + | tee out.txt

ls: +: No such file or directory

补充

借助重定向,可以像使用stdin那样从文件中读取数据1$ cmd < FILE

使用别名

使用alias命令,如果别名已经存在,会将原别名取代1

2

3$ alias new_command='command sequence'

# 为保持别名持续有效,将其写入~/.bashrc

$ echo new_command='command sequence' > ~/.bashrc

获取终端信息

tput、stty是两款终端处理工具1

2

3

4# 基本用不到

tput cols # 输出当前终端列数

tput lines # 输出当前终端行数

tput longname # 输出当前终端名

获取、设置日期和延时

使用date命令1

2

3

4

5

6

7

8

9# date.sh 获取程序运行的时间

#!/bin/bash

start=$(date +%s)

cmd

cmd

...

end=$(date +%s)

duration=$((end - start))

使用sleep生成延时1$ sleep 5 # 延时5秒

调试脚本set -x

运行带 -x 的脚本能打印出所执行的每一行命令以及当前状态

在脚本文件中可心使用 set 命令进行设置命令描述set -x在执行时显示参数和命令

set +x禁止调试

set -v当命令进行读取时显示输入

set +v禁止打印输入

技巧,通过设置变量决定是否开启调试1

2

3

4

5

6

7# debug.sh

#!/bin/bash

# if statement

if [ $_DEBUG == "on" ]; then

echo "debug"

fi

调用1$ _DEBUG=on ./debug.sh

将 #!/bin/bash 修改为 #!/bin/bash -xv ,这样就不用其他选项就可以启用调试功能

函数与参数

定义函数1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22#!/bin/bash

function func1()

{

echo "func1"

}

func1

func2()

{

echo "func2"

}

func2

function func3()

{

echo $1

}

func3 "func3"$1 是第一个参数

$2 是第二个参数

$n 是第n个参数

$@ 扩展成”$1” “$2” “$3”等

$* 扩展成”$1c$2c$3”等

函数也能像环境变量一样用export导出,则函数的作用域可以扩展到子进程中1export -f fname

读取命令序列输出

输入通常是通过stdin或参数传递给命令,输出要么出现在stderr,要么出现在stdout1cmd1 | cmd2 | cmd3

cat -n 将输出加上行号

读取命令序列的输出1

2

3

4

5cmd_output=$(ls | cat -n)

echo $cmd_output

# 或者

cmd_output=`ls | cat -n` # 使用反引用

echo $cmd_output1

2

3

4

5

6

7

8

9

10

11

12$ cat text.txt

1

2

3

$ out=$(cat text.txt)

1

2

3

$ out="$(cat text.txt)"

1

2

3

读取字符

下面语句从输入中读取n个字符并存入变量variable_name1read -n number_of_chars variable_name1

2

3

4

5$ 使用定界符:

$ read -d ":" var

hello:

$ echo $var

hello

字段分隔符和迭代器

IFS:内部字段分隔符,默认值为空白字符(换行符、制表符或空格)1

2

3

4

5

6

7

8

9

10

11

12

13

14

15# ifs.sh

#!/bin/bash

data="name,gender,age,location"

oldIFS=$IFS

IFS=,

# for循环不错

for item in $data;

do

echo Item: $item

done

IFS=$oldIFS

比较与测试

文件系统相关条件作用[ -f $var ]正常文件名或路径,返回真

[ -x $var ]文件可执行,返回真

[ -d $var ]正常目录,返回真

[ -e $var ]文件存在,返回真

[ -c $var ]一个字符设备文件的路径,返回真

[ -b $var ]一个块设备文件路径,返回真

[ -w $var ]可写,返回真

[ -r $var ]可读,返回真

[ -L $var ]符号链接,返回真

字符串比较条件作用[[ $str1 = $str2 ]]相等为真

[[ $str1 == $str2 ]]相等为真

[[ $str1 != $str2 ]]不相等为真

[[ $str1 > $str2 ]]大于

[[ $str1 < $str2 ]]小于

[[ -z $str1 ]]字符串包含空格字符,返回真

[[ -n $str1 ]]非空字符串,返回真

使用逻辑运算符将代码简洁一点,减少if else1

2[ condition ] && action # 如果为真则执行

[ condition ] || action # 如果为假则执行

结合多个条件进行测试-a: 逻辑与

-o: 逻辑或1

2

3

4# 0 < $var and $var < 10

[ $var -gt 0 -a $var -lt 10 ]

# $var < 0 or $var > 10

[ $var -lt 0 -o $var -gt 10 ]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值