Abhishek Prakash 发布的文章

初学者们,让我们在这个大型的教程中来认识一下 Bash 脚本编程。

Shell 是 Linux 的核心部分,它允许你使用各种诸如 cdlscat 等的命令与 Linux 内核进行交互。

Bash 是 Linux 上众多可用的 Shell 中的一个。这些 Shell 主要的语法基本相同,但并非完全一样。Bash 是目前最受欢迎的 Shell,并在大多数 Linux 发行版中被设为默认 Shell。

当你打开一个终端或 SSH 会话时,即使你无法真切地看到它,你其实已经在运行着一个 Shell。

当你输入一个命令,它会被 Shell 解释。如果命令和语法是正确的,它就会被执行,否则你会看到一个错误。

当你可以直接运行 Linux 命令时,为什么还需要 Bash 脚本?

你可以直接在终端输入命令,它们就会被执行。

$ echo "hello world"
hello world

并且,同样的操作也可以在脚本中进行:

$ cat >> script.sh
#!/bin/bash

echo "hello world"
$ bash script.sh
hello world

那么,为什么我们需要 Shell 脚本呢?因为你不必一遍又一遍地输入同一个命令,你只需运行 Shell 脚本即可。

此外,如果你的脚本中有复杂的逻辑,把所有的命令都输入到终端中可能并不是一个好主意。

例如,如果你输入下面的命令,它会奏效,但这并不容易理解。不断地输入相同的命令(甚至要在 Bash 历史记录中搜索)会造成困扰。

if [ $(whoami) = 'root' ]; then echo "root"; else echo "not root"; fi

相反,你可以把命令放进 shell 脚本中,这样就更容易理解并且可以轻松运行了:

#!/bin/bash

if [ $(whoami) = 'root' ]; then
    echo "You are root"
else
    echo "You are not root"
fi

这还是比较简单的情况。尝试想象一下,一个复杂的脚本可能有五十行或一百行!

你将会学到什么?

在这个 Bash 脚本教程中,有九个部分。你将会学到:

  • 创建并运行你的第一个 Bash Shell 脚本
  • 使用变量
  • 在你的 Bash 脚本中传递参数和接受用户输入
  • 进行数学计算
  • 操作字符串
  • 使用条件语句,例如 if-else
  • 使用 forwhileuntil 循环
  • 创建函数
? 所有的部分都会给你一个简单的例子。如果你愿意,你可以通过访问每个部分的详细章节来更深入地学习。这些章节也都包含了实践练习。

这个教程的目标读者是谁?

这个教程适合任何想要开始学习 Bash Shell 脚本的人。

如果你是一名学生,而你的课程里包括了 Shell 脚本,那么这个系列就是为你准备的。

如果你是一个常规的桌面 Linux 用户,这个系列将会帮助你理解在探索各种软件和修复问题时遇到的大多数 Shell 脚本。你也可以使用它来自动化一些常见的、重复的任务。

在这个 Bash 脚本教程结束时,你应该可以编写简单的 Bash 脚本。

? 希望你已经拥有 Linux 命令行和编程语言的基础知识。

如果你对 Linux 命令行完全不熟悉,我建议你先掌握基础知识。

19 个你应该知道的基础而重要的 Linux 终端技巧

你应该了解如何在命令行中进入特定的位置。为了做到这一点,你需要理解 Linux 文件系统中的路径是如何工作的。

Linux 中的绝对路径和相对路径有什么不同

接下来,这个教程系列会给你介绍目录导航和文件操作的基本知识。

终端基础:Linux 终端入门

1、编写你的第一个 Bash Shell 脚本

创建一个名为 hello.sh 的新文件:

nano hello.sh

这将在终端中打开 nano 编辑器。在其中输入以下几行代码:

#!/bin/bash
echo "Hello World"

通过按 Ctrl+X 键可以保存并退出 nano 编辑器。

现在,你可以以以下方式运行 Bash Shell 脚本:

bash hello.sh

你应该可以看到以下的输出:

Hello World

另一种方式是首先赋予脚本执行权限:

chmod u+x hello.sh

然后这样运行它:

./hello.sh
? 你也可以使用基于图形用户界面的文本编辑器来编写脚本。这可能更适合编写较长的脚本。然而,你需要切换到保存脚本的目录中才能运行它。

恭喜!你刚刚运行了你的第一个 Bash 脚本。

Bash 基础知识系列 #1:创建并运行你的第一个 Bash Shell 脚本

2、在 Bash 脚本中使用变量

变量的声明方式如下:

var=some_value

然后可以像这样访问变量:

