Shell 基础

Lesson1 - shell 脚本简介

Shell script 是解释型语言,而不是编译型语言 shell 分好多种,如果想看你的操作系统中支持哪几种,可以执行如下命令:

cat /etc/shells

输出如下(每个人的不一样):

# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.
/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh

新建一个 hello.sh 文件

touch hello.sh

.sh 后缀名不是必要的,它不影响 shell 脚本的运行 执行 ls -al 命令可以看到更多的有关 hello.sh 的信息:

total 0drwxr-xr-x   3 liusilong  staff    96 Jan 30 15:03 .drwxr-xr-x@ 37 liusilong  staff  1184 Jan 30 15:03 ..-rw-r--r--   1 liusilong  staff     0 Jan 30 15:03 hello.sh

-rw-r--r-- 表示对我自己是 rw(可读可写);对 group 是 r(只读);对 user 也是 r(只读) shell script 的第一行是指定 bash 的位置,可以通过 which bash 命令还获取操作系统中 bash 的位置。所以shell 脚本中第一行一般为:

#! /bin/bash

接着我们来输出一个 Hello world

#! /bin/bash
echo "Hello world"

接着我们使用 ./hello.sh 命令来执行这个 shell 脚本。会出现如下:

zsh: permission denied: ./hello.sh

因为 hello.sh 是仅仅只有读写权限的:-rw-r--r--,并没有可执行权限,我们使用命令 chmod +x hello.sh 来让 hello.sh 拥有可执行权限,执行之后,hello.sh 的权限信息就会为:-rwxr-xr-x

Lesson2 - 使用变量及注释注释

注释是以 # 开头

#! /bin/bash# 这是一行注释echo "hello world" # 这里也是注释

变量分为两种,一种是系统变量,一种是用户定义的变量 一般的,系统变量都是大写,用户自定义变量都是小驼峰

系统变量:

echo $BASHecho $BASH_VERSIONecho $HOMEecho $PWD

用户自定义变量:

name=Mark
val=10
echo The name is $name
echo value is $val

Lesson3 - 读取用户输入

我们可以使用 read 命令来接受用户的输入,如下:

read name

意思就是读取用户的输入,然后将用户输入保存在变量 name 中 完整例子:

#! /bin/bash
# Read User Input
echo "Enter name :"
read name
echo "Entered name : $name"

接收多个用户输入如下:

#! /bin/bash
# Read User Input
echo "Enter name :"
read name1 name2 name3
echo "Entered name : $name1, $name2, $name3"

执行如下(假设输入为: a b c):

Enter name :
jack rose tom
Entered name : jack, rose, tom

上面的 read 命令是换行输入,我们也可以单行输入

read -p "username: " user_name
echo "username is $user_name"

输出:

username: liusilong
username is liusilong

我们可以使用 -sp 来输入密码,就是让输入的密码不显示

read -p "username: " user_name
read -sp "password: " pass_word # 密码输入时不显示
echo # 换行
echo "username is $user_name"
echo "password is $pass_word"

输出:

username: liusilong
password: 
username is liusilong
password is 12345

将用户输入的多个值保存到一个数组中

echo "Enter names:"
# -a 表示让 shell 读取一个数组(array),names 为数组变量
read -a names
echo "names : ${names[0]}, ${names[1]}"

输出:

Enter names:
jack rose
names : jack, rose

如果我们在 read 后面不写接收用户输入的变量

echo "Enter name : "
# read 后面并没有有用于接受用户输入的变量
read
# 使用内置变量 REPLAY 来获取用户输入
echo "name is $REPLY"

输出:

Enter name : 
jack
name is jack

Lesson4 - shell 脚本传参

shell 脚本中定义参数是 $1, $2, $3 等等,不能写 $0,因为 $0 模式是该 shell 脚本的名称。例子如下:

#! /bin/bash
echo $1 $2 $3

这样我们在执行上述 shell 脚本的时候,后面就可以带上参数:

./hello.sh jack rose tom

输出如下:

jack rose tom

还有一种就是将接收到的参数保存到数组里面:

echo "Enter name: " $1 $2 $3
# 定义一个变量 args,为一个数组
args=("$@")
echo "输入的参数为: $@"
echo "参数的个数为: $#"

执行 ./hello.sh jack rose tom 输出:

Enter name:  jack rose tom
输入的参数为: jack rose tom
参数的个数为: 3

