Dskpimc? · 2020年09月06日

Bash shell语言学习

平时用惯了被人搭建的环境、脚本,总是make xxx/run xxx,都忘记了如何自己搭建了。现在开始要自己学习下啦~

第一件就是terminal设置,为我们常见的命令设置一些快捷键,如gvim、cd ..、ls -l等等。我是在terminal中写一个bash脚本。可以在terminal中输入echo $SHELL或echo $0或env命令来判断现在terminal是csh还是bash。$0是指当前正在运行的进程,所以,当在 shell 中输出 $0 时,即是 shell 的名称。但是,如果是在脚本中输出,则是脚本的名字。如下图:
111.PNG

.如果想切换terminal的shell设置:

终端命令:chsh -s /bin/bash和chsh -s /bin/csh退出以后重登陆将会更改默认SHELL。

对于bash shell的快捷键和环境变量设置可以在.bashrc文件中设置,该文件在home目录下,为隐藏文件。对于c shell的则在.cshrc中设置。如下为设置的环境变量和alias举例。
222.png

对于csh设置环境变量命令是:setenv FILTERS FILTERBIN.RES,对于bash为:export FILTERS=FILTERBIN.RES。对于常用的环境变量建议写到.shrc文件中。

bash脚本第一行会有#!/bin/bash,指定了程序将使用的解释器。linux有很多解释器,如bash、zsh、sh、csh和ksh等。可以在terminal中输入:cat /etc/shells,看系统支持哪些shell。如果在脚本中不包含解释器,则使用默认shell执行命令,因此代码有可能正常执行,使用echo $SHELL可以查看目前运行的解释器。在shell中,注释以#开始,#后面的内容都会被忽略,但#!除外。

变量:
变量是指向内存的一块区域,变量有对应的变量名和值,可以存储一些可能更改的数据。在shell中定义变量不需要指定变量的类型。变量名区分大小写,要使用变量,必须在变量前面加$符号。如: VARIABLE=“value” echo $VARIABLE echo ${VARIABLE}。

提示:1、可以把命令执行后的输入结果赋值给一个变量,如:LIST=$(ls),SERVER=$(hostname);

2、read -p命令可以用于从接收键盘的输入,如: read -p “input a strin” NAME,从键盘输入的信息会存储在NAME当中。

测试(判断):
测试主要用于条件判断。[ condition-to-test-for ],如[ -e /etc/passwd ],注意的是[]前后必须有空格,[ -e /etc/passwd]是错误的写法。

1、文件测试操作

-d FILE_NAM  # True if FILE_NAM is a directory
-e FILE_NAM  # True if FILE_NAM exists
-f FILE_NAM  # True if FILE_NAM exists and is a regular file
-r FILE_NAM  # True if FILE_NAM is readable
-s FILE_NAM  # True if FILE_NAM exists and is not empty
-w FILE_NAM  # True if FILE_NAM has write permission
-x FILE_NAM  # True if FILE_NAM is executable

2、字符串测试操作

-z STRING  # True if STRING is empty
-n STRING  # True if STRING is not empty
STRING1 = STRIN2 # True if strings are equal
STRING1 != STRIN2 # True if strings are not equal

3、算术测试操作

var1 -eq var2  # True if var1 is equal to var2
var1 -ne var2  # True if var1 not equal to var2
var1 -lt var2  # True if var1 is less than var2
var1 -le var2  # True if var1 is less than or equal to var2
var1 -gt var2  # True if var1 is greater than var2
var1 -ge var2  # True if var1 is greater than or equal to var2

判断比较:
1、if语句

if [ condition-is-true ]
then
  command 1
  command 2
    ...
    ...
  command N
fi

if-else-fi

if [ condition-is-true ]
then
  command 1
elif [ condition-is-true ]
then
  command 2
elif [ condition-is-true ]
then
  command 3
else
  command 4
fi

case语句可以实现和if一样的功能,但是当条件判断很多的时候,使用if不太方便,比如使用if进行值的比较

case "$VAR" in
  pattern_1)
    # commands when $VAR matches pattern 1
    ;;
  pattern_2)
    # commands when $VAR matches pattern 2
    ;;
  *)
    # This will run if $VAR doesnt match any of the given patterns
    ;;
esac

shell脚本支持逻辑与和逻辑或
逻辑与 &&逻辑或 ||

Example:mkdir tempDir && cd tempDir && mkdir subTempDir这个例子中,如果创建tempDir成功,执行后面的cd,继续创建subTempDir

循环:
可以通过循环执行同一个代码块很多次。

  1. for循环
for VARIABLE_NAME in ITEM_1 ITEM_N
do
  command 1
  command 2
    ...
    ...
  command N
done