$var
? 在声明变量时,等号(=)前后不能有空格。

我们通过添加一个变量来修改前面的脚本。

#!/bin/bash
message="Hello World"
echo $message

如果运行这个脚本,输出仍然会保持不变。

Hello World
Bash 基础知识系列 #2:在 Bash 中使用变量

3、向 Bash 脚本传递参数

你可以在运行 Bash 脚本时以以下方式传递参数:

./my_script.sh arg1 arg2

在脚本中,你可以使用 $1 来代表第 1 个参数,用 $2 来代表第 2 个参数,以此类推。$0 是一个特殊变量,它代表正在运行的脚本的名字。

现在,创建一个新的 shell 脚本,命名为 arguments.sh,并向其中添加以下几行代码:

#!/bin/bash

echo "Script name is: $0"
echo "First argument is: $1"
echo "Second argument is: $2"

使其可执行并像这样运行它:

$ ./argument.sh abhishek prakash
Script name is: ./argument.sh
First argument is: abhishek
Second argument is: prakash

让我们快速看一下特殊变量:

特殊变量描述
$0脚本名称
$1$2...$9脚本参数
${n}10 到 255 的脚本参数
$#参数数量
$@所有参数一起
$$当前 shell 的进程 id
$!最后执行命令的进程 id
$?最后执行命令的退出状态

你也可以通过接受键盘输入使你的 Bash 脚本变得交互式。

为此,你必须使用 read 命令。你还可以使用 read -p 命令提示用户进行键盘输入,而不需要 echo 命令。

#!/bin/bash

echo "What is your name, stranger?"
read name
read -p "What's your full name, $name? " full_name
echo "Welcome, $full_name"

现在,如果你运行这个脚本,当系统提示你输入“参数”时,你必须输入。

$ ./argument.sh
What is your name, stranger?
abhishek
What's your full name, abhishek? abhishek prakash
Welcome, abhishek prakash
Bash 基础知识系列 #3:传递参数和接受用户输入

4、执行算术运算

在 Bash Shell 中执行算术运算的语法是这样的:

$((arithmetic_operation))

下面是你可以在 Bash 中执行的算术运算的列表:

操作符描述
+加法
-减法
*乘法
/整数除法(没有小数)
%模运算(只余)
**指数(a 的 b 次方)

以下是在 Bash 脚本中进行加法和减法的示例:

#!/bin/bash

read -p "Enter first number: " num1
read -p "Enter second number: " num2

sum=$(($num1+$num2))
sub=$(($num1-$num2))
echo "The summation of $num1 and $num2 is $sum"
echo "The substraction of $num2 from $num1 is $sub"

你可以执行 Shell 脚本,使用你选择的任意数字作为参数。

如果你尝试除法,会出现一个大问题。Bash 只使用整数。默认情况下,它没有小数的概念。因此,你会得到 10/3 的结果为3,而不是 3.333。

对于浮点数运算,你需要这样使用 bc 命令:

#!/bin/bash

num1=50
num2=6

result=$(echo "$num1/$num2" | bc -l)

echo "The result is $result"

这个时候,你将看到准确的结果。

    The result is 8.33333333333333333333

Bash 基础知识系列 #4:算术运算

5、在 Bash 脚本中使用数组

你可以使用 Bash 中的数组来存储同一类别的值,而不是使用多个变量。

你可以像这样声明一个数组:

distros=(Ubuntu Fedora SUSE "Arch Linux" Nix)

要访问一个元素,使用:

${array_name[N]}

像大多数其他的编程语言一样,数组的索引从 0 开始。

你可以像这样显示数组的所有元素:

${array[*]}

这样获取数组长度:

${#array_name[@]}
Bash 基础知识系列 #5:在 Bash 中使用数组

6、Bash 中的基础字符串操作

Bash 能够执行许多字符串操作。

你可以使用这种方式获取字符串长度:

${#string}

连接两个字符串:

str3=$str1$str2

提供子字符串的起始位置和长度来提取子字符串:

${string:$pos:$len}

这里有一个例子:

你也可以替换给定字符串的一部分:

${string/substr1/substr2}

并且你也可以从给定字符串中删除一个子字符串:

    ${string/substring}

Bash 基础知识系列 #6:处理字符串操作

7、在 Bash 中使用条件语句

你可以通过使用 ifif-else 语句为你的 Bash 脚本添加条件逻辑。这些语句以 fi 结束。

单个 if 语句的语法是:

if [ condition ]; then
  your code
fi

注意使用 [ ... ];then

if-else 语句的语法是:

if [ expression ]; then
    ## execute this block if condition is true else go to next
elif [ expression ]; then
    ## execute this block if condition is true else go to next
else
    ## if none of the above conditions are true, execute this block
fi

这里有一个使用 if-else 语句的 Bash 脚本示例:

#!/bin/bash

read -p "Enter the number: " num
mod=$(($num%2))

if [ $mod -eq 0 ]; then
    echo "Number $num is even"
else
    echo "Number $num is odd"
fi

运行它,你应该能看到这样的结果:

-eq 被称为测试条件或条件操作符。有许多这样的操作符可以给你不同类型的比较:

这些是你可以用来进行数值比较的测试条件操作符:

条件当...时,等同于 true
$a -lt $b$a < $b$a 是小于 $b
$a -gt $b$a > $b$a 是大于 $b
$a -le $b$a <= $b$a 是小于或等于 $b
$a -ge $b$a >= $b$a 是大于或等于 $b
$a -eq $b$a == $b$a 等于 $b
$a -ne $b$a != $b$a 不等于 $b

如果你在进行字符串比较,你可以使用以下这些测试条件:

条件当...时,等同于 true
"$a" = "$b"$a 等同于 $b
"$a" == "$b"$a 等同于 $b
"$a" != "$b"$a 不同于 $b
-z "$a"$a 是空的

还有些条件用于检查文件类型:

条件当...时,等同于 true
-f $a$a 是一个文件
-d $a$a 是一个目录
-L $a$a 是一个链接
? 要特别注意空格。开括号和闭括号、条件之间必须有空格。同样地,条件操作符(-le== 等)之前和之后必须有空格。
Bash 基础知识系列 #7:If-Else 语句

8、使用 Bash 脚本中的循环

Bash 支持三种类型的循环:forwhileuntil

这是 for 循环的一个例子:

#!/bin/bash

for num in {1..10}; do
    echo $num
done

运行它,你将看到以下输出:

1
2
3
4
5
6
7
8
9
10

如果你选择使用上面的示例,可以使用 while 循环这样重写:

#!/bin/bash

num=1
while [ $num -le 10 ]; do
    echo $num
    num=$(($num+1))
done

同样,可以使用 until 循环来重写:

#!/bin/bash

num=1
until [ $num -gt 10 ]; do
    echo $num
    num=$(($num+1))
done
? while 循环和 until 循环非常相似。区别在于:while 循环在条件为真时运行,而 until 循环在条件为假时运行。
Bash 基础知识系列 #8:For、While 和 Until 循环

9、在 Bash 脚本中使用函数

Bash Shell 支持使用函数,这样你不必反复编写相同的代码片段。

这是声明 Bash 函数的通用语法:

function_name() {
  commands
}

这是一个使用带参数的函数的 Bash 脚本样例:

#!/bin/bash

sum() {
    sum=$(($1+$2))
    echo "The sum of $1 and $2 is: $sum"
}

echo "Let's use the sum function"
sum 1 5

如果你运行该脚本,你将看到以下输出:

Let's use the sum function
The sum of 1 and 5 is: 6
Bash 基础知识系列 #9:Bash 中的函数

接下来呢?

这只是一个初窥。这个 Bash 脚本教程只是一篇引言。Bash 脚本的内容还有很多,你可以慢慢地、逐渐地探索。

GNU Bash 参考是一份优秀的在线资源,可以解答你的 Bash 疑问。

GNU Bash 参考

除此之外,你可以下载这本免费书籍来学习更多在此未涵盖的 Bash 内容:

下载 Bash 初学者指南

一旦你具有足够的 Bash 基础知识,你可以通过这本免费书籍来学习高级 Bash 脚本:

下载高级 Bash 编程指南

这两本书至少都有十年的历史,但你仍然可以使用它们来学习 Bash。

? 希望你喜欢这个作为学习 Bash 脚本起点的教程。请在评论区提供你的反馈。

(题图:MJ/98f47121-7426-4297-9242-8683ccf0496d)


via: https://itsfoss.com/bash-scripting-tutorial/

作者:Abhishek Prakash 选题:lujun9972 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在 Bash 基础系列的最后一章中学习函数的全部知识。

大多数编程语言都支持函数的概念。

函数帮助你避免在同一个程序中反复编写同一段代码。你只需将代码写为一个函数,然后在需要特定代码片段的地方使用这个函数。

在 Bash 基础知识系列的最后一章中,你将学习在 Bash 脚本中使用函数。

Bash 中的函数

下面是声明 Bash 函数的通用语法:

function_name() {
    commands
}

只有在 “调用函数” 的脚本中,函数内的命令才会被执行。

这里有一个伪代码来演示这个情况:

function_name() {
    commands
}

some_other_commands

# 函数调用
function_name argument;
? 函数定义必须在你调用函数之前。

让我们通过一个简单的例子来看看这个:

#!/bin/bash

fun() {
    echo "This is a function"
}

echo "This is a script"
fun

当你运行脚本时,你应该看到这样的输出:

This is a script
This is a function

函数是在没有任何参数的情况下被调用的。接下来,让我们看看在 bash 中如何处理函数的参数。

向函数传递参数

向函数传递参数和向 Bash 脚本传递参数是一样的。你在调用函数时,可以在函数名旁边写上参数。

function_name argument;

让我们用一个例子来看看这个:

#!/bin/bash

sum() {
    sum=$(($1+$2))
    echo "The sum of $1 and $2 is: $sum"
}

echo "Let's use the sum function"
sum 1 5

如果你运行这个脚本,你会看到以下输出:

Let's use the sum function
The sum of 1 and 5 is: 6

请记住,传递给脚本的参数和传递给函数的参数是不同的。

在下面的例子中,我在调用函数时交换了参数。

#!/bin/bash

arg() {
    echo "1st argument to function is $1 and 2nd is $2"
}

echo "1st argument to script is $1 and 2nd is $2"
arg $2 $1

当你运行这个脚本时,你会看到这样的交换:

$ ./function.sh abhi shek
1st argument to script is abhi and 2nd is shek
1st argument to function is shek and 2nd is abhi

Bash 中的递归函数

一个递归函数会调用它自己。这就是递归的含义。这个梗图可能会帮助你理解它。

递归功能非常强大,可以帮助你编写复杂的程序。

让我们用一个计算阶乘的样本脚本来看看它的应用。如果你忘记了,阶乘的定义是这样的。

n 的阶乘:

(n!) = 1 * 2 * 3 * 4 *...  * n

所以,5 的阶乘是 1 * 2 * 3 * 4 * 5,计算结果是 120。

这是我用递归计算给定数字的阶乘的脚本。

#!/bin/bash

factorial() {

    if [ $1 -gt 1 ]; then
        echo $(( $1 * $(factorial $(( $1 -1 ))) ))
    else
        echo 1
    fi

}

echo -n "Factorial of $1 is: "
factorial $1

注意到 echo $(( $1 * $(factorial $(( $1 -1 ))) )),代码使用比输入值小 1 的值调用了函数自身。这个过程会一直持续到值变为 1。所以,如果你运行脚本并输入参数 5,它最终会返回 5 * 4 * 3 * 2 *1 的结果。

$ ./factorial.sh 5
Factorial of 5 is: 120

非常好。现在,让我们来做些练习吧。

?️ 练习时间

以下是一些示例编程挑战,用来帮助你实践你所学。

练习 1:写一个 Bash 脚本,使用一个名为 is_even 的函数来检查给定的数字是否是偶数。

练习 2:类似的练习,你需要编写一个脚本,该脚本具有一个名为 is_prime 的函数,并检查给定数字是否是质数。如果你还不知道,质数只能被 1 和它自身整除。

练习 3:编写一个生成给定数字的斐波那契序列的脚本。序列从 1 开始,脚本必须接受大于 3 的数字。

所以,如果你运行 fibonacci.sh 5,它应该输出 “1 1 2 3 5”。

就这些了,伙计们!这是 Bash 基础系列的最后一节。当然,你在这里学到的只是冰山一角;Bash 编程还有更多需要学习的内容。

但是现在,你应该对 Bash Shell 有了一定的理解。你应该能够理解大多数 Bash 脚本,并能编写简单的脚本,即便不能编写复杂的。

如果你想深入学习,没有什么比阅读 GNU Bash 手册更好的了。

GNU Bash 手册

? 希望你喜欢这个 Bash 基础知识系列。我们正在创建更多的教程系列,以给你提供更流畅的学习体验。请提供你的反馈,帮助我们帮助其他人学习 Linux。

(题图:MJ/f0022a50-85fe-40cc-afdd-285d976ec98c)


via: https://itsfoss.com/bash-function/

作者:Abhishek Prakash 选题:lujun9972 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在 Bash 基础知识系列的倒数第二章节,学习 forwhileuntil 循环。

循环是任何编程语言中的一个强大功能。如果你还不知道,循环其实是一种根据某些条件重复代码的方式。

例如,想象一下你需要打印从 1 到 10 的数字。你可以使用 echo 命令写十次,但那太原始了。你使用一个循环,在 3 到 4 行代码内,就能完成。

这是我能想到的最简单的例子。我将在讨论 Bash 循环时,分享一些实际有用的例子。

在 Bash 中有三种类型的循环:

  • for
  • while
  • until

我将在教程中展示所有三种类型的循环。让我们从最常见的一种开始。

Bash 中的 For 循环

以下是 Bash 中的 for 循环语法:

for arg in LIST; do
    commands
done

这里的 LIST 可能是一个数组或者一个项目列表。括号扩展 也是进行循环的常用手段。

考虑一下我在开始提到的最简单的场景。让我们使用 for 循环打印从 1 到 10 的数字:

#!/bin/bash

for num in {1..10}; do
    echo $num
done

如果你运行它,你应该会看到像这样的输出:

$ ./for-loop.sh
1
2
3
4
5
6
7
8
9
10

你也可以使用 for num in 1 2 3 4 5 6 7 8 9 10; do ,但是使用括号扩展使得代码看起来更短且更智能。

{..} 是用于扩展模式的。你使用 {d..h} ,它等同于 d e f g h 。关于括号扩展的更多信息,可以在这篇文章中找到。

在 Bash 中使用括号扩展

? 如果你熟悉 C 语言编程,你可能会喜欢在 bash 中使用 C 风格的 for 循环:

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

让我们看另一个例子,显示 Bash 数组 的所有内容:

#!/bin/bash

distros=(Ubuntu Fedora Debian Alpine)

for i in "${distros[@]}"; do
    echo $i
done

如果你运行脚本,它将显示数组中定义的所有发行版:

Ubuntu
Fedora
Debian
Alpine

Bash 中的 While 循环

while 循环测试一个条件,然后只要条件为真,就继续循环。

while [ condition ]; do
    commands
done

如果你考虑前一个例子,它可以使用 while 循环进行重写:

#!/bin/bash

num=1
while [ $num -le 10 ]; do
    echo $num
    num=$(($num+1))
done

如你所见,你首先需要将变量 num 定义为 1,然后在循环体内,你增加 num 的值。只要 num 小于或等于 10,while 循环就会检查条件并运行脚本。

因此,现在运行脚本将会显示出和之前 for 循环中看到的完全相同的结果。

1
2
3
4
5
6
7
8
9
10

让我们看另一个例子。这是一个 Bash 脚本,它接受一个数字作为参数 并显示该表。

#!/bin/bash

echo "Table for $1 is:"
index=1
while [ $index -le 10 ]; do
    echo $(($1*$index))
    index=$(($index+1))
done

如果你对 $1 的使用感到困惑,它代表传递给脚本的第一个参数。更多的细节可以参考这个系列的 第三章

如果你运行这个脚本,它应该会显示以下的输出:

$ ./table.sh 2
Table for 2 is:
2
4
6
8
10
12
14
16
18
20

Bash 中的 Until 循环

这是一个使用较少的循环格式。它的行为和 while 循环类似。这里的区别是,循环运行直到它检查的条件为真为止。意味着为了在循环中执行代码,[ ] 中的条件必须为假。

我马上会解释一下。让我们先看一下它的语法。

until [ condition ]; do
    commands
done

现在,如果我要使用相同的示例,即使用 until 循环打印从 1 到 10 的数字,它看起来会是这样:

#!/bin/bash

num=1
until [ $num -gt 10 ]; do
    echo $num
    num=$(($num+1))
done

区别在于条件;其余部分保持不变。

  • 当变量 num 小于或等于 10 时,while 循环就会运行。[ ] 中的条件必须为真,循环才会执行。
  • 知道变量 num 变得大于 10 时,until 循环才会运行。[ ] 中的条件必须为假,循环才会执行。

这都是做同样事情的两种不同方式。while 更受欢迎,因为你会在大多数编程语言中找到类似 while 的循环语法。

?️ 练习时间

那是有趣的。现在是做一些练习的时候了。

练习 1:编写一个脚本,该脚本接受一个数字作为参数并打印其表格。如果脚本在没有参数的情况下运行,你的脚本还应显示一个消息。

预期输出

$: ./table.sh
You forgot to enter a number

$: ./table.sh 3
3
6
9
12
15
18
21
24
27
30

练习 2 : 编写一个脚本,列出目录 /var 中的所有文件。

提示 : 对于循环,使用 /var/* 作为 “列表”。

Bash 基础知识系列即将结束。作为该系列的最后一章,你将在下周学习在 Bash 脚本中使用函数。敬请期待。

(题图:MJ/945241d6-6a73-432c-9bcd-e0948b3fadc0)


via: https://itsfoss.com/bash-loops/

作者:Abhishek Prakash 选题:lujun9972 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

想了解 Linux 命令行的基础知识吗? 这是一个带有实践方法的教程系列。

Linux 终端可能令人生畏。这块黑色的屏幕只能使用命令。很容易让人感到迷失。

问题是 Linux 命令行是一个很大的话题。你只需使用命令即可管理整个系统。我的意思是,这就是系统管理员、网络工程师和许多其他工作的角色。

本教程集的目的不是让你做好工作准备。它旨在为你提供 Linux 命令行之旅的起点。 它将为你提供足够的能力来使用终端并了解一些基本知识,例如读取文件和编辑文件。

由于这只是开始,所以大部分教程都属于“文件操作”类别。这是大多数 Linux 书籍和课程的起点。

? 最好的学习方法就是自己动手。我以“实践模式”编写了这些教程,以便你可以在 Linux 系统上参照这些示例。本系列的每一章都包含一些示例练习来锻炼。跟着学、多练习,你很快就能熟练掌握 Linux 命令行。

第 0 章:熟悉终端和术语

当你对终端完全陌生时,即使在阅读教程时你也会发现自己迷失了方向。那是因为你应该知道至少你得理解最简单的术语。

下面的文章将帮助你解决其中的一些问题。虽然我分享的一些技巧可能对你来说有点超前或不太有用,但你会发现很多有用的东西。

19 个基础而重要的 Linux 终端技巧

第 1 章:更改目录

在第一章中,学习使用绝对路径和相对路径切换目录(文件夹)。这样,你就可以在 Linux 命令行中切换。

在 Linux 终端更改目录

第 2 章:创建目录

现在你已经了解了如何切换目录,接下来了解如何创建新目录。

在 Linux 终端创建目录

第 3 章:列出目录中的内容

你已经很好地掌握了目录。学习查看目录内部并查看它们有哪些文件和子目录。

在 Linux 终端列出目录

第 4 章:创建文件

关于目录已经足够了。了解在 Linux 命令行中创建新文件。

在 Linux 终端创建文件

第 5 章:读取文件

文件里面有什么?在本章中学习阅读文本文件。

在 Linux 终端读取文件

第 6 章:删除文件和目录

现在你已经学会了创建新文件和文件夹,是时候删除它们了。

在 Linux 终端删除文件和目录

第 7 章:复制文件和目录

在终端基础知识系列的本期中,继续进行文件操作并学习复制文件和目录。

在 Linux 终端复制文件和目录

第 8 章:移动文件和目录

移动文件操作就像剪切粘贴一样。你也可以使用相同的方法重命名文件和目录。

在 Linux 终端移动文件和目录

第 9 章:编辑文件

作为最后一个主要的文件操作,学习在命令行中编辑文本文件。

在 Linux 终端编辑文件

第 10 章:获取帮助

现在你已经了解了大量基本的 Linux 命令行操作,是时候了解如何在终端本身中获取帮助了。

在 Linux 终端获取帮助

从这往哪儿走?

现在你已经更熟悉终端并了解命令行中的基本文件操作,你可能想知道接下来要怎么做。

我建议你购买一本 Linux 书籍,例如《How Linux Works》。不过,你可以从你遇到的任何 Linux 书籍开始。这里有一些 我喜欢的几本 Linux 书籍

还不想花钱买书吗? 不用担心! 这里有一些 你可以下载的免费 Linux 电子书

Bash 脚本也是 Linux 学习中不可或缺的一部分。即使你不必编写 Shell 脚本,如果你了解基础知识,你也应该能够理解使用 Linux 时遇到的脚本。

Bash 基础知识系列

学无止境。不可能面面俱到。但是,如果你至少了解基础知识,就能帮助你更有效地使用系统。

? 希望你喜欢这个 Linux 终端教程系列。请在评论部分分享你的反馈。


via: https://itsfoss.com/linux-terminal-basics/

作者:Abhishek Prakash 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

熟悉在 Linux 命令行中复制文件和目录的 cp 命令。

cp 命令是 Linux 中一个重要的命令,你可能经常会用到它。

正如名称所示,cp 代表 复制 copy ,它被用于 在 Linux 命令行中复制文件和目录

这是一个相对简单的命令,只有几个选项,但你仍有必要深入了解它。

在展示 cp 命令的实际示例之前,我更建议你先熟悉绝对路径和相对路径的概念,将文件从一个位置复制到另一个位置时,你需要用到它们。

Linux 中的绝对路径和相对路径的不同之处

复制单个文件

cp 命令最简单和最常见的用途是复制文件,只需指定源文件和要“粘贴”文件的目标目录即可。

cp 源文件 目标目录

将单个文件从源目录复制到目标目录。

在复制文件的同时重命名它

你将文件复制到另一个位置时可以同时进行 重命名。这有点类似于文本编辑器中的“另存为”选项。

为此,你必须在路径中给出新的文件名。

cp 源文件 目标目录/新文件名

在复制文件的同时重命名

复制多个文件

你还可以将多个文件复制到另一个位置。

cp 文件1 文件2 文件3 目标目录

复制多个文件时,将目标目录放在最后

在这种情况下,你无法重命名文件。

你还可以使用通配符扩展,将特定后缀的文件复制到另一个位置:

cp *.txt 目标目录

使用通配符扩展复制多个文件,比如所有 .txt 后缀的文件

复制文件时避免覆盖现有文件

如果你将 file1.txt 复制到一个已经存在名为 file1.txt 文件的目录中,它会将原有的文件覆盖掉。

如果你不希望这样,cp 命令还提供了几个选项来处理文件覆盖的情况。

首先是使用选项 -i 的交互模式。在交互模式下,它会询问是否确认或放弃覆盖目标文件。

cp -i 源文件 目标目录
cp:覆盖 '目标目录/源文件' ?

Y 覆盖文件,按 N 跳过复制该文件。

覆盖,但以交互方式询问(内容将被覆盖)

覆盖,但以交互方式询问(内容不会被覆盖)

选项 -n 代表完全取消覆盖。使用此选项时目标文件不会被覆盖。

cp -n 源文件 目标目录

取消覆盖(目录内文件的内容未更改)

还有一个选项 -b,在目标目录的文件将被覆盖时自动为其创建备份。我猜这里 b 代表 备份 backup

cp -b 源文件 目标目录

覆盖文件,但在备份文件后附加了“~”。

最后,还有一个“ 更新 update ”选项 -u,如果目标文件比源文件旧,或者目标文件不存在,就会被覆盖掉。

cp -u 源文件 目标目录

新文件会覆盖旧文件

复制目录(文件夹)

cp 命令也用来在 Linux 命令行中复制目录

在复制目录时,你需要使用递归选项 -r

cp -r 源目录 目标目录

在 Linux 中使用 cp 命令复制整个目录

你还可以将多个目录复制到另一个位置:

cp -r 目录1 目录2 目录3 目标目录

使用 cp 命令复制多个目录

在复制时保留属性

当你将文件复制到另一个位置时,它的 时间戳文件权限 甚至所有权都会发生变化。

这是正常的行为。但在某些情况下,你可能希望在复制文件时保留其原始属性。

要保留属性,请使用选项 -p

cp -p 源文件 目标目录

? 还有一个 -a 选项用于存档模式。它将连 ACL 也保留下来。

?️ 练习时间

想要练习一下 cp 命令吗?以下是一些简单的练习题供你尝试。

  • 打开终端并创建一个名为 practice_cp 的目录。
  • 现在,将 /etc/services 文件复制到这个新创建的目录中。
  • practice 目录中对复制的 services 文件进行一些小的更改。
  • 现在,使用更新模式再次复制 /etc/services 文件。有什么变化吗?观察一下。
  • 查看 /var/log 目录,并将以 mail 开头的日志文件复制到你的联系目录下。
  • 现在,返回到你的家目录,并创建一个名为 new_dir 的新目录(好吧,我想不出更好的名字)。
  • practice_cp 目录复制到 new_dir 目录中。

对你来说这些练习足够用了。希望你能喜欢在这里学习 Linux 命令。

(题图:MJ/07b35a39-826e-4904-9f85-25257831ce9d)


via: https://itsfoss.com/cp-command/

作者:Abhishek Prakash 选题:lkxed 译者:onionstalgia 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

如果这样,那就那样,否则就……。还不明白吗?了解了 Bash Shell 脚本中的 if-else 语句后就明白了。

Bash 支持 if-else 语句,以便你可以在 shell 脚本中使用逻辑推理。

通用的 if-else 语法如下:

if [ expression ]; then

  ## 如果条件为真则执行此块,否则转到下一个

elif [ expression ]; then

  ## 如果条件为真则执行此块,否则转到下一个

else 

  ## 如果以上条件都不成立,则执行此块

fi

正如你所注意到的:

  • elif 用于 “否则如果” 类型的条件。
  • if-else 条件始终以 fi 结尾。
  • 使用分号 ;then 关键字

在展示 if 和 else-if 的示例之前,我先分享一下常见的比较表达式(也称为测试条件)。

测试条件

以下是可用于数字比较的测试条件运算符:

条件当满足以下条件时为真
$a -lt $b$a < $b$a 小于 $b
$a -gt $b$a > $b$a 大于 $b
$a -le $b$a <= $b$a 小于等于 $b
$a -ge $b$a >= $b$a 大于等于 $b
$a -eq $b$a == $b
$a -ne $b$a != $b

如果你要比较字符串,可以使用以下测试条件:

条件当满足以下条件时为真
"$a" = "$b"$a$b 相同
"$a" == "$b"$a$b 相同
"$a" != "$b"$a$b 不同
-z "$a"$a 为空字符串

文件类型检查也有条件:

条件当满足以下条件时为真
-f $a$a 是一个文件
-d $a$a 是一个目录
-L $a$a 是一个链接

现在你已经了解了各种比较表达式,让我们在各种示例中看看它们的实际应用。

在 Bash 中使用 if 语句

让我们创建一个脚本来告诉你给定的数字是否为偶数。

这是我的脚本,名为 even.sh

#!/bin/bash

read -p "Enter the number: " num

mod=$(($num%2))

if [ $mod -eq 0 ]; then
    echo "Number $num is even"
fi

当模数运算(%)整除给定数字(本例中为 2)时,它返回零。

? 特别注意空格。左括号和右括号与条件之间必须有空格。同样,条件运算符(-le、== 等)前后必须有空格。

这是我运行脚本时显示的内容:

Running a script with if statement example in bash

你是否注意到,当数字为偶数时,脚本会告诉你,但当数字为奇数时,脚本不会显示任何内容? 让我们使用 else 来改进这个脚本。

使用 if else 语句

现在我在前面的脚本中添加了一条 else 语句。这样,当你得到一个非零模数(因为奇数不能除以 2)时,它将进入 else 块。

#!/bin/bash

read -p "Enter the number: " num

mod=$(($num%2))

if [ $mod -eq 0 ]; then
    echo "Number $num is even"
else
    echo "Number $num is odd"
fi

让我们用相同的数字再次运行它:

Running a bash script that checks odd even number

正如你所看到的,该脚本更好,因为它还告诉你该数字是否为奇数。

使用 elif(否则如果)语句

这是一个检查给定数字是正数还是负数的脚本。在数学中,0 既不是正数也不是负数。该脚本也检查了这一事实。

#!/bin/bash

read -p "Enter the number: " num

if [ $num -lt 0 ]; then
    echo "Number $num is negative"
elif [ $num -gt 0 ]; then
    echo "Number $num is positive"
else
    echo "Number $num is zero"
fi

让我运行它来涵盖这里的所有三种情况:

Running a script with bash elif statement

用逻辑运算符组合多个条件

到目前为止,一切都很好。但是你是否知道通过使用与(&&)、或(||)等逻辑运算符可以在一个条件中包含多个条件? 它使你能够编写复杂的条件。

让我们编写一个脚本来告诉你给定的年份是否是闰年。

你还记得闰年的条件吗? 它应该被 4 整除,但如果它能被 100 整除,那么它就不是闰年。但是,如果能被 400 整除,则为闰年。

这是我的脚本。

#!/bin/bash

read -p "Enter the year: " year

if [[ ($(($year%4)) -eq 0 && $(($year%100)) != 0) || ($(($year%400)) -eq 0) ]]; then
    echo "Year $year is leap year"
else
    echo "Year $year is normal year"
fi
? 注意上面双括号 [[ ]] 的使用。如果你使用逻辑运算符,则这是强制性的。

通过使用不同的数据运行脚本来验证脚本:

Example of running  bash script with logical operators in if statement

?️ 练习时间

让我们做一些练习吧 ?

练习 1:编写一个 Bash Shell 脚本,检查作为参数提供给它的字符串的长度。如果未提供参数,它将打印 “empty string”。

练习 2:编写一个 Shell 脚本来检查给定文件是否存在。你可以提供完整的文件路径作为参数或直接在脚本中使用它。

提示:文件使用 -f 选项

练习 3:通过检查给定文件是否是常规文件、目录或链接或者是否不存在来增强之前的脚本。

提示:使用 -f、-d 和 -L

练习 3:编写一个接受两个字符串参数的脚本。脚本应检查第一个字符串是否包含第二个参数的子串。

提示:请参阅上一章 Bash 字符串

我希望你喜欢 Bash 基础知识系列。在下一章中,你将了解如何在 Bash 中使用循环。继续编写 Bash!

(题图:MJ/1e8f2f5c-9e47-4c84-b8c1-072808e9cf70)


via: https://itsfoss.com/bash-if-else/

作者:Abhishek Prakash 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出