Lesson5 - if 语句(if..then, if..then..else, if..elif..else)

shell 中 if 的基本句法如下:

if [ condition ]
then
    statement
fi

还有一种写法是将 condition 放在双小括号里面:

if ((condition))
then
    statement
fi

说明:如果 condition == true 则执行 then 下面的 statement 语句块,statement 语句块执行完成之后,需要一个 fi 来结尾表示这个 if 语句的结尾。 shell 中的整型比较:

-eq 相等 if [ "$a" -eq "$b" ] (a == b)
-ne 不等 if [ "$a" -ne "$b" ] ( a != b)
-gt 大于 if [ "$a" -gt "$b" ]
-lt 小于 if [ "$a" -lt "$b" ]
-ge 大于等于 if [ "$a" -ge "$b" ]
-le 小于等于 if [ "$a" -le "$b" ]
< 小于 if (($counter < 20))
...

注意:如果我们使用 -eq 这样的比较两个整数的大小,则条件可以直接放到方括号里面;如果我们使用普通的运算符来比较,条件就需要放到双小括号里面。

切记不能写成 if (( $counter -gt 9 ))

案例:

count=10
if [ $count -ge 9 ]
then
    echo "condition is true"
fi
if (($count > 9))
then
    echo "right"
fi

字符串比较:

= - is equal to - if [ "$a" = "$b" ]
== - is equal to - if [ "$a" == "$b" ]
!= - is not equal to - if [ "$a" != "$b" ]
< - is less than, in ASCII alphabetical order - if [[ "$a" < "$b" ]]
> - is greater than, in ASCII alphabetical order - if [[ "$a" > "$b"]]
-z - string is null, that is, has zero length

案例:

word="abc"
if [ $word == "abc" ]
then
    echo "condition is true"
fi
letter="a"
if [[ $letter < "b" ]]
then
    echo "a less than b"
fi

if..then..else 案例

letter="a"
if [[ $letter == "b" ]]
then
    echo "condition is true"
else
    echo "condition is false"
fi

if..elif..else 案例

grade=90
if (($grade < 60))
then
    echo "not good"
elif (($grade > 60 && $grade < 80))
then
    echo "good"
else 
    echo "very good"
fi

Lesson6 - File test operators

下面的例子中,编写一个程序用来检测文件是否存在:

# -e 和结尾出的 \c 是为了让光标不换行
echo -e "Enter the name of the file: \c"
# 将用户输入的文件名称保存在 file_name 变量中
read file_name
# -e 用来判断该文件是否存在
if [ -e $file_name ]
then
    echo "$file_name found"
else
    echo "$file_name not found"
fi

测试:

➜  shell ./hello.sh              
Enter the name of the file: test
test not found
➜  shell touch test
➜  shell ./hello.sh
Enter the name of the file: test
test found

File 相关的操作符:

  • -e 判断文件是否存在
  • -f 判断该文件是否存在并且是否是一个常规文件
  • -d 判断文件是否是目录文件
  • -c 判断文件是否是文本文件,如 text 文件
  • -b 判断文件是否是 block file,如图片,音频,视频
  • -s 判断文件是否为空文件
  • -r 判断文件是否有可读权限
  • -w 判断文件是否有可写权限
  • -x 判断文件是否有可执行权限

向 test 中写入内容

cat > test 我是写入的内容 接着按 control + d 保存退出 注意:cat > test 是 test 文件中的内容被完全覆盖 cat >> test 是向 test 文件中继续写入内容,不覆盖

Lesson7 - 向文件中写内容

下面的案例是需求如下: 用户输入文件名称,检查文件是否存在,如果存在再检查该文件是否有写入权限,如果有写入权限就写入内容。

# -e 和结尾出的 \c 是为了让光标不换行
echo -e "Enter the name of the file: \c"
# 将用户输入的文件名称保存在 file_name 变量中
read file_name
if [ -f $file_name ] # ①
then
    if [ -w $file_name ] # ②
    then
        echo "输入要写入的内容,按 ctrl+d 退出"
        cat >> $file_name # ③
    else
        echo "该文件没有可写权限"
    fi
else
    echo "$file_name not exists"
fi

说明:
①:检查用户输入的文件是否存在
②:检查该文件是否有可写权限
③:向该文件中写入内容