Example

#!/bin/bash
COLORS="red green blue"
for COLOR in $COLORS
do
  echo "The Color is: ${COLOR}"
done

Another Example,记住for后面必须带两个括号

for (( VAR=1;VAR<N;VAR++ ))
do
  command 1
  command 2
    ...
    ...
  command N
done

在当前所有txt文件前面追加new实现重命名

#!/bin/bash
FILES=$(ls *txt)
NEW="new"
for FILE in $FILES
do
  echo "Renaming $FILE to new-$FILE"
  mv $FILE $NEW-$FILE
done

while 循环
当所给的条件为true时,循环执行while里面的代码块

while [ CONNDITION_IS_TRUE ]
do
   Commands will change he entry condition
  command 1
  command 2
    ...
    ...
  command N
done

判断条件可以是任意的测试或者命令,如果测试或命令返回0,则表示条件成立,如果为非0则退出循环,如果一开始条件就不成立,则循环永远不会执行。

例子 一行一行读取文件内容

#!/bin/bash
LINE=1
while read CURRENT_LINE
do
  echo "${LINE}: $CURRENT_LINE"
  ((LINE++))
done < /etc/passwd
 This script loops through the file /etc/passwd line by line

注意⚠️continue 用于结束本次循环break 用于结束整个循环

参数传递:
当我们运行脚本的时候,可以传递参数供脚本内部使用$ ./script.sh param1 param2 param3 param4这些参数将被存储在特殊的变量中

$0 -- "script.sh"
$1 -- "param1"
$2 -- "param2"
$3 -- "param3"
$4 -- "param4"
$@ -- array of all positional parameters

$# -- 传递给脚本总的参数数目;
$* -- 传递给脚本总的参数组成的字符串
$? -- 上一个代码或shell脚本在shell中退出的情况,如果正常退出则为0,非正常退出则为非0值;$?其实就是存储退出状态吗,任何命令执行完成后都会产生一个退出状态码,范围0~255,状态码可以用来检查错误,0表示正确执行并正常退出。当然我们可以自定义退出状态码,默认的状态码是上一条命令执行的结果,我们可以通过exit来自定义状态码:exit 0、exit 1、exit 2、... 、exit 255.

这些变量可以在脚本中的任何地方使用,就像其他全局变量一样

函数:
可以把一些常用的带有关联性的命令和语句封在一个函数内,从程序的其他地方调用,函数必须先定义后调用。通常可以把函数定义在程序开始或主程序之前。

语法:

function function_name() {
    command 1
    command 2
    command 3
      ...
      ...
    command N
}

调用函数只需简单的给出函数名字

#!/bin/bash
function myFunc () {
    echo "Shell Scripting Is Fun!"
}
myFunc # call

函数的参数传递:

和脚本一样,也可以给函数传递参数完成特殊的任务,第一个参数存储在变量$1中,第二个参数存储在变量$2中...,$@存储所有的参数,参数之间使用空格分割 myFunc param1 param2 param3 ...

变量的作用范围:

全局变量: 默认情况下,shell中的变量都定义为全局变量,你可以从脚本中的任何位置使用变量,但是变量在使用之前必须先定义本地变量: 本地变量只能在方法内部访问,可以通过local关键词定义一个本地变量,定义一个本地变量的最佳实践是在函数内部。

通配符:
使用通配符可以完成特定的匹配
一些常用的通配符* 可以通配一个或多个任意字符

*.txt
hello.*
great*.md

?匹配一个字符

?.md
Hello?

[]匹配括号内部的任意一个字符

He[loym], [AIEOU]

[!]不匹配括号内的任何字符

`[!aeiou]`

预先定义的通配符 [[:alpha:]]

    [[:alnum:]] [[:space:]]
    [[:upper:]]] [[:lower:]]
    [[:digit:]]

匹配通配符 有些情况下我们想匹配* 或?等特殊字符,可以使用转义字符*?

调试:
bash提供一些可选项帮助你调试程序Some Options:

  1. -x option

它在执行时打印命令和参数。它被称为打印调试,跟踪或x跟踪。我们可以通过修改第一行来使用它

  1. -e option

它代表“出错”。如果命令以非零退出状态退出,这将导致脚本立即退出。

  1. -v option

它在读取时打印shell命令/输入行。

注意:这些选项可以组合使用,一次可以使用多个选项!

!/bin/bash-xe
!/bin/bash-ex
!/bin/bash-x-e
!/bin/bash-e-x

相关阅读

作者:谷公子
首发博客:https://blog.csdn.net/W1Z1Q/article/details/101078966
推荐阅读
关注数
19637
内容数
1303
主要交流IC以及SoC设计流程相关的技术和知识
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息