站点图标

Linux Bash 简要教程

  在本节中,我们将介绍Bash Terminal的一些基础语法。

一、文件目录相关

  1. ls i.e. list storage:显示当前目录下的文件与文件夹。
  2. pwd i.e. print work directory:显示当前目录。
  3. cd i.e. change directory:使用dir/dir/来切换相对目录(个人习惯使用./);使用/dir/dir来切换绝对目录。

1.1 pushd和popd

  为了实现多个目录的相互跳转,这里使用一个目录堆来完成。当前的目录如下:

.
├── 01.sh
├── T1
├── T2
└── T3

  使用dirs可以查看该堆:

xjt@u16:~/mk/Bash$ dirs -p -v
 0  ~/mk/Bash
 1  ~/mk/Bash/T1

  我已经向该堆添加了两个目录。下面我们使用pushd可以向其中添加目录:

xjt@u16:~/mk/Bash$ pushd T2/
~/mk/Bash/T2 ~/mk/Bash ~/mk/Bash/T1
xjt@u16:~/mk/Bash/T2$ dirs -p -v
 0  ~/mk/Bash/T2
 1  ~/mk/Bash
 2  ~/mk/Bash/T1
xjt@u16:~/mk/Bash/T2$ 

  之后在使用pushd +n来切换目录:

xjt@u16:~/mk/Bash/T2$ pushd +2
~/mk/Bash/T1 ~/mk/Bash/T2 ~/mk/Bash
xjt@u16:~/mk/Bash/T1$ 

  出栈则使用popd来完成:

xjt@u16:~/mk/Bash/T1$ popd +0
~/mk/Bash/T2 ~/mk/Bash
xjt@u16:~/mk/Bash/T2$ dirs -p -v
 0  ~/mk/Bash/T2
 1  ~/mk/Bash

1.2 文件与查找

  1. file:用于查看文件属性。
  2. locate:用于模糊查找文件。

1.3 创建文件夹与文件

  1. mkdir:创建文件夹。
  2. touch:创建文件。

1.4 拷贝与移动

  1. cp:拷贝。
  2. mv:移动。

二、文件编辑

2.1 concatenate

  bash使用cat来连接文件,我们有如下文件:

.
├── file1.txt
└── file2.txt

  我们可以使用cat来打印文件内容:

xjt@u16:~/mk/Bash$ cat file1.txt 
hello
xjt@u16:~/mk/Bash$ cat file2.txt 
world

  同时能使用>>来向文件中追加内容,使用>覆写

xjt@u16:~/mk/Bash$ cat >> file1.txt 
world
xjt@u16:~/mk/Bash$ cat file1.txt 
hello
world
xjt@u16:~/mk/Bash$ 

当我们结束追加内容的时候,使用Ctrl+D来结束命令。欲清空文件的内容则可以使用cat /dev/null > file1.txt来完成,该命令是将一个文件的内容覆写到另外一个文件,追加则使用>

2.2 more & less

  当我们想要查看文件内容的时候,可以使用more或者less来查看。使用more一次跳转多行,less则可以一行一行地跳转。两者均可以使用q键退出。

2.3 文本编辑器

  linux下的编辑器常用的有nano、vim、gedit。其中nano操作简单,在界面的下方有相应的提示;vim和gedit则没有,但是功能更加多样,比如同时处理多个文件等。

  接下来,我们将介绍如何编写bash脚本。

三、开始

  bash脚本与在终端中使用相同,直接使用命令即可,下面是一段简单的脚本,同时tree如下。

#! /bin/bash

ls
echo "Hello World"

# tree
# .
# └── run.sh

在第一行的#! /bin/bash表示除此之外的所有#引导的内容均为注释。值得注意的是,我们直接使用./run.sh是无法直接运行的,我们要么使用bash run.sh,要么给予它+x的权限。例如:

xjt@u16:~/mk/Bash$ bash run.sh 
run.sh
Hello World

xjt@u16:~/mk/Bash$ chmod +x run.sh 
xjt@u16:~/mk/Bash$ ./run.sh 
run.sh
Hello World

sh和bash有着相似的内容,但对于规则的兼容性不同。对于ubuntu来说,/bin/sh指向/bin/bash,但是也可以使用-posix来指定其模式。

四、基本语法

4.1 if

  下面是一段基础的逻辑判断:

Name="XJT"

if [ "$Name" == "XJT" ]
then
    echo "Your name is XJT"
else
    echo "Your name is not XJT"
fi

在上面的代码中,有几个需要注意的地方。一是变量赋值之间是不允许有空格,即Name="XJT",而不是Name = "XJT";二是if之后不使用(),而是使用[],同时需要注意括号前后均有空格,即if [ $val ],而非if [$val]

  接下来我们看一下一般变量的情况。

Num1=3
Num2=5

if [ $Num1 -gt $Num2 ]
then
    echo "$Num1 is greater than $Num2"
else
    echo "$Num1 is less than $Num2"
fi

  接下来看对于文件的处理。

File="hello.txt"

if [ -f $File ]
then 
    echo "$File Exist"
else
    echo "$File not Exist"
fi

# xjt@u16:~/mk/Bash$ tree
# .
# └── run.sh

# 0 directories, 1 file
# xjt@u16:~/mk/Bash$ ./run.sh
# hello.txt not Exist

# xjt@u16:~/mk/Bash$ touch hello.txt
# xjt@u16:~/mk/Bash$ tree
# .
# ├── hello.txt
# └── run.sh

# 0 directories, 2 files
# xjt@u16:~/mk/Bash$ ./run.sh
# hello.txt Exist
# xjt@u16:~/mk/Bash$ 

在上面的if中,我们使用-f来指定$File为文件。同样的,其他的标签如下:

  1. -d,是目录
  2. -e,文件存在,常用-f代替。
  3. -f,提供的字符串是文件。
  4. -g,文件已有group id。
  5. -r,可读。
  6. -s,大小不为零
  7. -u,已有user id。
  8. -w,可写。
  9. -x,可执行。

4.2 case

  case与C中的switch相同,下面来看一下它是如何运作的。

read -p "Input y/yes or n/no: " Input

case $Input in 
    [yY] | [yY][eE][sS])
        echo "yes!"
        ;;
    [nN] | [nN][oO])
        echo "no!"
        ;;
    *)
        echo "default output"
        ;;
esac

在上面的代码中,有几个需要注意的地方。一是在每一个分支的后面需要加上);二是每个分支结束需要加上;;;三是最后的*相当于其他语言中的default

4.3 for

  for循环与python相似,下面是一个最基本的for循环。

Array="1 2 3 4 5"

for it in $Array 
    do
        echo "$it"
done

  下面来看一个对文件重命名的脚本:

txtFiles=$(ls *.txt)
att="new"

for file in $txtFiles
    do
        echo "Rename $file to $att-$file"
        mv $file $att-$file
done

4.4 while

  接下来看一下如何使用while来读取一个文件夹的内容。

Line=1
while read -r CURRENT_LINE
    do
        echo "$Line: $CURRENT_LINE"
        ((Line++))
done < "./file.txt"

4.5 function

  下面是一个简单的Hello world函数。

function hello()
{
    echo "Hello world"
}

hello

  bash中含参函数和其他语言并不一样,其参数并不需要声明到()中,来看一个例子:

function sum()
{
    let ans=$1+$2
    echo "Sum: $ans"
}

sum 5 6
退出移动版