一般的,我们如果直接使用命令如:touch demo 创建一个 demo 文件的情况下,该文件是有可写权限的,如下:

image

那么我们为了测试 ② 处的代码,可以手动移除 demo 文件的可写权限,执行命令 chmod -w demo 即可。

image

然后我们可以执行命令 chmod +w demo 即可重新设置 demo 文件的可写权限。

Lesson8 - 逻辑运算符 AND

age=20
if [ "$age" -gt 18 ] && [ "$age" -lt 30 ]
then
    echo "valid age"
else
    echo "age not valid"
fi

另外一种写法是:if [ "$age" -gt 18 -a "$age" -lt 30 ]
还有一种写法是:if (( $age >18 && $age < 30 ))
或者: if [[ "$age" -gt 18 && "$age" -lt 30 ]]

Lesson9 - 逻辑运算符 OR

逻辑或 和 逻辑与 运算符的语法一样,就是表达的意思不一样 逻辑与 需要 condition 中的所有条件都满足,当前的 condition 才为 true 逻辑或 只需要 condition 中的有一个条件满足,当前的 condition 就为 true

Lesson10 - 算术运算符

如果我们直接在 shell 脚本中执行如下命令:

#! /bin/bash
echo 1+1

执行之后并不会输出 2,而是会直接输出 1+1,因为 echo 会把之后的字符都当成字符串,并不会去执行算术运算符

我们使用如下的方式去执行两个数之间的运算

num1=20
num2=5

echo $(( num1 + num2 ))
echo $(( num1 - num2 ))
echo $(( num1 * num2 ))
echo $(( num1 / num2 ))
echo $(( num1 % num2 ))

输出:

25
15
100
4
0

注意:需要使用双括号开包裹,并且前面需要有一个 $ 符号

Lesson11 - 浮点型运算

我们将上一节中的 num1 的值由 20 改成 20.5,就会计算出错,如下:

num1=20.5
num2=5
echo $(( num1 + num2 ))
echo $(( num1 - num2 ))
echo $(( num1 * num2 ))
echo $(( num1 / num2 ))
echo $(( num1 % num2 ))

执行输入结果如下:

./hello.sh: line 8: 20.5: syntax error: invalid arithmetic operator (error token is ".5")
./hello.sh: line 9: 20.5: syntax error: invalid arithmetic operator (error token is ".5")
./hello.sh: line 10: 20.5: syntax error: invalid arithmetic operator (error token is ".5")
./hello.sh: line 11: 20.5: syntax error: invalid arithmetic operator (error token is ".5")
./hello.sh: line 12: 20.5: syntax error: invalid arithmetic operator (error token is ".5")

很明显,使用整型运算符的语法计算浮点型是行不通的。

要计算浮点型数据,我们需要借助系统内置的一个工具 bc,我们可以使用命令 man bc 来查看 bc 的相关文档。案例如下:

num1=20.5
num2=5

echo "$num1 + $num2" | bc
echo "$num1 - $num2" | bc
echo "$num1 * $num2" | bc
echo "$num1 / $num2" | bc
echo "$num1 % $num2" | bc

输出:

25.5
15.5
102.5
4
.5

注意:20.5 / 5 应该等于 4.1 的,但是上面计算你的结果是 4。这是个问题,我们可以通过 scale 来指定保留几位小数。

num1=20.5
num2=5

# 结果保留两位小数,输出的结果为 4.10
echo "scale=2;$num1 / $num2" | bc

还可以求平方根,立方等:

num3=4
# 求 4 的开平方根;-l 表示使用标准的 mathlib;具体用法可以 man bc
echo "scale=2;sqrt($num3)" | bc -l
# 求 3 的立方
echo "scale=2;3^3" | bc -l

有关 bc 的更多用法,可以通过 man bc 查看文档。

Lesson12 - case 语句

case 的语法如下:

case expression in 
    pattern1 )
        statements ;;
    pattern2 )
        statements ;;
    ...
esac

案例:

vehicle=$1
case $vehicle in 
    "car" )
        echo "Rent of $vehicle is 100 dollar" ;;
    "van" )
        echo "Rent of $vehicle is 80 dollar" ;;
    "bicycle" )
        echo "Rent of $vehicle is 5 dollar" ;;
    "truck" )
        echo "Rent of $vehicle is 150 dollar" ;;
    * ) 
        echo "Unknow vehicle"
esac

