注册 | 登录 | QQ登陆 |

终极 Bash 脚本指南

时间:2024-08-14人气:-


内部变量

Bash 的内部变量也不少,有时我们可能会用到,如 $BASHPID $IFS $PWD 等,更多看这里 。

将命令输出分配给变量

可以使用 $(command) 将命令输出存储在变量中。例如这是一个info.sh脚本内容:

#!/bin/bashLIST=$(ls -l)echo "File information: $LIST"

执行(别忘了给执行权限)

$ ./info.shFile information: total 8-rwxrwxr-x 1 razeen razeen 85 2月   5 07:35 hello.sh-rwxrwxr-x 1 razeen razeen 58 2月   5 07:36 info.sh

下面的脚本会将时间和日期,用户名以及系统正常运行时间保存到日志文件中。

其中 > 是重定向之一,它将覆盖文件。使用 >> 可以将输出追加到文件。

#!/bin/bashDATE=$(date -u) # UTC 时间#!/bin/bashDATE=$(date -u) # UTC 时间WHO=$(whoami) # 用户名UPTIME=$(uptime) # 系统运行时间echo "Today is $DATE. You are $WHO. Uptime info: $UPTIME" > logfileWHO=$(whoami) # 用户名UPTIME=$(uptime) # 系统运行时间echo "Today is $DATE. You are $WHO. Uptime info: $UPTIME" > logfile

image-20210205074148588

内建命令

Shell 内建命令是可以直接在Shell中运行的命令。可以这么查看内建命令:

$ compgen -b | sort-.:[aliasautoloadbgbindkeybreakbuiltinbyecd

也可以用 type 查看命令的类型。

$ type cdcd is a shell builtin

可以用 which 命令查看可执行文件的文件路径:

# which sort/usr/bin/sort

可通过 man builtins 查看内建命令的详细描述。

测试IF条件表达式

if 后面需要接者then:

if [ condition-for-test ]then  command  ...fi

或者,

if [ condition-for-test ]; then  command  ...fi

如:

#!/bin/bash VAR=myvarif [ $VAR = myvar ]; then    echo "1: \$VAR is $VAR"   # 1: $VAR is myvarfiif [ "$VAR" = myvar ]; then    echo "2: \$VAR is $VAR"   # 2: $VAR is myvarfiif [ $VAR = "myvar" ]; then    echo "3: \$VAR is $VAR"   # 3: $VAR is myvarfiif [ "$VAR" = "myvar" ]; then    echo "4: \$VAR is $VAR"   # 4: $VAR is myvarfi

上面,我们在比较时,可以用双引号把变量引用起来。

但要注意单引号的使用。

#!/bin/bashVAR=myvarif [ '$VAR' = 'myvar' ]; then    echo '5a: $VAR is $VAR'else    echo "5b: Not equal."fibas# Output:# 5b: Not equal.

上面这个就把 ‘$VAR’ 当一个字符串了。

但如果变量是多个单词,我们就必须用到双引号了,如

#!/bin/bash# 这样写就有问题VAR1="my var"if [ $VAR1 = "my var" ]; then    echo "\$VAR1 is $VAR1"fi# Output# error [: too many arguments# 用双引号if [ "$VAR1" = "my var" ]; then    echo "\$VAR1 is $VAR1"fi

总的来说,双引号可以一直加上。

空格问题

比较表达式中,如果=前后没有空格,那么整个表法式会被认为是一个单词,其判断结果为True.

#!/bin/bash VAR2=2#  由于被识别成一个单词, [] 里面为 trueif [ "$VAR2"=1 ]; then    echo "$VAR2 is 1."else    echo "$VAR2 is not 1."fi# Output# 2 is 1.# 前后加上空格就好了if [ "$VAR2" = 1 ]; then    echo "$VAR2 is 1."else    echo "$VAR2 is not 1."fi# Output# 2 is not 1.

另外需要注意的是, 在判断中,中括号 [ 和变量之间一定要有一个空格,= 或者 ==。 如果缺少了空格,你可能会到这类似这样的错误:unary operator expected’ or missing ]` 。

# 正确, 符号前后有空格if [ $VAR2 = 1 ]; then    echo "\$VAR2 is 1."else    echo "It's not 1."fi# Output# 2 is 1.# 错误, 符号前后无空格if [$VAR2=1]; then    echo "$VAR2 is 1."else    echo "It's not 1."fi# Output# line 3: =1: command not found# line 5: [=1]: command not found# It's not 1.

文件测试表达式

对文件进行相关测试,判断的表达式如下:

表达式True

file1 -nt file2

file1 比 file2 新。

file1 -ot file2

file1 比 file2 老。

-d file

文件file存在,且是一个文件夹。

-e file

文件 file 存在。

-f file

文件file存在,且为普通文件。

-L file

文件file存在,且为符号连接。

-O file

文件 flle 存在, 且由有效用户ID拥有。

-r file

文件 flle 存在, 且是一个可读文件。

-s file

文件 flle 存在, 且长度大于0。

-w file

文件 flle 可写入。

-x file

文件 flle 可写执行。

可以使用man test查看那详细的说明。

当表达式为True时,测试命令返回退出状态 0,而表达式为False时返回退出状态1。

#!/bin/bashFILE="/etc/resolv.conf"if [ -e "$FILE" ]; then  if [ -f "$FILE" ]; then      echo "$FILE is a file."  fi  if [ -d "$FILE" ]; then      echo "$FILE is a directory."  fi  if [ -r "$FILE" ]; then      echo "$FILE is readable."  fifi

字符串比较表达式表达式True

string1 = string2 或 string1 == string2

两字符相等

string1 != string2

两个字符串不相等

string1 > string2

string1 大于 string2.

string1 < string2

string1 小于string2.

-n string

字符串长度大于0

-z string

字符串长度等于0

#!/bin/bashSTRING=""if [ -z "$STRING" ]; then  echo "There is no string." >&2   exit 1fi# Output# There is no string.

其中>&2将错误信息定位到标准错误输出。

数字比较表达式

下面这些是用来比较数字的一些表达式。

[…]((…))True

[ “int1” -eq “int2” ]

(( “int1” == “int2” ))

相等.

[ “int1” -nq “int2” ]

(( “int1” != “int2” ))

不等.

[ “int1” -lt “int2” ]

(( “int1” < “int2” ))

int2 大于 int1.

[ “int1” -le “int2” ]

(( “int1” “int2” ))

int1 大于 int2

[ “int1” -ge “int2” ]

(( “int1 >= “int2” ))

int1 大于等于 int2

双括号 (())

数值的比较或者计算可以用((... ))。

#!/bin/basha=3b=4c=3if (("$a" < "$b")); then    echo "$a is less than $b."else    echo "$a is not less than $b."fiif (("$a" != "$c")); then    echo "$a is not equal to $c."else    echo "$a is equal to $c."fi# 计算echo "$a + $b = $(($a + $b))"# Output# 3 is less than 4.# 3 is equal to 3.# 3 + 4 = 7

怎么使用 if/else 和 if/elif/else

其实上面已经展示了不少了,这里总结下if...else 和 if...elif...else 语句。

if/else 语句格式如下:

if [ condition-is-true ]then  command Aelse  command Bfi# 或if [ condition-is-true ]; then  command Aelse  command Bfi

例如:

#!/bin/bashMY_SHELL="csh"if [ "$MY_SHELL" = "bash" ]then  echo "You are using the bash shell."else  echo "You are not using the bash shell."fi

if/elif/else 语句格式如下:

if [ condition-is-true ]then  command Aelif [ condition-is-true ]then  command Belse  command Cfi# orif [ condition-is-true ]; then  command Aelif [ condition-is-true ]; then  command Belse  command Cfi

如:

#!/bin/bashMY_SHELL="csh"if [ "$MY_SHELL" = "bash" ]; then  echo "You are using the bash shell."elif [ "$MY_SHELL" = "csh" ]; then  echo "You are using csh."else  echo "You are not using the bash shell."fi

双中括号的使用[[]]

如用用于比较的变量不是单个单词,就需要[[]] , 或者用单中括号(这时需要加双引号)。 在平常的使用中,最好都使用[[]]。

与单中括号相比,双中括号具有其他功能。 如,可以对其中正则使用逻辑&&和||和=〜。

#!/bin/bashVAR1="variable"VAR2="variable 2"if [[ (VAR1 == "variable")  ]]; then    echo "They are the same."else    echo "Not the same."fi# 使用 &&[[ ($VAR1 == variable) && ($VAR2 == "variable 2") ]] && echo "They are the same again."

#!/bin/bashdigit=4if [[ $digit =~ [0-9] ]]; then    echo "$digit is a digit"else    echo "$digit isn't a digit"filetter="abc"if [[ $letter =~ [0-9] ]]; then    echo "$letter is a digit"else    echo "$letter isn't a digit"fi# Output# 4 is a digit# abc isn't a digit

怎么使用 For 循环

for循环的使用如下:

for VARIABLE_NAME in ITEM_1 ITEM_Ndo  command Adone

例如:

#!/bin/bashfor COLOR in red green bluedo  echo "COLOR: $COLOR"done# Output# COLOR: red# COLOR: green# COLOR: blue

可以在其中使用变量,如下:

#!/bin/bashCOLORS="red green blue"for COLOR in $COLORSdo  echo "COLOR: $COLOR"done

用 for 循环重命名文件

我们举个简单的例子,用for循环重命名当前目录下的jpg图片。

#!/bin/bashIMGS=$(ls *jpg)DATE=$(date +%F)for IMG in $IMGSdo  echo "Renaming ${IMG} to ${DATE}-${IMG}"  mv ${IMG} ${DATE}-${IMG}done

image-20210213170152011

怎么传参

执行脚本的时候,后面可以跟着很多参数,如:

$ scriptname param1 param2 param3

param1 到 param3 称为可选参数, 可以在脚本中用 $0, $1, $2等,来引用这些参赛。例如:

#!/bin/bashecho "'\$0' is $0"echo "'\$1' is $1"echo "'\$2' is $2"echo "'\$3' is $3"

输出:

$ ./param.sh'$0' is ./param.sh'$1' is'$2' is'$3' is

$0 参数0返回的是当前执行文件的名字,包括路径。

可以用 $@ 接受所以的参数。

#!/bin/bashfor PARAM in $@do  echo "Param is: $PARAM"done

Using this script:

$ ./params.sh a b c d e fParam is: aParam is: bParam is: cParam is: dParam is: eParam is: f

怎么接收用户输入

用户输入称为STDIN。可以将read命令与-p(提示)选项一起使用来读取用户输入,它将输出提示字符串。 -r 选项不允许反斜杠转义任何字符。

read -rp "PROMPT" VARIABLE

例如:

#!/bin/bashread -rp "Enter your programming languages: " PROGRAMMESecho "Your programming languages are: "for PROGRAMME in $PROGRAMMES; do    echo "$PROGRAMME "done

运行:

$ ./read.shEnter your programming languages: go pyYour programming languages are:gopy

用大括号来表示范围 {}

如下所示,我们可以用大括号来表所一个数字或字母的范围。

$ echo {0..3}$ echo {a..d}# output: # 0 1 2 3# a b c d

你也可以在 for 循环中这么使用:

#!/bin/bashfor i in {0..9}; do   touch file_"$i".txt; done

This will create different file names with different modification times.

$ ls -al file_*-rw-rw-r-- 1 razeen razeen 0 2月  14 09:54 file_0.txt-rw-rw-r-- 1 razeen razeen 0 2月  14 09:54 file_1.txt-rw-rw-r-- 1 razeen razeen 0 2月  14 09:54 file_2.txt...

怎么使用While

当 While 后的表达式结果为 true时,执行循环内语句。

#!/bin/bashi=1while [ $i -le 5 ]; do  echo $i  ((i++))done

Output:

12345

退出码/返回码 是什么?

每个命令都返回退出状态,范围为0-255。 0代表成功,非0代表错误。 可以用来进行错误检查。

数值含义

成功

返回内置命令,从而提示错误

126

命令找到了,但不是可执行的

127

没有找到命令

128+N

由于接收到信号N,命令退出

怎么检查退出码

特别声明:以上内容(如有图片或视频亦包括在内)为本平台用户上传并发布,本平台仅提供信息存储服务。


上篇:逆战官方网站

下篇:逆战 The Viral Factor