里面的 * 代表默认条件,类似 Java 中的 switch-case 语句中的 default 分支

Lesson13 - case 例子

判断用户输入的字符:

echo -e "Enter some character: \c"
read value

case $value in 
    [a-z] )
        echo "User entered $value a to z"
        ;;
    [A-Z] )
        echo "User entered $value A to Z"
        ;;
    [0-9] )
        echo "User entered $value 0 to 9"
        ;;
    ? )
        echo "User entered $value special character"
        ;;
    * )
        echo "Unknow input"
        ;;
esac

Lesson14 - 数组

# 定义一个数组
os=('ubuntu' 'windows' 'kali')

# 通过下标来添加或者更新元素
os[3]='mac'

# 通过下标删除数组中的元素
unset os[2]

# 输出数组中的所有数据
echo "${os[@]}"

# 输出数组中的第二个元素
echo "${os[1]}"

# 输出数组中所有的下标
echo "${!os[@]}"

# 输出数组的长度
echo "${#os[@]}"

string=afadsf

# 输出 afadsf
echo "${string[@]}"

# 输出 afadsf
echo "${string[0]}"

# 没有输出
echo "${string[1]}"

# 输出 1
echo "${#string[@]}"

Lesson15 - while 循环

while 的语法如下:

while [ condition ]
do
    command1
    command2
    command3
done

从 1 到 10 循环输出:

n=1

while [ $n -le 10 ] # 或者 while (( $n <= 10 ))
do
    echo "$n"
    n=$(( n+1 )) # 或者直接 (( n++ ))
done

Lesson16 - while 循环中的 sleep

我们下面的例子是每间隔一秒输出一个数,从 1 到 10

n=1

while [ $n -le 10 ]
do
    echo "$n"
    n=$(( n+1 ))
    sleep 1 # 单位是 秒
done

Lesson17 - 读取文件内容

使用 while 循环来读取文件内容

#! /bin/bash

while read p
do
    echo $p
done < hello.sh

上述代码中,我们就是读取的 hello.sh 脚本中的内容,如下:

#! /bin/bash

while read p
do
echo $p

使用 cat 读取 hello.sh 文件内容

#! /bin/bash

cat hello.sh | while read p
do
    echo $p
done

使用 IFS 读取 hello.sh 文件内容

#! /bin/bash

while IFS= read -r line
do
    echo $line
done < hello.sh

Lesson18 - until loop

until loop 的语法如下:

until [ condition ]
do
    command1
    command2
    command3
done

也就是说知道 condition 满足,do..done 中间的语句就不执行了,否则会一直执行 do..done 中的语句

下面写一个例子用来输入 1..9

n=1

until [ $n -ge 10 ]
do
    echo $n
    n=$(( n+1 )) # 或者直接这样 (( n++ ))
done

上述代码中,condition 是 n >= 10,所以会输出 1..9,如果需要输出 1..10 则只需要将 condition 改成 $n -gt 10 即可。

Lesson19 - For 循环

For 循环的几种语法如下:

for VARIABLE in 1 2 3 4 5 .. N
do
    command1
    command2
    commandN
done

# OR ------------

for VARIABLE in file1 file2 file3
do
    command1 on $VARIABLE
    command2
    commandN
done

# OR ------------

for OUTPUT in $(Linux-Or-Unix-Command-Hrer)
do
    command1 on $OUTPUT
    command2
    commandN
done

#OR ------------
# 类似 Java 中的 for 循环
for ((Exp1; Exp2; Exp3))
do
    command1
    command2
    command3
done

案例:输出 1 2 3 4 5

for i in 1 2 3 4 5
do
    echo $i
done

如果你的 bash 的版本是 3.x ,还可以这样写:

for i in {1..5}
do
    echo $i
done

使用类似 Java 中的 for 循环写法如下: 输出:0 1 2 3 4

for (( i=0; i<5; i++ ))
do
    echo $i
done

Lesson20 - 使用 for 循环执行命令

下面的例子中,我们使用 for 循环分别执行 ls pwd date 这三个命令,如下:

for command in ls pwd date
do
    echo "---$command-----" # 输出命令名称
    $command # 执行命令
done

输出如下:

---ls-----
demo        hello.sh    test
---pwd-----
/Users/liusilong/Dev/shell
---date-----
Sat Feb  1 20:59:22 CST 2020

输出当前目录下所有是文件夹的文件

# * 表示当前文件夹下的所有文件
for item in *
do
    if [ -d $item ] # -d 用来判断该文件是否为文件夹
    then
        echo $item
    fi
done

Lesson21 - Select 循环

select 循环为我们提供了一个列表供我们选择,下面例子中我们提供一个名字的列表,然后让用户选择:

select name in mark john tom ben
do
    echo "$name selected"
done

运行上述脚本,会给我们提供代码中的 4 个名字的选项列表:

image

接着我们选择第二个名称,输入 2,如下:

image

select 循环也可以和 case 语句结合使用,如下:

select name in mark john tom ben
do
    case $name in
        mark )
            echo mark selected
            ;;
        john )
            echo john selected
            ;;
        tom )
            echo tom selected
            ;;
        ben )
            echo ben selected
            ;;
        * ) # default
            echo "Error"
            ;;
        esac
done

输出如下:

image

Lesson22 - Break and Continue

break 用来退出当前循环。 下面的例子中,我们写一个从 1 到 10 的 for 循环,但是只输出前五个数字:

for (( i=1; i<=10; i++ ))
do
    if [ $i -gt 5 ] # 如果 i > 5
    then 
        break # 退出当前循环
    fi
    echo $i
done

输出:

1
2
3
4
5

continue 就是跳过本次循环,继续执行下一次。

我们同样使用 for 循环来输出 1 到 10,但是不输出 3 和 6,即,遇到 3 或者 6 就跳过本次循环。

for (( i=1; i<=10; i++ ))
do
    if [ $i -eq 3 -o $i -eq 6 ] # 类似 Java 中的 if ( i == 3 || i == 6 )
    then 
        continue
    fi
    echo $i
done

输出:

1
2
4
5
7
8
9
10

Lesson23 - Functions

shell 中方法的基本语法如下:

function name() {
    statements
}

当然,function 关键字也可以省略:

name() {
    statements
}

例子:

# 定义一个 hello 方法
function hello(){
    echo "Hello"
}

# 定义一个 quit 方法
quit() {
    exit
}

# 调用 hello 方法
hello

echo "foo"

# 调用 quit 方法
quit

输出:

Hello
foo

接受参数的方法:

# 定义一个 print 方法,并接受一个参数
function print(){
    echo $1
}

# 调用 print 方法,并传递参数
print jack
print rose

输出:

jack
rose

Lesson24 - 局部变量(Local variables)

下面是一个带有局部变量的方法的例子:

function print(){
        # 定义一个局部变量 name
    name=$1
    echo "the name is $name"
}

# 调动 print 方法,并传入参数
print Shell

输出: the name is Shell

我们把上述代码改成如下:

function print(){
        # 定义一个局部变量 name
    name=$1
    echo "the name is $name"
}

# 定义一个全局变量 name
name="Tom"

echo "the name is $name : Before"
# 调动 print 方法,并传入参数
print Shell

echo "the name is $name : After"

这个输出如下:

the name is Tom : Before
the name is Shell
the name is Shell : After

看到了吗?最后一行输出中,明明调用的是 全局变量 name,为什么输出的是 局部变量 name 的值呢?

出现这种情况,我们需要在声明局部变量的时候,在其之前加上 local 关键字,否则局部变量的改变会影响到全局变量。

只需将上述代码中的 name=$1 改为 local name=$1,这样,输出就正常了,局部变量和全局变量之间互不影响了。

原与译
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容

  • 第一节 Shell概述 1.Shell是什么 Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送...
    littlexjing阅读 1,783评论 0 1
  • 这是我第一次尝试使用双拼输入法翻译一篇日本的Liunx基础教材上的一章。共花费一周左右。 shell的使用 前言 ...
    今後次阅读 1,022评论 0 4
  • 概述 首先,咱们来了解一下,什么是Shell。操作系统内核给我们提供了各种接口,同时也提供了各种用户层的库,理论上...
    keysaim阅读 1,282评论 0 0
  • Shell基础 Shell概述 1、Shell是什么 Shell是一个命令行解释器,它为用户提供了一个向Linux...
    全村滴希望阅读 469评论 0 0
  • shell 是英语“壳,外壳”的意思。你可以把它想象成嵌入在 Linux 这样的操作系统中的一个“微型编程语言”。...
    Zoulf阅读 547评论 0 0