StudyTonight-杂项中文教程-一-
StudyTonight 杂项中文教程(一)
原文:StudyTonight
Linux
Linux 基础
Bash if..else
语句
原文:https://www.studytonight.com/linux-guide/bash-if-else-statement
Bash if-else 语句或条件语句是任何提供有条件执行代码功能的编程语言中最基本的概念。当我们希望只在某些条件满足时执行一段代码,而在条件不满足时执行一些代码时,这种方法很有用。
if-else 语句用于此目的,并具有其他几种形式,如 if、if-else、if-elif-else、嵌套 if 等。
我们将在本文中学习所有这些条件流。那么,让我们开始吧。
如果语句
这是仅在指定条件为真时执行的条件语句的最简单用法。这个语句的一般语法是。
if CONDITIONAL-COMMAND
then
STATEMENTS
fi
CONDITIONAL-COMMAND 是一个条件,并且if
语句仅在该条件为真时执行。then
关键字与 if 相关联,并包含当 if 为真时执行的语句。让我们通过一个例子来理解。
示例:if 语句
在本例中,首先,语句读取用户输入,然后在 if 条件语句中验证该输入。如果用户输入小于 20,则将执行 if 条件。
#!/bin/bash
echo -n "Enter a number: "
read VAL
if [[ $VAL -lt 20 ]]
then
echo "The value is less than 20."
fi
将此代码保存到. sh 文件中,并使用以下命令执行。
$ bash filename.sh
它将要求用户输入,如果输入小于 20,则输出为:
该值小于 20。
if-else 语句
此语句是 if 语句的附加版本,提供了当 if 语句为 false 时执行的 else 语句。所以,如果你想在 if 条件失败时执行一些语句。该语句的一般语法是:
if CONDITIONAL-COMMAND
then
STATEMENTS
else
STATEMENTS
fi
示例:if-else 语句
在本例中,首先,语句读取用户输入,然后在 if 条件语句中验证该输入。如果用户输入小于 20,则将执行 if 条件,如果不是,则执行 else 语句。
#!/bin/bash
echo -n "Enter a number: "
read VAL
if [[ $VAL -lt 20 ]]
then
echo "The value is less than 20."
else
echo "The value is equal or greater than 20."
fi
它将要求用户输入,如果输入大于或等于 20,则执行 else 块,输出为:
该值等于或大于 20。
if-elif-else 语句
此语句用于测试一行中的多个条件,如果任何条件为真,则退出控件。在某些编程语言中,它也被称为 if-else 阶梯。该语句的一般语法是:
if CONDITIONAL-COMMAND1
then
STATEMENTS1
elif CONDITIONAL-COMMAND2
then
STATEMENTS2
else
STATEMENTS3
fi
elif 语句仅在 if 条件为 false 时执行。
示例:if-elif-else 语句
这里,如果用户输入 20,则 if 条件失败,控制转到 elif 条件,其中条件为真,语句执行。
#!/bin/bash
echo -n "Enter a number: "
read VAL
if [[ $VAL -lt 20 ]]
then
echo "The value is less than 20."
elif [[ $VAL -eq 20 ]]
then
echo "The value is equal to 20."
else
echo "The value is equal or greater than 20."
fi
它将要求用户输入,如果输入等于 20,则将执行 elif 块,输出为:
该值等于 20。
嵌套 if 语句
Bash 允许在 if 语句中使用任意数量的 if 语句,这意味着我们可以使用嵌套的 if 语句来测试多个条件。当我们必须检查 if 语句中的多个条件时,这很有帮助。该语句的一般语法是:
if CONDITIONAL-COMMAND1
then
if CONDITIONAL-COMMAND2
then
STATEMENTS1
else
STATEMENTS2
fi
else
STATEMENTS3
fi
嵌套 if 仅在第一个 if 条件失败时执行。
示例:嵌套 if 语句
在这个例子中,我们从用户那里获取三个输入值,并使用嵌套的 if 语句测试哪一个更小。
#!/bin/bash
echo -n "Enter first number: "
read VAL1
echo -n "Enter second number: "
read VAL2
echo -n "Enter third number: "
read VAL3
if [[ $VAL1 -lt $VAL2 ]]
then
if [[ $VAL1 -lt $VAL3 ]]
then
echo "$VAL1 is smallest Number"
else
echo "$VAL3 is smallest Number"
fi
fi
它将要求用户输入,如果输入是 20、50、40,那么输出将是:
20 是最小的数
结论
Bash 脚本使用条件语句(如 if、if-else、if-elif 和嵌套 if)来创建基于指定条件执行的条件程序。在本文中,我们通过适当的例子和用例来理解条件语句的使用。
Bash for
语句
Bash 脚本中的 For 循环用于重复执行指定的语句/命令。Bash For 循环类似于 C 语言中的循环。如果你熟悉 C 语言,那么理解这个概念是很容易的,但是如果不熟悉,那么不要担心,理解起来非常简单。
将循环视为一些代码语句的主体,这些语句执行到指定的条件。在 Bash 中,也可以使用循环来迭代,直到该项出现在列表、数组、字符串等中。for 循环的一般语法如下。
用于循环语法的 Bash
for item in [LIST]
do
[COMMANDS]
done
让我们通过创造一些例子来学习。
循环迭代字符串元素的 Bash
我们可以使用 for 循环遍历字符串元素。它将每个单词视为一个元素,并迭代直到元素出现。它不需要任何条件,因为当项目完成时,它会自动停止。
VAL="India is my country"
for word in $VAL
do
echo "word: $word"
done
字:印
字:正
字:吾
字:国
Bash For 循环迭代一个范围
我们可以使用 for 循环来横向取一个范围的值。在 Bash 中,可以通过使用大括号来创建范围,所以我们在循环中传递范围,循环迭代直到范围的最大值。
这里,范围包括 0 到 5 个值。
for i in {0..5}
do
echo "i= $i"
done
I = 0
I = 1
I = 2
I = 3
I = 4
I = 5
打印偶数值的循环 Bash
在该范围中,第一个值表示起点,第二个值表示终点,第三个值表示每次迭代的跳过点。这里,循环将每隔一次迭代就跳过一次,并且只对偶数值执行。请看下面的例子。
for i in {0..10..2}
do
echo "i= $i"
done
I = 0
I = 2
I = 4
I = 6
I = 8
I = 10
循环迭代数组的 Bash
For 循环也可以用来遍历数组元素。当我们想要打印一个数组的元素时,这是循环最常见的用法,对于同样的数组,这也是循环最常见的用法。
INTEGER=(1 2 3 4)
for i in "${INTEGER[@]}"; do
echo "i: $i"
done
i: 1
i: 2
i: 3
i: 4
Bash 中循环的 c 风格
我们可以像使用 C 语言一样使用 for 循环。该循环包含三个部分:初始化、条件、和增量。
在第一部分中,变量以初始值/起始值开始,然后在条件中,指定结束值,这意味着循环只能进行到指定的结束值。最后,指定增量值,基本上将初始化的变量增加 1。
for ((i = 0 ; i <= 5 ; i++)); do
echo "i= $i"
done
I = 0
I = 1
I = 2
I = 3
I = 4
I = 5
Bash For 循环中的 Break 语句
break 语句用于停止当前的代码执行流,并且控件超出了范围。
在 for 循环中,我们可以使用 break 语句来停止其执行,并将控制权交还给 for 循环。您可以看到循环只打印前 3 个值,当它达到 3 时,由于 break 语句,它停止执行。
for ((i = 0 ; i <= 5 ; i++)); do
if [[ "$i" == 3 ]]; then
break
fi
echo "i= $i"
done
i= 0
i= 1
i= 2
Bash For 循环中的继续语句
continue 语句用于跳过当前的代码执行流程,控制转到循环的下一个迭代。
在 for 循环中,我们可以使用 continue 语句跳过它的执行。您可以看到循环打印除 3 之外的所有值,因为当它达到 3 时,由于 continue 语句,它跳过执行,并继续下一个迭代,即 4。
for ((i = 0 ; i <= 5 ; i++)); do
if [[ "$i" == 3 ]]; then
continue
fi
echo "i= $i"
done
I = 0
I = 1
I = 2
I = 4
I = 5
结论
在 Bash 中,for 循环通常用于遍历列表、数组、字符串、范围等元素。我们还可以使用它来迭代/重复执行,直到指定的条件。循环的主要目的基本上是重复执行任务。所以,我们可以用它来重复 Linux 中的任何语句/命令。
理解 Linux(Unix)中的文件权限
原文:https://www.studytonight.com/linux-guide/understanding-file-permissions-in-linux-unix
在本教程中,我们将向您介绍 Linux 中的文件权限或访问模式。每当我们在 linux 中创建一个文件或在 linux 中创建一个目录时,一组标志与该文件或目录相关联,表示该特定文件或目录的权限或模式或访问模式。设置权限是为了保护文件和目录。这些权限或访问模式决定了哪个用户可以对文件执行什么操作。
有三种不同类型的用户:
-
创建文件的文件所有者(所有者)。
-
然后是定义的用户所有权组(组)
-
而其他人(其他)
以下是允许用户进行的操作或用户获得的类型的访问:
-
读取文件内容(读取)。
-
将内容写入文件(“写入”)。
-
执行文件(“执行”)。
这些权限表示为读取的 r 、写入的 w 和执行的 x 。对于所有不同类型的用户来说,这些访问权限都是定义好的,共同构成了文件权限。
权限是如何表示的?
当您使用ls -l
命令列出目录中存在的文件和目录时,您会看到关于文件的信息,如创建它的用户、文件的大小、创建时间和文件权限,例如:
没人没人没人没人没人没人没人没人没人没人没人没人没人没人没人没人没人没人没人没人没人没人没人没人没人
这里,文件权限表示为:
dr - r - r - 为 dir1 ,其中第一个 d 表示这是一个目录(如果是常规文件开头会是 - (破折号),其余为权限。这里的 r - r - r -是指所有的三类用户,也就是所有者、用户组和其他人都可以直接读取目录的内容。
在权限表示中,我们有 10 个字符,第一个是表示它是用于常规文件还是目录,接下来的 9 个字符,每个用户类各 3 个,表示权限,其中 r 代表读取, w 代表写入, x 代表执行,用一个破折号(-) 代替任何权限意味着权限没有授予用户类。
要验证这一点,通过运行以下命令创建目录:
mkdir -m 444 dir1
然后尝试使用触摸命令在该目录内创建一个新文件:
touch dir1/text.txt
您将获得以下输出:
触摸:不能触摸 dir1/text.txt:权限被拒绝
同样,权限 rwxrwxr-x 表示目录的所有者拥有权限 rwx (读、写、执行),用户组拥有权限 rwx (读、写、执行),其他人拥有权限 r-x (读、执行)。
权限表示中的破折号 (-)表示特定权限未授予用户类。
标志 | 意义 |
---|---|
读写执行 | 意味着所有的权限-读、写和执行都被授予用户类。 |
读和执行 | 意味着用户可以读取和执行文件/目录,但不能向其中写入内容。 |
r - | 意味着用户只能读取文件/目录的内容。 |
八进制权限表示
当我们使用mkdir
命令创建一个新目录时,我们提供的权限是 444 ,那么这个数字是如何转换成权限的呢?
就像我们有 -r - r - r - 表示一样,在二进制形式中我们可以表示为 100100100 ,在八进制数中是 444 ,这里 1 表示许可被授予, 0 表示许可未被授予。
同样,权限 755 表示 111101101 ,对于文件拥有者是 111 ,表示文件拥有者拥有所有权限(读、写、执行),用户组拥有权限 101,只是读、执行,其他人也拥有权限 101 ,表示读、执行。
同样,我们也可以用八进制数来表示权限。事实上,当我们必须更改任何目录的任何文件的权限时,我们使用 chmod 命令,该命令以八进制数的形式输入,以更改 Linux 中文件或目录的权限。
结论:
所以这都是关于 Linux 或任何其他基于 Unix 的操作系统中的权限。这有点棘手,但是一旦您理解了它并开始看到模式,您将通过查看权限表示就知道哪个文件具有什么权限。
Linux 中的wget
命令
原文:https://www.studytonight.com/linux-guide/wget-command-in-linux
Wget 是 Linux 中的一个实用命令,用于从 web 下载文件。我们可以用它从 HTTP、HTTPS 或 FTP 服务器下载文件。
我们也可以用它来下载一个网站。它提供了几个选项,可以根据需要下载文件。所以,让我们开始学习。
在 Linux 中使用 wget 下载一个文件
您可以使用此命令从网站下载文件。您可以使用命令传递文件路径,无需任何选项。这是一个简单的命令,在文章的后面,我们将学习使用 flag/options。
$ wget https://www.mysite.com/filename.zip
该实用程序预装在所有 Linux 发行版中,但如果不可用,请使用这些命令下载。
在 Ubuntu 和 Debian 上安装 Wget
$ sudo apt install wget
在 CentOS 上安装 Wget
如果您使用的是 CentOS 操作系统,请使用此命令下载并安装 wget。
$ sudo yum install wget
在 Fedora 上安装 Wget
如果您使用的是 Fedora 操作系统,请使用此命令下载并安装 wget。
$ sudo dnf install wget
wget
命令语法
这是 Linux 中wget
命令的一般结构。
$ wget [option] [url]
如何用 wget 下载文件
要从网站下载文件,请使用带有文件位置的wget
命令。它会将文件存储在您计算机的当前目录中。
$ wget https://www.mysite.com/filename.zip
用不同的名称保存下载的文件
如果您想为下载的文件设置一个新名称,那么使用wget
命令的-o
选项。默认文件以原始名称下载,如果已经存在同名文件,可能会导致覆盖。
$ wget -O latest-hugo.zip https://github.com/gohugoio/hugo/archive/master.zip
将文件下载到特定目录
如果您想将下载的文件存储在当前目录以外的目录中,请使用wget
命令的-p
选项。给定的命令
$ wget -P /mnt/iso https://releases.ubuntu.com/20.04.2.0/ubuntu-20.04.2.0-desktop-amd64.iso
限制下载速度
该命令提供了设置下载速度限制的选项,以便您可以根据需要调整下载。限速选项可以做到这一点。您可以将该值作为 1m(1 Mb)、10k(10 kb)等传递。
wget --limit-rate=1m https://dl.google.com/py/g52.14.1.linux-amd64.tar.gz
恢复下载
有时下载会因为网络不良或任何其他原因而停止,请不要担心,您可以使用wget
命令的-c
选项恢复下载。该命令将要求服务器从停止的位置开始。
$ wget -c https://releases.ubuntu.com/20.04.2.0/ubuntu-20.04.2.0-desktop-amd64.iso
后台下载
如果你想把下载过程放在后台,那么使用-b 选项和命令,它会隐藏这个过程并在后台继续。
wget -b https://releases.ubuntu.com/20.04.2.0/ubuntu-20.04.2.0-desktop-amd64.iso
通过文件传输协议下载
从 FTP 服务器下载需要用户名和密码以及wget
命令。因此,请提供适当的有效凭据来下载文件。
wget --ftp-user=FTP_USERNAME --ftp-password=FTP_PASSWORD ftp://ftp.mysite.com/filename.tar.gz
创建网站的镜像
如果您想下载任何网站的副本,请使用命令的-m
选项。它会将站点的镜像下载到您的本地计算机上。
wget -m https://mysite.com
结论
wget 是 Linux 中的一个命令,它有助于从网上下载文件。它允许从 HTTP、HTTPS 和 FTP 服务器下载文件。我们可以用它来下载当前目录或不同目录下的文件,在后台下载,甚至可以通过命令使用一个特殊的标志来控制下载速度。
Linux 中的gzip
命令
原文:https://www.studytonight.com/linux-guide/gzip-command-in-linux
gzip
命令只是用来压缩和缩小文件的大小。压缩文件与原始文件具有相同的属性,如时间戳和所有权。gzip
命令压缩的文件有。gz 作为文件扩展名。
$ gzip filename # It will create filename.gz
我们可以使用这个命令来压缩和解压缩数据。该命令的一般语法是:
句法
gzip [arguments] [filename]
Gzip 不同于 zip,因为 gzip 不同于 zip,不能一次压缩多个文件。它一次只能压缩一个文件,如果您有多个文件,那么您要么必须为多个文件运行命令,要么可以在 Linux 中使用 tar 或 zip 命令捆绑它们,然后用 gzip 压缩它。
gzip
命令通常用于压缩文本和档案等常规文件。不建议压缩媒体文件,如视频、音频、pdf 和其他可执行文件,因为它们已经被压缩。任何进一步的压缩都会损坏数据。
gzip 相对于 zip 的优势
- Gzip 具有更好的压缩算法,因此从 gzip 生成的归档文件比通过 zip 生成的归档文件更小。
- 当压缩捆绑在一起的多个文件时,它几乎好 10 倍,因为它不会压缩多个文件,而是将它们作为一个文件,并将文件大小大幅减小。
gzip 的缺点
- 与 zip 不同,如果您想从归档文件中提取单个文件,您必须解压缩整个归档文件,然后提取该文件。而在 zip 中,您可以简单地提取和解压缩特定的文件。
- 压缩和解压缩多个文件需要多个步骤,并且非常耗时。您必须使用 tar 或 zip 将文件捆绑在一起,然后使用 gzip 压缩它们。解压缩也是如此,你必须解压缩它,并使用 tar 或 zip 提取文件。
gzip 可用的选项/参数
有多个选项/参数可以与 gzip 一起使用,以提高工作效率并节省时间。这些是可选的,您可以使用默认设置压缩和文件,而无需键入任何参数。
-f(强制压缩):当已经有同名的压缩文件时,使用此参数。例如,如果您试图压缩一个名为 cars.txt 的文件,并且已经有一个名为 cars.txt 的压缩文件,使用-f 将强制 gz 压缩该文件并保存它。
-k(压缩并保留):此参数将告诉 gzip 压缩文件,并保存原始文件和压缩文件。默认情况下,gzip 压缩文件并删除原始文件,只保留压缩文件以节省空间。
-v ( 统计显示):此参数将显示 gzip 运行完成后压缩或解压缩后文件大小的变化。
-l(进度显示):此参数显示压缩或解压缩期间的进度百分比。
-d(解压缩):此参数与 gzip 一起使用,用于解压缩文件。您也可以将此参数与上述参数一起使用。
使用gzip
命令压缩文件
让我们学习在 Linux 中使用gzip
命令压缩文件。对文件名使用以下命令。
$ gzip filename
它将在同一目录下创建一个. gz zip 文件,并删除原始文件。
使用gzip
命令时保留原始文件
上面的压缩命令删除了原始文件,如果我们想在压缩后保留这个文件,那么使用命令中的-k
选项。
gzip -k filename
控制台的详细输出
如果您想查看与文件压缩和速度等相关的详细信息,请将-v
选项与命令一起使用。
$ gzip -v filename
文件名:32% -替换为 filename.gz
压缩多个文件
要压缩多个文件,请使用以下命令。它需要命令中所有文件的名称。
$ gzip filename1 filename2 filename3
gzip
命令不会为所有文件创建一个压缩文件,而是为每个文件创建单独的 zip 文件,如:filename1.gz、filename2.gz、filename3.gz。
压缩目录中的所有文件
如果你想压缩一个目录的所有文件,那么使用gzip
命令的-r
选项。-r
用于递归目的。
$ gzip -r directory-name
它将压缩同一目录下的所有文件。
指定压缩级别
我们可以为命令指定压缩级别,以设置或多或少的压缩质量。基本上,它使用 1 到 9 个数字来设置压缩级别,这意味着 1 将压缩更少,并以更快的速度完成该过程,而 9 指定最佳压缩级别,但速度很慢。我们可以相应地设置级别。
$ gzip -9 filename
它将进行最大程度的压缩。
在 Linux 中解压缩文件
我们可以使用gzip
命令通过使用-d
选项来解压缩一个存档文件。以下命令将文件解压缩到相同的目录中。
$ gzip -d filename.gz
解压缩多个文件
类似于单个文件,您也可以通过对多个 zip 文件使用相同的命令来解压缩多个文件。
$ gzip -d filename1.gz filename2.gz filename3.gz
结论
gzip
命令是 Linux 中的一个实用命令,可以用来压缩和解压缩文件。在本文中,我们学习了如何将它与几个选项一起使用,例如-k 表示零售原始文件,-v 表示获取详细信息,-d 表示解压缩。gz 文件等。本文包含了在 Linux 中使用gzip
命令的简化指南。
如何列出目录内容(ls
命令)
原文:https://www.studytonight.com/linux-guide/how-to-list-directory-content-ls-command
在 Linux 中,要列出一个目录或子目录的所有文件,我们可以使用ls
命令。这是每个 Linux 用户最常用的命令。我们将通过可用的选项和示例详细了解该命令。
- 如果我们使用
ls
命令而没有任何参数的话它列出了当前工作目录中的文件和目录。 ls
命令在 EFI(可扩展固件接口)Shell 中也有。- 在其他环境中,如 DOS(磁盘操作系统)和微软视窗,类似的功能由
dir
(目录)命令提供。 ls
命令的输出是有色的,而dir
命令是有色的。
ls
命令的一般语法
以下是 Linux 中ls
命令的语法。
ls [OPTION]... [FILE]...
Linuxls
命令选项
以下是 ls 命令可用选项的简要说明。
选择 | 描述 |
---|---|
-所有人 | 它用于显示隐藏的文件。 |
-一个,-几乎所有 | 不要列出隐含的。还有。。 |
-作者 | 用于打印每个文件的作者信息。 |
-块大小=大小 | 它用于在打印前设置缩放尺寸。 |
-B,-忽略-备份 | 它用于忽略备份文件的列表。 |
分类 | 它用于将指示符(一个*/=>@|)添加到条目中。 |
-文件类型 | 用于设置文件类型。 |
-我,伊诺德 | 它用于打印每个文件的索引号。 |
-r-倒车 | 它用于在排序时以相反的顺序列出文件。 |
-R,-递归 | 它用于递归列出子目录。 |
救命 | 它用于显示ls 命令的帮助。 |
-版本 | 它用于打印ls 命令的版本信息。 |
示例:列出目录的内容
在本例中,ls
命令显示文件和目录列表。
示例:列出目录的隐藏内容
在这个例子中,我们使用的是ls -a or ls --all
命令,该命令显示所有包含隐藏文件的文件(文件以。或者..是隐藏的文件或目录)。
示例:用ls
命令显示每个文件的作者
在本例中,我们将 ls 命令与 -author 选项一起使用,该选项以权限打印每个文件的作者。我们也可以使用ls -author <file name>.
检查任何特定文件
示例:列出目录的内容,不包括备份文件
在本例中,我们使用ls
命令ls -B option in
排除了备份文件(文件以~符号结尾)。我们也可以使用ls --ignore-backups
过滤备份文件。
示例:在ls
命令中使用附加指示器
在本例中, ls -F 或-classize命令将文件分类为它们的类型。
- “/”符号表示目录。
- “*”符号表示可执行文件。
- “@”符号表示符号链接。
- “%”符号表示空白。
- “=”符号表示插座。
- “|”符号表示先进先出。
示例:递归列出子目录
如果一个目录包含多个子目录,并且我们想要列出所有子目录及其内容,那么 -R 选项可以与ls
命令一起使用。请参见下面的命令。
$ ls -R
结论
在本教程中,我们介绍了如何使用ls
命令列出 Linux 操作系统中的目录内容,以及可用的选项和合适的示例。在 Linux 中,dir
和vdir
也可用于列出目录及其内容,但用于其他目的。我们将在下一个教程中讨论这些内容。
如何更改文件所有权
原文:https://www.studytonight.com/linux-guide/how-to-change-file-ownership-chown
Linux 是一个多用户操作系统,有时我们在公共文件夹中有所有用户都可以访问的文件。为了维护安全性以及处理数据访问,Linux 使用所有权。同样,您拥有的对象不能被其他任何人访问,除非上级给予权限,Linux 使用chown
(更改所有者)命令确保您的文件只被指定的用户或组访问。有了一些经验chown
甚至可以用来设置文件的组。
chown
语法
chown [OPTION]... [OWNER][:[GROUP]] FILE...
chown [OPTION]... --reference=RFILE FILE...
与chown
一起使用的常用选项
|
[计]选项
|
描述
|
| --- | --- |
| -c-变化 | 就像一个冗长的报告,但只有在发生变化时才报告 |
| 安静,安静 | 隐藏大多数错误消息 |
| -v,-冗长 | 为每个处理的文件输出诊断 |
| -参考=RFILE | 引用并应用 RFILE 所有权 |
| -R,-递归 | 递归地将权限应用于文件和目录 |
要对文件进行任何编辑并观察更改,让我们看看文件的当前所有者。
文件所有者详细信息:
ls -l fileName
这里的“delta
”分别是“.bashrc
”文件所属的所有者、和组。
将所有权变更给其他用户
-
使用命令
adduser userName
创建一个新用户,通过在命令前面加上sudo
来使用 sudo 权限,或者通过启动一个提升的 shell,使用命令sudo -s
来登录,并启动一个交互 shell(一个交互 shell 在提示的末尾有#
,而不是通常的$
)。 -
使用命令
ls -l fileName
列出文件信息。 -
要更改文件所有权,请运行
chown <userName|userID> fileName
。 -
要查看是否已经进行了更改,我们可以再次运行
ls -l fileName
,或者我们可以根据所需的详细程度和用例,在chown
命令中使用-c
或-v
标志。
更改集团所有权,并使用chown
选项
-
我们已经看到了如何编辑文件的所有者用户。使用
chown
命令,组所有权的一些特殊情况如下-
我们可以使用以下格式的命令来更改我们的组
chown [OPTION]... :[GROUP] FILE...
这将只改变指定文件的组。
-
同时更改用户和组的所有权
chown [OPTION]... [USER]: FILE... # When Group is to be made login group of User chown [OPTION]... [USER]:[GROUP] FILE... # When User, and Group are to be explicitly changed
-
-
带
-c
标志的chown
(如有变更,报告) -
chown
带有-v
标志(报告所有更改和错误)和--reference
标志(对所有作为参数传递的文件使用引用的文件所有权)
结论
我们已经看到了如何在基于*nix 的操作系统上,在终端中使用chown
来操纵所有权和确保文件的安全性。我们还介绍了合适的日常需求选项,并举例说明了命令的使用。
chown
也可以用来操纵组所有权,正如 1.1 中上一节所规定的,当这样使用时,chown
的行为类似于chgrp
。
如何在 Linux 中添加用户?
原文:https://www.studytonight.com/linux-guide/how-to-add-user-in-linux
在 Linux 中,对于添加新用户,我们可以使用useradd
命令。
我们知道 Linux/Unix 是一个多用户操作系统,它意味着多个用户可以同时与系统交互。用户管理是系统管理员的责任,即应该如何管理相关任务,如创建新用户、删除现有用户等。useradd
命令用于在 Linux 系统中创建新用户。
由 root 或sudo
权限执行的用户管理任务。如果我们使用具有sudo
权限的useradd
命令,那么我们必须提供系统密码。
命令的一般语法。
useradd [options] LOGIN
useradd -D
useradd -D [options]
useradd 命令可用选项的简要描述。
选择 | 描述 |
---|---|
恶名 | 不要检查坏名字 |
-D,-默认值 | 打印或更改默认用户添加配置 |
-G,-group,groups | 新帐户的补充组列表 |
-m,-创建-主页 | 创建用户的主目录 |
-o,-非唯一的 | 允许创建具有重复(非唯一)UID 的用户 |
-r,-系统 | 创建系统帐户 |
救命 | 显示帮助并退出 |
示例:向 Linux 操作系统添加新用户
在这个例子中,使用sudo useradd <username>
命令,我们可以很容易地将新用户添加到我们的系统中。这里我们不是以 root 权限执行这个命令,所以我们需要使用sudo
并且我们必须提供一个系统密码。
示例:使用-D 或- default 选项显示当前默认选项类型
在本例中,执行useradd --default
或useradd -D
后,当前默认选项将提示如下图所示。
示例:使用带有useradd
命令的-r
或--system
选项创建系统用户。
在这个例子中,我们可以使用sudo useradd --system <username>
创建一个系统用户。系统用户和普通用户的主要区别在于,系统用户是在没有截止日期的情况下创建的。
在选项表中,仅给出了几个重要的选项和描述,以了解更多关于用户添加命令用户useradd --help
中可用选项的信息,它将提示用户添加命令中的所有可用选项。
如何在 Linux 中创建文件?
原文:https://www.studytonight.com/linux-guide/how-to-create-a-file-in-linux
当您使用 Linux 操作系统或任何风格的 Linux(如 Ubuntu、CentOS 等)并想要创建一个新文件时,您可以使用touch
命令或cat
命令或使用编辑器(如 vim 和 nano 等)来创建,这些在您的 Linux 安装中可能可用,也可能不可用,但您可以尝试。
在本教程中,我们将从最基本的方法开始介绍所有这些方法,然后继续介绍在 Linux 中创建文件的一些特定场景。
使用touch
命令:
如果只是想创建一个没有内容的文件,那么可以使用touch
命令在 Linux 中创建一个文件。
如果您想创建一个名为study now . txt的文件,那么运行以下命令:
touch studytonight.txt
执行这个命令不会给出任何输出,只会在当前目录下创建一个名为study now . txt的新文件。您可以通过运行ls
命令列出目录中存在的文件来验证这一点。
ls -l
-rw-rw-r - 1 没人没人 0 7 月 2 日 16:11 今晚学习
我们也可以使用touch
命令创建多个文件:
touch file1.txt file2.txt file3.txt
如果您想在此文件中添加任何内容/文本,可以使用 Vim 或 Nano 编辑器。
使用cat
命令
现在让我们看看创建文件的第二种方法,这次是在其中包含一些内容。如果你想在 Linux 中创建一个文件,里面有一些内容,那么使用cat
命令是一个很好的选择。
cat > studytonight.txt
然后输入想要添加到文件中的内容,如“ Hello World!”或其他,然后按 CTRL + D 保存文件退出。
同样,您可以使用ls
命令查看文件是否已创建。要查看文件的内容,您可以再次使用cat
命令,但不要使用尖括号。
cat studytonight.txt
你好世界!
使用代码编辑器,如 Vim 或 Nano
我们还可以使用 Linux 操作系统中可用的代码编辑器来创建和编辑文件。要检查您是否安装了这些编辑器,请在您的终端中键入nano
或vim
。
使用纳米编辑器创建文件:
要使用 nano 编辑器在 Linux 中创建新文件,请使用以下命令:
# nano /path/to/file/name-of-file.extension
nano test.txt
上面的命令将打开 Nano 编辑器来创建一个新文件,现在你可以键入你想要添加到你的文件中的文本。完成后,按 CTRL + X,这是退出的命令,编辑会让你保存文件,然后按 Y 键确认,你的新文件就被保存了。
使用 Vim 编辑器创建文件:
要使用 vim 编辑器在 Linux 中创建新文件,请使用以下命令:
vim test.txt
# or vi text.txt also works
上面的命令会创建一个空文件,向里面插入文本,先按 I ,然后输入文本,一旦完成,按 ESCAPE 退出插入模式,然后输入 :wq!点击进入。是的,这个有点难用。
结论:
在本文中,我们介绍了在 Linux 中创建文件的不同方法。您可以创建一个空文件或带有一些文本的文件,甚至可以使用我们刚刚讨论的编辑器 Nano 和 Vim 编辑现有文件。
如何在 Linux 中创建目录(mkdir
命令)
原文:https://www.studytonight.com/linux-guide/how-to-create-directory-in-linux-mkdir-command
在 Linux 中,如果你想创建一个新的目录,你可以使用mkdir
命令。mkdir
命令用于在 Linux 中创建一个目录。
在进入我们如何创建目录(或者用 Windows 术语来说——一个文件夹)之前,首先让我们看看mkdir
命令是如何工作的。
使用mkdir
命令
以下是mkdir
命令的语法:
mkdir [OPTION] [DIRECTORY]
使用mkdir
命令时,我们可以提供一些选项和一个或多个目录的路径。
要查看可用选项,您可以在 yout 终端中运行以下命令:mkdir --help
现在让我们看看如何在 Linux 中使用mkdir
命令创建一个目录。
创建目录
我们将从使用mkdir
命令创建一个目录开始:
mkdir studytonight
上述命令将在当前工作目录中创建一个名为study night的新目录。您可以使用ls
命令列出当前目录中的文件和目录。
ls -l
drwxrwxr-x 2 没人没人 6 7 月 2 日 17:29 今晚学习
默认情况下,目录在当前目录内创建。如果我们想在其他位置创建目录,那么我们可以在创建目录时提供完整的路径。
我们举个例子吧。假设我们有一个目录结构:
home:
-some user:
-learn-Linux
-test-Linux
我们目前在目录中,某个用户想要在目录 test-linux 中创建一个名为 sample 的新目录,我们可以使用以下命令:
mkdir text-linux/sample
让我们再创建一个目录。考虑到您当前位于目录 test-linux 中,并且想要在目录 learn-linux 中创建一个名为 sample 的目录,我们可以使用以下命令来完成:
mkdir ../learn-linux/sample
开头的两个点代表我们要移出测试-linux 目录,然后进入学习-linux 目录,在那里创建一个名为样本的目录。
注意: 创建目录时,如果您没有访问任何位置,并且试图在那里创建目录,您可能会出现权限被拒绝错误。
与父目录一起创建目录
如果我们想要创建一个目录结构,例如在上面给定的目录结构中,如果您当前在 someuser 目录中,并且您想要在目录 practice-linux 中创建一个目录示例,您会怎么做?注意,我们在中没有练习-linux 目录,有些用户目录中没有练习-Linux 目录。
我们也可以使用mkdir
命令创建父目录,同时使用-p
选项创建目录。
让我们看看这是如何工作的,
mkdir -p practice-linux/sample
当我们运行上面的命令时,一个新的目录练习-linux 将被创建,并且在其中一个样本目录也将被创建。这就是mkdir
命令的-p
选项的神奇之处。
同样,您可以使用-p 选项创建多级父目录。
创建多个目录
如果我们想一次创建多个目录,我们可以使用mkdir
命令轻松完成。
mkdir dir1 dir2 dir3
上面的命令将在当前目录中创建 3 个目录。
drwxrwxr-x 2 没人没人 6 7 月 2 日 17:50 dir1
drwxrwxr-x 2 没人没人 6 7 月 2 日 17:50 dir2
drwxrwxr-x 2 没人没人 6 7 月 2 日 17:50 dir3
看看有多简单。同样,您可以通过运行一个命令来提供不同的路径,以便在不同的位置创建多个目录。
使用自定义权限创建目录
当我们在 Linux 中使用mkdir
命令创建目录时,分配给它的默认模式/权限是 755,这意味着所有人都有读取和执行权限,但不是每个人都可以写入这个目录。如果您想提供自定义权限,如 700,或 644,甚至更严格的 444,我们可以使用mkdir
命令使用-m
选项(代表模式)来实现。
这里有一个例子,
mkdir -m 444 dir1
没人没人没人没人
这将创建一个具有 444 模式/权限的新目录,您可以在代表权限的输出 dr - r - r - 的开头看到。我们可以使用 Linux 中的 chmod 命令来更改任何目录或文件的权限。
结论
在本教程中,我们介绍了如何在 Linux 中创建一个目录或创建多个目录。我们还学习了如何在父目录不存在的情况下创建父目录以及创建目录。
如何在 Linux 中重命名文件或目录
原文:https://www.studytonight.com/linux-guide/how-to-rename-a-file-or-directory-in-linux
如果你想在 Linux 中重命名一个文件或目录,没有具体的重命名命令,但是有移动命令可以同时使用,将文件/目录移动到一个新的位置或者重命名文件或目录。
移动文件就是以某种方式重命名文件。怎么做?
我们举一个简单的例子。考虑以下目录结构:
- 目录 1
- 子目录 1
- somefile.txt
- 子目录 1
- 目录 2
- 子目录 2
我们有两个名为 dir1 和 dir2 的目录,然后我们在这些文件中有子目录,在其中一个子目录子目录中,我们有一个文件 somefile.txt ,一个普通的文本文件。
文件 somefile.txt 的完整路径或名称是dir 1/subdir 1/some file . txt,对。现在,如果我想把这个文件移到目录子目录,那么这个文件的完整路径或完全限定名将变成目录 2/子目录/somefile.txt 。
现在,当我们将一个文件从一个位置移动到另一个位置时,在某种程度上,它的完全限定名改变了,或者它的路径改变了,这也是它的名称的一部分。
这里需要注意的另一个要点是,在 Linux 中,文件或目录由它们的完全限定名来管理。所以我们可以在 Linux 中使用 move 命令来重命名一个文件,这个命令可以用来更新任何文件或者目录的完全限定路径,这个路径无非就是文件名。
在 Linux 中重命名文件/目录- mv
命令:
我们将使用mv
命令来重命名 Linux 中的任何文件或目录。mv
命令用于将文件或目录移动到不同的位置,这类似于重命名文件,我们在上一段中刚刚理解了这一点。
使用mv
命令的基本语法是:
mv [Option] <SOURCE_FILE> <DESTINATION_FILE>
在上面的命令中,源文件是您要重命名的文件或目录的完全限定名,目标文件是更改了名称的新路径。
运行mv
命令时,我们可以使用许多选项。
Linux 中的mv
命令使用起来非常简单。我们可以将此命令用于:
-
重命名单个文件或目录
-
一次重命名多个文件或目录。
让我们从更简单的一个开始,重命名一个文件或一个目录。
重命名单个文件/目录
如果您想要按照上面解释的目录结构中描述的那样重命名文件 somefile.txt ,以使新名称为 mynewfile.txt ,我们可以运行以下命令:
mv somefile.txt mynewfile.txt
没有任何选项,它应该直接重命名。现在运行 ls -l 命令列出目录中的文件,您会看到您的文件被重命名了。
代替 somefile.txt ,我们也可以提供文件的全限定路径,代替 mynewfile.txt ,我们可以提供更新后的路径,然后使用mv
命令,它会重命名文件,并将文件移动到新的路径。
同样,您也可以重命名目录:
mv dir1 mydir
名为 dir1 的目录将更名为 mydir 。
重命名多个文件/目录
要一次重命名多个文件,我们不能直接使用mv
命令。为此,我们必须编写一个小的 bash 脚本。
让我们举个例子,考虑一个目录,其中存储了许多不同扩展名的文件。我们想用改变文件的扩展名。txt 扩展并使其成为。日志扩展。我们要怎么做?
我们可以使用下面的 bash 脚本来实现:
for f in *.txt; do mv -- "$f" "${f%.txt}.log"
在上面的 bash 脚本中,我们使用了一个for
循环来遍历所有带有的文件。txt 扩展,然后运行mv
命令重命名它们并替换。txt 延伸带。日志扩展。
同样,您也可以重命名目录。
重命名目录会影响目录中的内容吗?
当使用mv
命令重命名目录时,目录的组件保持原样。唯一的变化是,现在他们获得了一个新的更新的路径与改变的目录名。
重命名目录后,使用ls -l
命令列出它的文件和子目录,这样就不会有变化了。
摘要
如果你是 Linux 新手,不要被我们使用mv
命令来重命名文件的事实所迷惑。因为重命名文件和移动文件,或多或少是一样的。
Linux tail
命令
原文:https://www.studytonight.com/linux-guide/linux-tail-command
尾部命令显示一个或多个文件或管道数据的最终部分(默认为 10 行)。它还可以用来实时监控文件的变化。
tail 命令最典型的应用之一是观察和分析日志和其他随时间变化的文件,通常与 grep 等附加工具配对。
本教程将教你如何使用 Linux tail 命令以及实用的例子和最常见的 tail 参数的大量解释。
tail
命令语法
在深入研究如何利用尾部命令之前,让我们从检查基本语法开始。
tail
命令表达式采用以下形式:
tail [OPTION]... [FILE]...
选项 -尾部选项。我们将在以下几节中讨论最常见的可能性。
文件 -零个或多个输入文件名。如果没有提供文件,或者当文件为-时,tail 将读取标准输入。
如何使用tail
命令
在最简单的形式中,尾命令在没有任何参数的情况下使用时将显示前 10 行。
tail filename.txt
如何显示特定的行数
使用-n(—线)选项选择要显示的线的号:
tail -n <NUMBER> filename.txt
或者,您可以跳过字母 n,直接使用连字符 (-)和数字(中间没有空格)(中间没有空格)。
显示名为文件名的文件的最后 50 行。txt,您可以使用:
tail -n 50 filename.txt
以下示例将产生与上述命令相同的结果:
tail -50 filename.txt
如何显示特定的字节数
使用-c(—字节)选项显示指定的字节。
tail -c <NUMBER> filename.txt
例如,要显示名为 filename.txt 的文件中最后 500 个字节的数据,可以使用:
tail -c 500 filename.txt
您也可以在数字后添加一个乘数后缀,以定义要显示的字节数。b 乘以 512,kB 乘以 1000,K 乘以 1024 ,MB 乘以 1000000,M 乘以 1048576,以此类推。
以下程序将显示文件 filename.txt 的最后两千字节(2048):
tail -c 2k filename.txt
如何查看文件中的更改
要查看文件的更改,请使用-f(—跟随)选项:
tail -f filename.txt
该功能对于监控日志文件非常方便。例如,要显示最新的 10 行 /var/log/nginx/error.log 文件,并监控文件中您将使用的更改:
tail -f /var/log/nginx/error.log
要在查看文件时中断tail
命令,请使用Ctrl+c
要在文件重新生成时监控文件,请使用-F 选项。
tail -F filename.txt
当尾部命令正在跟踪旋转的日志文件时,该选项很有帮助。与-F 选项一起使用时,当文件再次变为可访问时,tail 命令将重新打开文件。
如何显示多个文件
如果向尾命令提供了许多文件作为输入,它将显示每个文件的最近 10 行。
tail filename1.txt filename2.txt
您可以使用与显示单个文件时相同的参数。
此示例显示文件文件名 1.txt 和文件名 2.txt 的最后 20 行:
tail -n 20 filename1.txt filename2.txt
如何在其他命令中使用 Tail
tail
命令可以通过管道将标准输出从其他公用设施转移到其他公用设施,与其他命令一起使用。
例如,要监视 apache 访问日志文件并仅显示包含 IP 地址 192.168.42.12、的行,您可以使用:
tail -f /var/log/apache2/access.log | grep 192.168.42.12
以下 ps 命令将列出按 CPU 使用情况排序的前 10 个运行进程:
ps aux | sort -nk +3 | tail -5
结论
到目前为止,您应该已经对如何利用 Linux tail
命令有了相当的了解。是对 head 命令的补充,head 命令将第一行发布到终端。
如何更改文件或目录的权限
原文:https://www.studytonight.com/linux-guide/how-to-changes-the-permissions-of-a-file-or-directory
在本教程中,我们将学习如何在 Linux 中更改文件或目录的访问权限。在继续学习本教程之前,您应该首先对 Linux 中的文件权限有一个基本的了解。
Linux 中的文件权限可以用来限制对任何文件或目录的访问。我们还可以向任何用户提供特定的权限,如只读、读写、或读写执行权限。
我们将使用chmod
命令来处理 Linux 中文件和目录的权限。
Linux chmod
命令
每当我们在 Linux 中创建新的文件或目录时,默认情况下,会为该文件/目录配置一些权限,这决定了谁(创建该文件的用户、任何来宾用户或其他人)可以访问该文件或目录以及以何种模式访问,如只读模式、读写更多或读写执行模式。
现在,如果您想更改任何文件的访问模式,限制对它的访问或允许对它的自由访问,我们可以通过使用 Linux 中的chmod
命令来实现。
句法
chmod [Options] [Mode] [File]chmod [Options] [Mode] [File]
我们将通过示例和支持选项来讨论这个命令。
Linux chmod 选项
下表包含了 Linux 中 chmod 命令的选项。
[计]选项 | 描述 |
---|---|
-c,-变化 | 它用于对所有实际更改的文件进行诊断。 |
-f,-无声,-相当 | 它用于抑制大多数错误消息。 |
-v,- verbose | 它用于递归地更改文件和目录。 |
-R,-递归 | 它用于递归地更改文件和目录。 |
-帮助 | 它用于显示帮助消息,然后退出。 |
-版本 | 它用于给出版本信息,然后退出。 |
Linux 命令模式
Linux 以两种不同的模式支持该命令:
- 数字符号
- 符号符号
数字符号:
在数字表示法中,三位八进制数(0-7)序列用于设置权限。每个数字都有自己的类别。第一个数字代表用户,第二个数字代表组,最后一个数字代表其他人。如果数字超出范围,那么它们将被认为是零。
| seven | 读、写、执行。 |
| six | 读写。 |
| five | 读取并执行。 |
| four | 只读。 |
| three | 编写并执行。 |
| Two | 只写。 |
| one | 仅执行。 |
| Zero | 没有。 |
符号表示法:
符号表示法是指定权限的字母组合。一些重要的字母是(u)代表用户(g)代表组(o)代表其他人,以及(a)代表所有用户。
| rwx | 读、写、执行。 |
| rw- | 读写。 |
| r-x | 读取并执行。 |
| r - | 只读。 |
| -wx | 编写并执行。 |
| -w- | 只写。 |
| - x | 仅执行。 |
| - | 没有。 |
示例:Linux chmod
命令
让我们看看一些既有数字符号又有符号符号的示例命令。
下面的命令将只允许所有者读取文件。
执行命令后,任何一个文件都将被锁定进行编辑。
示例:组用户的权限
以下命令将授予用户和组读取文件的权限。
$ chmod 220 hello.txt
示例:读写和执行权限
以下命令将授予每个人读取、写入和执行文件的权限。
$ chmod 777 hello.txt
结论
在本教程中,我们介绍了如何在 Linux 操作系统中使用 chmod(更改模式)命令更改文件或目录的权限,并提供了可用的选项和合适的示例。
如何使用rmdir
命令删除空目录
原文:https://www.studytonight.com/linux-guide/how-to-removes-empty-directories-usinig-rmdir-command
在 Linux 中,如果我们想删除空目录,我们使用rmdir
命令。
rmdir
(删除目录)rmdir
命令用于从文件系统中删除一个空目录。
- 如果目录不是空的,那么我们不能通过
rmdir
命令删除目录。 - 删除目录时要小心,因为当我们以图形方式删除文件或目录时,该目录实际上被移动到废纸篓,可以很容易地恢复,但是通过
rmdir
命令删除的目录不能恢复。
rmdir 的一般语法
rmdir [OPTION]... DIRECTORY...
rmdir
命令可用选项的简要说明。
选择 | 描述 |
---|---|
-忽略-非空故障 | 忽略仅因为目录非空而导致的每个故障。 |
-p,-父母 | 删除 DIRECTORY 及其祖先;例如,“rmdir -p a/b/c”类似于“rmdir a/b/c a/b a”。 |
-v,- verbose | 为每个处理的目录输出一个诊断。 |
-帮助 | 显示此帮助并退出。 |
-版本 | 输出版本信息并退出。 |
示例:使用rmdir
命令删除一个空目录。
在这个例子中,hope 是影子父目录中的一个空目录使用rmdir <directory name>
可以删除一个空目录。
示例:删除子目录和父目录。
在本例中,我们将使用-p
或带有rmdir
命令的--parents
删除子目录和父目录。
示例:在rmdir
命令中使用- ignore-fail-on-non-empty 选项。
在此示例中,使用此选项不会报告仅因为目录非空而发生的故障。可以看到,影子是一个非空目录,仍然没有错误报告。
结论
在本教程中,我们介绍了如何使用不同的选项从文件系统中删除空目录。如果指定的目录有内容,那么我们不能使用rmdir
命令删除该目录。
Bash select
(制作菜单)
原文:https://www.studytonight.com/linux-guide/bash-select-make-menus
本文将研究 Bash 中选择构造的基本原理。
选择的结构使您能够构建菜单。
Bash 选择构造
选择的构造从项目列表中产生一个菜单。它具有与 for 循环几乎相同的语法:
select ITEM in [LIST]
do
[COMMANDS]
done
【列表】可以是由空格、整数范围、命令输出、数组等分隔的字符串序列。可以使用 PS3 环境变量为所选构造提供自定义提示。
当选择的构造被执行时,列表中的每一项都被写入屏幕上的(标准错误),以数字为前缀。
如果用户输入一个对应于所示项目之一的数字,则【项目】**的值被分配给该项目。所选项目的值保存在变量 REPLY 中。否则,如果用户输入为空,将再次显示提示和选项列表。
选择循环的将继续运行并请求用户输入,直到中断指令被调用。
为了展示所选择的构造是如何工作的,让我们看一下下面的基本示例:
PS3="Enter a number: "
select character in Sheldon Leonard Penny Howard Raj
do
echo "Selected character: $character"
echo "Selected number: $REPLY"
done
该脚本将显示一个菜单,该菜单由带有相关数字的项目和 PS3 提示组成。当用户输入数字时,脚本将输出选择的字符和数字:
1) Sheldon
2) Leonard
3) Penny
4) Howard
5) Raj
Enter a number: 3
Selected character: Penny
Selected number: 3
Enter a number:
Bash 选择示例
通常情况下,在连接时,用 if 语句。
让我们看一个更现实的场景。一个简单的计算器要求用户输入并进行基本的算术运算,包括加法、减法、乘法和除法。
PS3="Select the operation: "
select opt in add subtract multiply divide quit; do
case $opt in
add)
read -p "Enter the first number: " n1
read -p "Enter the second number: " n2
echo "$n1 + $n2 = $(($n1+$n2))"
;;
subtract)
read -p "Enter the first number: " n1
read -p "Enter the second number: " n2
echo "$n1 - $n2 = $(($n1-$n2))"
;;
multiply)
read -p "Enter the first number: " n1
read -p "Enter the second number: " n2
echo "$n1 * $n2 = $(($n1*$n2))"
;;
divide)
read -p "Enter the first number: " n1
read -p "Enter the second number: " n2
echo "$n1 / $n2 = $(($n1/$n2))"
;;
quit)
break
;;
*)
echo "Invalid option $REPLY"
;;
esac
done
脚本执行时显示菜单和 PS3 提示。用户被邀请选择程序并输入两位数。根据用户的输入,脚本将输出结果。
每次选择后,用户将被要求完成一个新的动作,直到中断指令被调用。
1) add
2) subtract
3) multiply
4) divide
5) quit
Select the operation: 1
Enter the first number: 4
Enter the second number: 5
4 + 5 = 9
Select the operation: 2
Enter the first number: 4
Enter the second number: 5
4 - 5 = -1
Select the operation: 9
Invalid option 9
Select the operation: 5
这个脚本的一个限制就是只能对整数进行运算。
这里有一个更复杂的版本。我们利用 bc 工具允许浮点数进行数学计算。此外,重复的代码被捆绑在一个函数中。
calculate () {
read -p "Enter the first number: " n1
read -p "Enter the second number: " n2
echo "$n1 $1 $n2 = " $(bc -l <<< "$n1$1$n2")
}
PS3="Select the operation: "
select opt in add subtract multiply divide quit; do
case $opt in
add)
calculate "+";;
subtract)
calculate "-";;
multiply)
calculate "*";;
divide)
calculate "/";;
quit)
break;;
*)
echo "Invalid option $REPLY";;
esac
done
输出:
1) add
2) subtract
3) multiply
4) divide
5) quit
Select the operation: 4
Enter the first number: 8
Enter the second number: 9
8 / 9 = .88888888888888888888
Select the operation: 5
结论
选择的结构使您能够设计菜单。方便构建需要用户输入的 shell 程序。
Linux 中的Tar
命令(创建和提取档案)
原文:https://www.studytonight.com/linux-guide/tar-command-in-linux-create-and-extract-archives
与 Linux 发行版捆绑在一起的 GNU tar 工具具有内置压缩功能。它可以生成一个. tar 档案,然后在一次操作中使用 gzip 或 bzip2 压缩来压缩它。这就是为什么结果文件是一个 .tar.gz 文件或. tar.bz2 文件。
压缩整个目录或单个文件
使用以下命令压缩整个目录或 Linux 上的单个文件。它还会压缩您指定的目录中的所有其他目录——换句话说;它递归运行。
tar -czvf name-of-archive.tar.gz /path/to/directory-or-file
以下是那些开关真正的含义:
-
-c:创建一个档案。
-
-z:使用 gzip 压缩存档。
-
-v:在构建归档文件时在终端中显示进度,通常称为“详细”模式。在这些说明中,v 通常是可选的,但它是有益的。
-
-f:允许您提供归档文件的文件名。
假设你在当前目录中有一个名为“stuff”的目录,你想把它保存到一个名为 archive.tar.gz 的文件中。您将执行以下命令:
tar -czvf archive.tar.gz things
或者,让我们假设在当前系统上有一个位于 /usr/local/ 的目录,并且您想要将其压缩为一个名为 archive.tar.gz 的文件。您将执行以下命令:
tar -czvf archive.tar.gz /usr/local/something
一次压缩多个目录或文件
虽然 tar 通常用于压缩单个目录,但您也可以使用它来压缩多个目录、大量单个文件或两者。只需提供一个文件或文件夹列表,而不是一个单独的列表。例如,假设您希望压缩 /home/ubuntu/Downloads 目录、/usr/local/stuff 目录和/home/Ubuntu/Documents/notes . txt 文件。您将执行以下命令:
tar -czvf archive.tar.gz /home/ubuntu/Downloads /usr/local/stuff /home/ubuntu/Documents/notes.txt
只需指定您希望备份的任意数量的文件夹或文件。
排除目录和文件
您可能希望在极少数情况下压缩整个目录,但不包括特定的文件和文件夹。您可以通过为您希望排除的每个指南或文件插入-exclude 选项来实现。
比如,假设你想压缩/home/ubuntu,但是不想压缩/home/ubuntu/Downloads 和/home/ubuntu/。缓存文件夹。你会这样做:
tar -czvf archive.tar.gz /home/ubuntu —exclude=/home/ubuntu/Downloads —exclude=/home/ubuntu/.cache
—exclude 开关功能强大。它不取文件夹和文件的名称——它取模式。你能做的还有很多。例如,您可以使用以下命令归档一个完整的目录并排除所有. mp4 文件:
tar -czvf archive.tar.gz /home/ubuntu —exclude=*.mp4
请改用 bzip2 压缩。
而 gzip 压缩通常用于生成. tar.gz 或。tgz 文件,tar 还支持 bzip2 压缩。这使您能够生成 bzip2 压缩文件,通常称为. tar.bz2、. tar.bz 或。tbz 文件。为此,将脚本中 gzip 的 -z 替换为 bzip2 的 a -j。
【Gzip】比较快,但是压缩往往会少一点,所以你收到的文件会稍微大一点。Bzip2 速度较慢,但它会卡住一点,所以你会得到一个稍微小一点的文件。Gzip 也越来越流行,一些精简的 Linux 系统默认提供 gzip 支持,但不支持 bzip2。然而,总的来说,gzip 和 bzip2 实际上是相同的,两者的性能相似。
例如,我们给出的第一个例子是压缩目录,而不是执行以下命令:
tar -cjvf archive.tar.bz2 things
提取档案
一旦你有了一个档案,你可以使用 tar 命令提取它。以下命令将把 archive.tar.gz 的内容移至当前目录。
tar -xzvf archive.tar.gz
它与我们之前使用的归档文件创建命令相同,只有 -x 选项替代了-c 开关。这表明您希望提取一个归档文件,而不是生成一个。
您可以选择将档案的内容提取到指定的目录中。您可以通过将-C 开关连接到命令的末尾来实现这一点。例如,以下命令将 archive.tar.gz 文件的内容提取到 /tmp 目录。
tar -xzvf archive.tar.gz -C /tmp
如果文件是bzip2-压缩文件,用“ j 替换前面说明中的“z”。
这是 tar 命令最简单的用法。该命令提供了许多其他选项,因此我们不能合理地将它们都放在这里。欲知详情。在 shell 中执行 infotar
命令,显示tar
命令的完整信息页面。完成后按 q 键离开信息页面。你也可以在线阅读 tar 手册。
Linux 中的diff
命令
原文:https://www.studytonight.com/linux-guide/diff-command-in-linux
diff 程序逐行比较两个文件,并生成一个更改列表。作为一种特殊情况,diff 将标准输入的副本与其自身进行比较。“如何在 Linux 中使用 diff 命令”是本文的主题。
“差异”指令的未来前景
识别文件的一个版本和另一个版本之间的差异。
比较两个配置或应用文件。
制作一个补丁文件,可以与 Linux / Unix 应用补丁一起使用。
什么是“diff”命令,它是如何工作的?
例如,我们有两个名为 file.txt 和 file1.txt 的文件。如下图所示,数据已输入 file.txt
I need to go out and get some apples.
I have to do some laundry.
I need to bathe the dog.
I'm going to have to have the automobile detailed.
文件 1.txt 中的数据如下:
I need to go out and get some apples.
I've got some laundry to do.
The automobile needs to be washed.
I need to conduct some research on the dog.
要比较这两个文件,请使用如下所示的 diff 命令—
$ diff /home/linux/Desktop/file.txt /home/linux/Desktop/file1.txt linux@linux
前面命令的输出应该如下:
$ diff /home/linux/Desktop/file.txt /home/linux/Desktop/file1.txt linux@linux
I have to do the laundry.
I need to bathe the dog.
I'm going to have to have the automobile detailed. > —- I've got some laundry to do.
> I'm going to have to wash the automobile.
> I need to acquire the dog's information.
结果的选择应该如下:
a-我已经将文本保存到文件中。
c-文件已被修改。
d-执行删除操作。
第一个文件中的行
第二个文件的行
根据输出,必须更改第一个文件中的第 2 行到第 4 行,以匹配第二个文件中的第 2 行到第 4 行。
再举一个例子:两个文本文件应该是这样的:
file.txt
I'm going to the store.
I need to go out and get some apples.
I'll bathe the dog when I come home.
file1.txt
I'm going to the store.
I need to go out and get some apples.
Oh, and I need to get some shredded cheese as well.
I'll bathe the dog when I come home.
要比较这两个文件,请使用 diff 命令。命令应该这样写:
/home/linux/Desktop/file.txt /home/linux/Desktop/file1.txt /home/linux/Desktop/file2.txt /home/linux/Desktop/file2.txt /home/linux/Desktop/
前面命令的输出应该如下:
2a3
Oh, and I need to get some shredded cheese as well.
结果中的 2a3 表示“必须在第一个文件的第 2 行之后插入一行:第二个文件的第 3 行。”
恭喜你!你现在明白了如何在 Linux 中使用 diff 工具。“在我们即将发布的 Linux 文章中,我们将了解更多关于这些命令**的信息。继续读!
Linux HowTo
如何在 Ubuntu 20.04 LTS 上安装 MySQL?
原文:https://www.studytonight.com/linux-guide/how-to-install-mysql-on-ubuntu-20-04-lts
MySQL 是一个开源的关系数据库管理系统(RDBMS),用于将数据存储到表中。在本教程中,我们将在 Ubuntu 20.04 LTS 上安装 MySQL。因此,让我们开始并遵循以下步骤。
步骤 1:更新包索引
安装之前,我们先用sudo apt update
命令更新包索引。
第二步:安装 MySQL 服务器
更新包索引后,现在我们可以使用下面的命令安装 MySQL 服务器了。
$ sudo apt install mysql-server
它会将数据库安装到我们的本地系统中。我们可以在控制台屏幕上看到教学信息。
根据您的网络速度,安装 MySQL 服务器软件包需要几分钟时间。
步骤 3:配置 MySQL
成功安装后,我们需要运行安全脚本,尤其是如果我们是第一次安装它。
这将带我们通过一系列提示。
选择 Y 或 Y 进行密码设置,如上图所示。
如上图所示的密码插件,对于认证你想选择什么样的密码有三级密码
输入密码时,没有任何符号显示为*符号。您的密码不可见。脚本完成后,它会询问您是要继续输入密码,还是要输入新密码。如果您满意,请输入 y 继续。
输入密码后,它会提示您一些安全选项,您应该选择这些选项来保护 MySQL 服务器。
- 删除匿名用户?(按 y|Y 表示“是”,按任何其他键表示“否”):Y
- 不允许根用户远程登录?(按 y|Y 表示“是”,按任何其他键表示“否”):Y
- 删除测试数据库并访问它?(按 y|Y 表示“是”,按任何其他键表示“否”):Y
- 现在重新加载特权表吗?(按 y|Y 表示“是”,按任何其他键表示“否”):Y
脚本完成后,继续使用 MySQL 客户端创建一个专用数据库用户。
第四步:连接到 MySQL 服务器
$ sudo mysql
完成所有配置和设置后,让我们使用上面的命令运行 MySQL。运行此命令并输入您的系统密码
输入有效密码后,它会显示以下消息。
要清洗终端控制台,可以使用ctrl + L
快捷键。
第五步:检查 MySQL 的版本
要检查 MySQL 服务器的安装版本,请运行mysql --version
命令。
第 6 步:测试 MySQL 状态
要检查服务器的当前状态,我们可以使用systemctl status mysql.service
命令,该命令将显示信息以及进程 id。
在 MySQL 中创建新用户
我们可以为 MySQL 创建新用户来控制用户的可访问性。使用下面的命令,将用户名和密码作为参数。
CREATE USER 'username'@'host' IDENTIFIED WITH authentication_plugin BY 'password';
成功创建用户后,它会返回一条消息“查询正常”。
创建新用户后,我们还可以授予新用户适当的权限,如 CREATE、ALTER、DROP、INSERT、DELETE、SELECT 等。
授予用户权限的一般语法如下:
GRANT PRIVILEGE ON database.table TO 'username'@'host';
登录到 MySQL 服务器
要访问 MySQL 数据库,请使用下面的命令来创建和运行 SQL 查询。
$ mysql -u username -p
这里 -u 为用户标志, -p 为密码认证标志。
停止 MySQL 服务器
要停止运行 MySQL,我们可以使用以下命令。
$ service msql stop
重新启动 MySQL 服务器
要重新启动 MySQL,请运行以下命令。它将首先停止当前进程,然后启动 MySQL 服务的新实例。
$ service msql restart
删除 MySQL
要从 Ubuntu 中删除 MySQL,请运行以下命令。它将从您的本地系统中删除 MySQL 服务器。
$ sudo apt-get remove mysql-server
Bash Shebang
如果你是通过阅读别人的代码来学习 Bash 脚本,你可能已经观察到脚本的第一行是以#开头的!字符和 Bash 解释器的路径。
这个序列的字符 (#!)被称为 Shebang,用于通知操作系统使用哪个解释器来解析文件的剩余部分。
希邦口译员指令
舍邦解释器指令有以下形式:
#!interpreter [arguments]
- 指令必须是脚本中的第一行。
- 指令必须以开头 #!
- 舍邦字符后面的空格是可选的。
- 解释器是一个二进制文件的完整路径(例如:/bin/sh,/bin/bash)。
- 解释器参数是可选的。
示例:
- #!/bin/bash - 使用 bash 解析文件。
- #!/usr/bin/env perl - 使用 env 命令定位 perl 可执行文件的路径。
- #!/usr/bin/python - 使用 python 二进制执行文件。
在 Bash 脚本中使用 Shebang
假设没有给出 shebang,执行 Bash 脚本的用户正在使用另一个 Shell。在这种情况下,无论 Shell 使用什么作为默认解释器,脚本都将被解释。例如,Bash 的默认解释器是 Bash,而对于 zsh 则是 sh。为了保证您的脚本总是被 Bash翻译,您需要使用 Shebang 提供可执行路径。
有两种方法可以使用 Shebang 指令和设置解释器。
使用 bash 二进制的绝对路径:
#!/bin/bash
使用环境实用程序:
#!/usr/bin/env bash
第二种技术的好处是,它将在用户的 $PATH 环境变量中寻找 bash 可执行文件。如果有多条路径可以痛击,脚本将选择第一条。
当使用第一个选项时,给 Bash shell 添加一个替代项,并将其发送给解释器。例如,要在调试模式下执行脚本,可以使用 #!/bin/bash -x. 如果使用 env 方法,则需要使用集合来定义选项。要激活调试模式,您可以将 set -x 放在 shebang 行之后。
示例脚本
让我们用 Shebang 构造一个基本脚本来输出“你好,世界。”打开文本编辑器,粘贴如下一行:
nano hello world
#!/bin/bash
echo "Hello, World"
为了能够在不从命令行提供解释器的情况下执行脚本,您需要使文件可执行:
chmod +x hello world
现在如果你可以通过输入执行脚本。/后跟脚本名称:
./hello world
越过沙邦
如果出于任何原因,您希望覆盖在 Shebang 行中设置的解释器,您需要通过显式提供预期的 Shell 来执行脚本。比如执行一个有 #的脚本!在使用 bash shell 的 Shebang 行中提供的/bin/sh 中,您可以键入:
bash hello world
请注意,覆盖 shell 解释器不是一个好主意,因为这可能会导致意外的脚本行为。
结论
到目前为止,你应该已经对什么是 Shebang 以及如何在你的 Bash 脚本中使用它有了一个相当好的了解。
如果你有任何问题或建议,请留言。
Linux 中的 cURL 如何传输数据?
原文:https://www.studytonight.com/linux-guide/curl-in-linux-how-to-transfer-data
cURL ,通常写成**curl**
,是一个 Linux 实用程序,用于从服务器或向服务器传输数据,使用任何协议,如 HTTP、HTTPS、FTP、FTPS 等(对于多文件传输**wget**
或 FTP 是可取的)。
curl 提供了各种选项,例如恢复传输、限制带宽、代理支持等等。
安装 cURL
在大多数 Linux 发行版上,CUlR 是预装的,但是在极少数情况下,它不是预装的,您的发行版 repo 应该有最新版本的 CUlR。
要检查是否安装了 cURL,只需单独运行命令**curl**
。如果没有安装 CUlR,它会返回一个 CUlR 未安装的错误,您可以使用以下命令将其安装在 Ubuntu 上。
sudo sh -c 'apt update && apt upgrade'
sudo apt install curl
使用 cURL
curl 有一个非常简单的语法,看起来像
curl [OPTIONS] [URL...]
例如,你想检索google.com
的主页,我们会运行以下内容。
curl google.com
输出将被打印到控制台。另外,如果没有指定协议,cURL 会尝试猜测,否则默认为 HTTP。
保存输出
cURL 输出可以通过两种方式保存。一个使用预定义的名称,或者两个使用原始名称。两者分别由-o
和-O
完成。
比如取google.com
,存储到index.html
,运行的命令如下。
curl -o index.html gooogle.com
下载多个文件
当要下载多个文件时,我们使用多个-o
和-O
选项,后跟文件名和网址,或者只有网址。因此,要获取google.com
并将其存储到google.html
,将duckduckgo.com
存储到duckduckgo.html
,我们将运行以下命令。
curl -o google.html google.com -o duckduckgo.html duckduckgo.com
恢复下载
有时,由于网络崩溃、停电、低带宽和许多其他原因,我们的下载会停止。当这种情况发生时,cURL 会拯救我们。我们不需要从头再下载所有东西,有了-C -
选项,我们就可以恢复下载,不会面临任何问题。
例如,假设您正在下载 Ubuntu-21.04 ISO,并且您的网络崩溃,我们可以使用以下命令恢复下载。
curl -O https://releases.ubuntu.com/21.04/ubuntu-21.04-desktop-amd64.iso # Download for ISO file
curl -C - -O https://releases.ubuntu.com/21.04/ubuntu-21.04-desktop-amd64.iso # Resume download by taking the previous command and adding -C -
跟踪重定向
有时一个页面已经移动了,如果你试图卷曲它,你会得到一个错误的页面,一个指向新网址的链接,或者一个带有后端服务器引擎名称的空白页面。您可以指示 cURL 按照这些重定向到新的位置,无论它们在哪里。例如,如果你卷曲duckduckgo.com
你会得到下面的页面。
但是如果你使用重定向标志,即-L
,它会引导到正确的站点,如下所示。
curl -L duckduckgo.com
指定最大传输速率
cURL 可以使用--limit-rate
标志限制正在下载的文件的传输速率。可以使用k
指定千字节的大小,m
指定兆字节的大小,g
指定千兆字节的大小。比如下载google.com
首页,以 1k 的速度,我们运行以下命令。
curl -L -o google.html google.com --limit-rate 1k
为了看出区别,我们执行了相同的命令,一次有--limit-rate
,一次没有。
使用代理
要使用代理,我们使用-x
/ --proxy
标志,后跟代理 URL。
例如,对于 192.168.33.24 端口 8000 上的代理,我们将运行以下命令。
curl -x 192.168.33.24:8000 https://www.google.com
如果代理服务器需要身份验证,-U
/ --proxy-user
标志与参数一起以如下所示的语法传递。
curl -U user:pass -x PROXY_IP:PROXY_PORT <IP or Name>
结论
本教程是如何在您的系统上安装 cURL,然后使用**curl**
程序从远程机器下载文件的便捷指南。它还展示了如何限制带宽,以及如何通过 cURL 连接到代理,等等。
在 Ubuntu 上安装和使用 PIP
原文:https://www.studytonight.com/linux-guide/installing-and-using-pip-on-ubuntu
Pip 是一个用于索引的工具,并且主要从 Python 包索引(PyPI)安装包,但是它也可以与其他包索引一起使用。
Pip 代表“首选安装程序”,是一个基于 python 的应用,用于 python 编程语言的包管理。它有助于管理库和依赖项,而不是手动操作。
Python 有两个版本,第 2 版和第 3 版。最新版本的默认版本是 Python 3。仍在使用 Python 2 的用户,建议切换到 Python 3。
从**apt**
安装 Python 包时,Python2 包前加一个python2-
,Python3 包加python3-
。
当安装 python 包时,如果您想全局安装,通常建议安装 apt repo 中可用的包,因为它们经过测试,是安全的 deb 包。
安装**pip**
要安装 pip
,首先,更新你的软件包库,然后安装**pip**
,使用以下命令。
sudo apt update
sudo apt upgrade
sudo apt install python3-pip
安装完成后,检查安装是否成功,运行以下命令。
pip3 --version
输出可能会有所不同,但看起来如下所示
使用pip
在这一节中,我们将看到 pip 的一些基本命令和用法。有了 pip,可以安装来自 PyPI、版本控制、本地项目的包,但我们将主要关注 PyPI。
获取 pip 运行支持的所有命令的列表
pip3 --help
关于命令的更多信息,我们可以运行**pip3 <command> --help**
或**pip3 <command> -h**
。
例如,为了获得安装帮助,我们运行
pip3 install -h
安装软件包
要安装软件包,您需要知道软件包名称。比如说你想安装[colorama](https://pypi.org/project/howdoi/)
包。命令如下
pip3 install colorama # To install a specific version, say 0.4.0 write colorama==0.4.0
使用需求文件安装
**requirement.txt**
是 python 包使用的文本文件,列出了依赖项和运行该项目所需的版本号。要使用需求文件进行安装,我们可以使用以下命令。
pip3 install -r requirement.txt
列出安装包
要列出包,我们运行以下命令。
pip3 list
升级包
要升级软件包,我们需要安装带有--upgrade
/ -U
标志的软件包。
pip3 install -U colorama
卸载包
可以使用以下形式的卸载命令卸载 Pip 包。
pip3 uninstall colorama
结论
本教程讲述了如何安装**pip**
,以及它是什么。它还展示了如何使用**pip**
做基本的事情,以及如何在你的 Ubuntu 上安装 python 包。
如何将用户添加到组?
原文:https://www.studytonight.com/linux-guide/how-to-add-user-to-a-group
改变用户所属的组是一项基本的任务,但不是每个人都知道如何去做。在本教程中,我们将与您一起讨论这一点。
Linux 组
组是 Linux 用来组织和管理用户帐户的组织单位。组的主要目的是定义权限,如读取、写入和执行权限。
组主要有两种类型:
- 主组:创建文件时,
**/etc/passwd**
文件中为当前用户指定的组作为所有者组。通常,它是一个与用户同名的组。 - 二级组:授予某组成员一定权限时有用。例如,如果用户被添加到
docker
组,他们现在将能够执行docker
命令。
每个用户只属于一个主要组,但属于多个次要组。
只有 root 或具有**sudo**
访问权限的用户才能编辑用户所属的组。
将现有用户添加到组
如果我们已经有了用户,并且设置了组,并且我们想要添加用户,我们可以使用**usermod**
或**gpasswd**
(避免危险错误的更安全的选项)。例如,我们想要将用户dakksh
添加到组docker
中,我们将运行
sudo usermod -a -G docker dakksh # -a represents append. Leaving out -a, will remove user from all other groups
sudo gpasswd -a dakksh docker # Add user to group docker
成功时,没有输出,但如果用户或组不存在,则会显示一条错误消息。
将用户添加到多个组
如果我们想将一个用户添加到多个组中,我们为 usermod
命令中的-G
标志提供一个逗号分隔的列表。因此,要将用户dakksh
添加到组docker
和sambashare
中,我们运行以下命令
sudo usermod -a -G docker,sambashare dakksh
从组中删除用户
要从组中删除用户,我们可以使用-d 标志和**gpasswd**
命令运行。因此要将用户dakksh
从组docker
中移除,我们运行
sudo gpasswd -d dakksh docker
创建新组
为了创建一个新的组,我们运行**groupadd**
,如下所示。
sudo groupadd groupName
删除组
要删除一个组,我们运行**groupdel**
,方式如下
sudo groupdel groupName
更改用户的主要组
要更改用户的**gid**
,我们使用带有-g
标志的**usermod**
命令。传递给-g
标志的参数可以是组名或 GID 。因此,要将当前用户的默认组更改为**sudo**
,我们可以这样做
sudo usermod -g sudo dakksh
同时创建用户和分配组
要创建用户,我们可以使用 useradd
命令,但我们不能只使用该命令创建用户。我们可以分配组,甚至用这个命令指定用户的主要组。例如,我们想要创建一个分配给组sudo
、docker
、sambashare
的用户vim
,并将主组设为dakksh
(GID 1000),我们将运行以下命令。
sudo useradd -g 1000 -G sudo,docker,sambashare vim
列出用户组
使用 id
或**groups**
我们可以列出主要和次要的用户组。**id**
是按以下格式运行的。
id [OPTIONS] [USER]
单独运行**id**
命令会给出uid
、gid
和groups
。
使用选项参数,通过-u
、-g
或-G
中的任意一个,组合或分开分别给出数值形式的uid
、gid
和groups
。
通过-n
标志,我们得到了**id**
返回的数字标识的名称。为了获得特定用户的组,我们指定用户名。
要使用**groups**
命令获取组,格式如下。
groups [USER]
默认情况下,如果没有提到用户,**id**
和**groups**
都使用当前用户。
结论
我们已经看到了如何使用**gpasswd**
和**usermod**
命令将用户添加到次要组或修改他们的主要组。
还介绍了如何创建用户并同时分配组,以及如何列出用户所属的组。
如何在 Linux 中找到文件?
原文:https://www.studytonight.com/linux-guide/how-to-find-files-in-linux
每个人都曾一度忘记他们把东西放在哪里,或者他们最后一次看到东西的地方,这也延伸到我们电脑上的文件和文件夹。
当我们想要找到一个文件时,我们可以通过浏览所有我们最后记得文件在哪里的文件夹来浪费宝贵的时间,或者依靠方便的 Linux 工具,比如find
、locate
,甚至fzf
。
本教程将涵盖find
程序的使用,以及如何使用众多选项中的一些来加快过程。
find
是一个方便的 Linux 实用程序,是 SysAdmin 武库中的一个很好的工具,如果使用得当,可以节省时间。可以结合grep
或sed
等工具,进一步加快进程。该程序根据用户给出的表达式在目录层次结构中搜索文件和目录,并在命令行标志的帮助下,对匹配项执行用户指定的操作。
通过操纵标志,您可以使用find
根据用户、组、上次编辑日期、类型、大小等搜索文件。
find
命令语法
find [OPTIONS] [STARTING-POINT] [EXPRESSION]
- OPTIONS :控制符号链接的处理方式、调试选项和优化级别。
- 起始点:开始搜索并递归下降的路径。
- 表达式:指定匹配要搜索文件的表达式、正则表达式类型、递归搜索深度等选项。
要搜索任何文件,用户需要该目录的读取权限。
假设我们想在一个文件夹中搜索所有 HTML
文件,从我们的起点开始最大深度为 3,我们会写下以下内容:
find Documents/ -maxdepth 3 -name '*.html'
上述命令以下列方式运行
- 我们从当前目录的
Documents
文件夹开始搜索 - 程序应该从其当前位置最多遍历 3 个目录的深度
- 它搜索所有
**HTML**
文件,其名称中包含任意数量的字符
为了使搜索不区分大小写,例如,搜索以**HTML**
结尾的文件,而不是**html**
,我们可以使用 -iname
标志来代替**-name**
,其中 I 表示不区分大小写。
现在来介绍一些最重要的 find
命令的旗帜,上面没有解释
-
**-not**
:find Documents/ -maxdepth 3 -not -name '*.html'
对于上面的例子,所有与指定模式不匹配的文件都会被返回,因此我们可以得到一个 JPG 文件。
-
**-type**
:
这指定了我们正在搜索的对象的种类。它的形式是-type *c*
,其中*c*
可以是多个值之一,但是普通用户使用的是***f***
、***l***
和***d***
。
***f***
代表文件,***d***
代表目录,***l***
代表符号链接。因此,find Documents/ -maxdepth 3 -type f -name '*git*' # Files having the word git in name find Documents/ -maxdepth 3 -type d -name '*git*' # Folders having the word git in name find Documents/ -maxdepth 3 -type l -name '*git*' # Symbolic links having the word git in name
-
**-size**
:
根据文件大小查找文件。旗帜的形式为-size [+-]n[cwbkMG]
([]中的字符是可选的,表示要使用这些字符中的一个)。这些字符的含义如下性格;角色;字母 意义 ±
(缺席表示文件大小准确)**+**
-大于指定大小的文件**-**
-小于指定大小的文件n
文件大小 c
字节 w
双字节字 b
512 字节块(默认) k
千字节(1024 字节的单位) M
mebi bytes(1024 * 1024 的单位= 1048576 字节) G
吉比字节(1024 * 1024 * 1024 = 1073741824 字节的单位) 尺寸不是圆形的。这意味着
-1M
的大小与**-1048576c**
不同,因此,前者将只匹配空文件,而后者将匹配所有大小小于 1048576 字节的文件。要搜索范围内的文件,可以使用如下命令find -type f -size +40M -size 60M # Returns all files with 40 < fileSize <= 60 M
-
-mtime``-daystart
:
-mtime
是**-mtime [+-]n**
的形式,其中 n 代表*n * 24*
小时。±
与-size
的意思相同。**-daystart**
用于使时间测量从当天开始开始,而不是从 24 小时前开始。
因此要找到一个不到 5 天前编辑过的文件,从今天开始,我们会使用find -type f -mtime -5 -daystart
-
**-perm**
:
通过权限查找文件,我们使用-perm
。如果按原样使用-perm
,它将匹配确切的权限,例如-perm 664
,将为用户和组匹配所有具有读写权限的文件,但只为其他人匹配读取权限。如果权限号前面有一个/
,则它确保至少一个权限(用户、组或其他)匹配。如果许可号前面加了一个**-**
,则保证至少设置了那些位,如果设置了更多位也没关系。因此,如果我们搜索一个标志为**-perm -117**
的文件,如果该文件的权限为 777 ,它将返回该文件作为真正的匹配。 -
-user``-group
:-
-user
用于通过提供用户名或 UID 来查找特定用户拥有的所有文件 -
-group
用于查找某个组拥有的文件,使用组或 GID
因此,要搜索 UID 为 1000 的用户和组 docker 拥有的所有文件,我们将运行
find -executable -user 1000 -group docker
-
-
-delete
:
对于给定的表达式,该选项删除所有返回真的文件。 -
-execdir``-executable
:
-execdir
用于对文件和/或目录执行与用户指定的选项和模式相匹配的命令来运行命令。字符串{}
扩展为当前文件名,每个文件运行一次指定的命令。以下所有文本都被视为命令,直到没有遇到;
为止。为了避免被 shell 扩展,这些字符串应该被引用,或者用\
字符转义。-executable
另一方面,用于匹配可执行文件。
结论
本教程已经介绍了find
命令,以及如何利用它来搜索文件系统中的文件和/或目录。它还涵盖了如何优化您的搜索,以及如何在文件上运行命令,而无需制作辅助列表。
如何提取 TGZ 文件?
原文:https://www.studytonight.com/linux-guide/how-to-extract-tar-gz-file
Linux 使用tar
命令提取 tar 存档文件。Tar 是为归档磁带文件而创建的 T 猿 Ar 细香葱的缩写。
它通常用于创建和提取 tar.gz 文件。相同的命令可用于创建和提取文件。它提供了几个选项,可以用于多种目的,如创建、移动、提取档案等。
在本文中,我们将学习如何在 Linux 中提取 tar.gz 档案文件。
在 Linux 中提取 tar.gz 文件的命令
tar -xf archive.tar.gz
这里,-x 表示提取,而-f 表示文件。
tar 支持广泛的压缩程序,如 gzip、lzip、bzip2、lzma、xz 等。
正在提取 tar.gz 文件
tar 预装在所有的 Linux 版本中,因此您可以使用下面的命令直接使用它。
$ tar -xf archive.tar.gz
这里,-x 用于提取存档文件。
上述命令将提取当前目录中的文件。除此之外,如果你在基于图形用户界面的系统上工作,那么你可以通过右击文件并选择全部提取来直接提取文件。它还会将文件提取到同一目录中。
如果你想获得所有解压文件到终端控制台的详细信息,那么使用-v 选项和tar
命令。
$ tar -xvf archive.tar.gz
这里,-v 表示控制台的详细输出。
将 tar.gz 文件提取到不同的目录
我们知道,默认情况下,文件是在同一个目录中提取的,但是我们可以通过使用tar
命令中的-C 选项来更改目录。例如,如果我们想在今晚的研究中将文件移动到一个文件夹中,那么使用这个命令。
$ tar -xvf archive.tar.gz -C /home/studytonight/myfolder
从 tar.gz 文件中提取特定文件
有时,我们只想从档案中提取选择性文件。在这种情况下,请在命令中指定文件名。
$ tar -xvf archive.tar.gz file1 file2 file3
它将只从归档中提取文件 1、文件 2 和文件 3。
我们可以使用相同的命令从归档文件中提取特定的目录。在给出文件或目录名时,请确保名称正确,因为不正确的名称会导致命令失败。
从 tar.gz 文件中提取相似文件
如果你想从档案中提取类似类型的文件,如 txt、pdf 或 doc 等。然后在tar
命令中使用星号(*)通配符,将只提取指定的文件。
$ tar -xvf archive.tar.gz --wildcards *.txt
它将只从档案中提取 txt 文件。
列出 tar.gz 文件
要检查 tar 归档文件中的文件列表,我们可以在命令中使用-t 选项。
$ tar -tvf archive.tar.gz
它会将所有文件输出到控制台,而不提取文件。因为我们使用了-v 选项,所以它将向控制台显示详细的输出。
结论
tar
命令可用于压缩和解压缩文件。要将文件压缩到 tar.gz,请使用-c 选项,要提取文件,请使用-x 选项和命令。它还提供了几个选项,例如将提取文件移动到不同的目录,或者使用-v 选项获得详细的输出。这篇详细的文章涵盖了tar
命令的所有方面。
如何在 Linux 中解压文件?
原文:https://www.studytonight.com/linux-guide/how-to-unzip-files-in-linux
解压缩是一个实用程序命令,用于从 zip 文件中提取文件和目录。它可以用来提取单个或多个文件,甚至可以提取受密码保护的文件。
在本文中,我们将学习在几个选项和场景中使用unzip
命令。所以,让我们开始学习。
Linux 中Unzip
文件的命令
unzip filename.zip
在开始解压缩之前,首先确保它安装在您的计算机上,因为大多数 Linux 版本都没有预安装它。
因此,首先,使用以下命令安装它。这是针对 Debian/Ubuntu 系统的。
$ sudo apt install unzip
如果您使用的是 Centos ,那么使用此命令安装解压缩实用程序。
$ sudo yum install unzip
如果您正在使用软呢帽,那么使用这个命令来安装解压缩实用程序。
$ sudo dnf install unzip
如何Unzip
文件和目录?
这是一个简单易行的命令,只需用这个命令在 Linux 中解压一个 zip 文件。请确保 zip 文件应该在同一个目录中,否则您必须提供正确的 zip 文件路径来定位该文件。
$ unzip filename.zip
它会将所有文件提取到当前目录位置。
您必须对解压 zip 的目录有写权限。
抑制unzip
命令的输出
当我们解压缩一个文件时,它会向控制台显示所有文件内容,如果我们想要隐藏/跳过这些信息,那么您可以使用-q 选项和解压缩命令。
$ unzip -q filename.zip
Unzip
将压缩文件保存到不同的目录
如果我们想将 zip 文件解压缩到当前目录之外的其他目录,那么使用命令的-d
选项并提供目录的完整路径。
$ unzip filename.zip -d /path/to/directory
由于我们正在向不同的目录写入(解压缩),因此必须将sudo
与命令一起使用,因为我们必须对该目录拥有写入权限。
Unzip
受密码保护的压缩文件
如果 zip 文件受密码保护,则使用-p
选项,命令将在解压缩前提示输入密码。
$ unzip -p filename.zip
解压缩多个文件
我们可以通过使用正则表达式来匹配所有的 zip 文件来解压缩多个文件。我们可以使用星号(*)通配符进行多选。比如:
$ unzip '*.zip'
它将在当前目录中搜索 zip 文件,并在同一目录中提取每个文件。最好使用单引号来绑定通配符。
显示压缩文件的内容
在这种情况下,您希望在提取之前看到 zip 文件的内容,然后在命令中使用-l
选项,它会在控制台屏幕上列出 zip 文件的所有内容。
$ unzip -l filename.zip
输出:
覆盖现有文件
如果解压缩文件已经被提取,并且您想再次unzip
解压缩,那么解压缩命令提示一些选项,如覆盖一个文件,覆盖所有文件等。要覆盖这些,您可以使用解压命令的-o
选项。
$ unzip -o filename.zip
结论
unzip
命令对 Linux 用户非常有用。它简化了工作,并提供了多用途的几个选项。在本文中,我们学习了如何在多个场景中使用解压,比如解压单个文件、多个文件、覆盖文件、列出 zip 文件内容等。
如何在 Ubuntu 20.04 中安装谷歌 Chrome?
原文:https://www.studytonight.com/linux-guide/how-to-install-google-chrome-in-ubuntu-2004
谷歌 chrome 是一款用于网上冲浪的网络浏览器。它是谷歌公司的产品,也是市场上最受欢迎的浏览器之一。
它提供了巨大的功能和出色的性能,这使得它成为当今每个程序员的选择,无论是在 windows、Linux 还是 macOS 上工作。
在本文中,我们将学习如何将其安装到 Ubuntu 20.04 中。那么,让我们开始吧。
1.下载谷歌浏览器
首先使用以下命令下载谷歌 chrome。它会将文件下载并存储到您的本地系统中。使用Ctrl+Alt+t
组合键打开终端,输入该命令。
$ wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
成功下载后,安装安装程序,使其可在计算机上运行。
2.安装谷歌浏览器
使用这个命令安装谷歌浏览器。因为我们正在安装安装程序,所以您必须拥有管理员权限。使用 Sudo 与命令一起使用。在开始安装之前,它会询问密码,所以请输入您的密码并让它安装。
$ sudo apt install ./google-chrome-stable_current_amd64.deb
成功完成这个命令后,谷歌 chrome 已经安装完毕。所以,现在你可以打开它开始工作了。
3.打开谷歌 Chrome
从谷歌 chrome 开始,只需点击 windows 键,或者搜索并输入 chrome,就会出现一个图标。所以,只要点击这个图标,谷歌浏览器就会打开。
按下回车键或点击后,将打开一个新窗口,您可以开始浏览。
一切就绪,我们已经成功地在本地计算机上安装了 chrome。让我们来探索 chrome 的一些其他操作。
更新谷歌 Chrome
您不需要担心更新 chrome,因为在安装过程中,系统中添加了一个文件,该文件会自动检查最新版本,并在 chrome 可用时进行更新。您可以使用以下命令检查文件。
$ cat /etc/apt/sources.list.d/google-chrome.list
它将向终端屏幕显示以下输出。
### THIS FILE IS AUTOMATICALLY CONFIGURED ###
# You may comment out this entry, but any other modifications may be lost.
deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main
移除谷歌浏览器
在这种情况下,如果你想从你的本地系统中删除谷歌浏览器,那么使用下面的命令。
$ sudo apt-get purge google-chrome-stable
$ mv ~/.config/google-chrome/ ~/.config/google-chrome.bak/
第一个命令将完全删除 chrome,第二个命令将配置文件移动到备份目录。
结论
最后,我们学会了在本地系统中安装谷歌 chrome。我们可以用最新版本更新 chrome,甚至可以在需要的时候移除。本教程帮助你一步一步地安装 chrome。
如何检查你的 Ubuntu 版本?
原文:https://www.studytonight.com/linux-guide/how-to-check-your-ubuntu-version
Ubuntu 是一个流行的开源操作系统。它被 Linux 爱好者广泛使用,它的 Gnome 特性给了它一个新的优势,使它在其他开源系统中很受欢迎。
当我们打开 ubuntu 的时候,会想到一个问题,我用的是什么版本的 ubuntu?然后我们开始搜索以了解版本细节。
在本文中,我们将学习检查您当前安装的 ubuntu 的版本。所以,让我们从探索开始。
使用 Gnome 图形检查 Ubuntu 版本
检查版本是最简单的方法之一,只需到桌面的右上角点击,然后选择设置即可。
选择设置后,将显示以下屏幕,点击左侧菜单中的关于部分,它将显示我们当前系统的所有细节。
使用 hostnamectl 命令检查 Ubuntu 版本
hostnamectl
命令可以用来检查当前的 Ubuntu 版本,因为它返回了与主机名设置相关的所有细节。
使用 lsb_release 命令检查 Ubuntu 版本
lsb_release
命令可以用来获取 Ubuntu 版本。它返回操作系统的分发信息。这里, -a 用于打印所有信息。
如果我们只想获得单行信息,那么使用这个命令使用 -d 选项。
使用 cat/etc/发布命令检查 Ubuntu 版本
cat
命令用于显示文件的内容。在这里,我们使用它来显示包含系统标识文本的 /etc/issue 文件的内容。
使用 cat /etc/os-release 命令检查 Ubuntu 版本
如果您使用的是最新版本的 ubuntu 16 或更高版本,这个命令对您很有用。 os-release 文件包含与操作系统及其版本相关的信息。
结论
在本文中,我们学习了如何了解和获取 Ubuntu 版本。我们使用了 Gnome 图形、lsb 命令、os-release、/etc/issue 等文件。希望看完文章后,能轻松拿到你的系统版本。
如何在 Vim/Vi 中保存文件并退出编辑器?
原文:https://www.studytonight.com/linux-guide/how-to-save-a-file-in-vim-vi-and-quit-the-editor
Vim 是 Linux 中常用的编辑工具,用于编辑。它是最受欢迎的编辑器之一,也可以用于文本编辑和编码。
Vim 也被称为 Vi,预装在所有的 Linux 发行版和 macOS 中。在本文中,我们将通过一些例子学习如何在 Vim 编辑器中保存和归档。
在 vim 编辑器中保存和退出文件的组合键。首先按下Esc
并输入以下内容:
:wq
之后按Enter
。这是针对您的问题的单行解决方案。让我们深入了解整个过程。
首先,按下Ctrl+Alt+t
打开终端,系统中会打开一个终端。现在,看一步一步的过程。
1.用 Vim 编辑器打开文件
要在 Vim 编辑器中打开文件,在终端中写入vim fileName
命令,然后按回车键。它将打开您在命令中指定的文件。如果该文件不存在,它将首先创建一个同名文件,然后打开该文件。请参见命令。
$ vim fileName
文件名可以是任何文本、HTML 或文档文件。因此,我们必须指定扩展名为 file.txt、file.doc 等的文件。
2.写入 Vim 编辑器
打开文件后,我们可以通过插入文本(书写)来修改文件。
要写入文件,按下将 vim 编辑器转换为写入模式的i
,在这里可以写入文件。大家可以看到下面截图我们插入一行,左下方可以看到编辑器模式,现在是插入。
3.保存到 Vim 编辑器中
写入/插入文本后,我们可以通过按以下键来保存文件:
-
转义字符
-
:(冒号)
-
w
-
进入
先按Esc
,再按:
(冒号)和w
,最后按Enter
。它会将您的文件数据保存到 vi 编辑器中。请参见屏幕截图以获取帮助。
4.保存并退出 Vim 编辑器
如果要在保存文件后退出 vim 编辑器,可以使用以下组合键:
-
转义字符
-
:(冒号)
-
w
-
q
-
进入
先按Esc
,再按:
(冒号)、w``q
,最后按Enter
。它将保存您的文件并退出 vim 编辑器。请参见下面的截图以获取帮助。
5.退出而不保存 Vim 编辑器
如果我们想退出 vim 而不保存文件,您可以使用以下组合键:
-
转义字符
-
:(冒号)
-
q
-
!
-
进入
首先按Esc
,然后按:
(冒号)、q
和!
,最后按回车键。它将退出 vim 编辑器而不保存您的文件。请参见下面的截图以获取帮助。
除了保存和退出 vim 编辑器,您还可以使用这个强大的编辑器做更多的事情。你可以阅读我们已有的文章,
结论
在本文中,我们重点学习如何保存和归档,以及保存后的 vim 编辑器。我们从零开始学习,打开 vim 编辑器,编写文本,保存文本,保存或不保存后退出。
如何使用scp
命令安全复制文件
原文:https://www.studytonight.com/linux-guide/how-to-use-scp-command-to-securely-copy-files
Linux scp
是一个用来安全复制文件的命令。当我们在服务器之间传输数据时,会用到它。它类似于在本地机器上复制文件的cp
命令。
在本文中,我们将学习在以下场景中使用scp
命令传输文件:
-
本地到远程服务器
-
远程服务器到本地
-
远程到远程服务器
-
AWS 本地的 SCP
让我们从对命令的基本理解开始。该命令的语法为:
scp [OPTION] [user@]SRC_HOST:]file_name1 [user@]DEST_HOST:]file_name2
选项:可能包括密文、端口号、限制等。
【用户@】SRC _ HOST:】:源地址(IP 地址)
文件名 1: 源文件名
【用户@】DEST _ 主机:】:目的地址(IP 地址)
文件名 2: 目标位置(文件或目录)
当使用scp
命令进行数据传输时,它会提示输入密码,并以加密的形式传输数据,这样就不会有人破坏或访问原始数据。
要复制,文件必须具有读取权限,目标必须具有写入权限。
该命令使用几个选项来处理所有类型的复制操作。其中一些是:
| 选项 | 描述 |
| -3 | 它通过本地主机在两个远程主机之间复制数据,如果没有此选项,数据将直接在两个远程主机之间复制。 |
| -4 | 它仅用于复制 IPv4 地址上的数据。 |
| -6 | 它仅用于复制 IPv6 地址上的数据。 |
| -丙 | 它用于启用压缩。 |
| -c | 它用于选择加密数据传输的密码。 |
| [构成来自拉丁语、结尾为-us 的名词的复数] | 它用于选择从中读取公钥身份验证的身份(私钥)的文件。 |
| -j | 它用于指定目的地 |
| -我 | 它用于限制带宽。 |
| -P | 它用于指定运行服务器的端口号。 |
| -p | 它用于保留原始文件的访问和修改时间。 |
| q | 它用于从 ssh 禁用进度指示器和警告。 |
| -r | 它用于将整个目录递归复制到远程服务器。 |
让我们从将文件复制到远程服务器开始。
将文件从本地主机复制到远程服务器
使用以下命令将文件从本地主机复制到远程服务器。
scp myfile.doc remote_username@101.155.10.20:/remote/directory
其中 myfile.doc 是文件名, remote_username 是远程用户的名称。101.155.10.20代表远程地址。
如果服务器在默认端口上运行,它可以正常工作,但是如果端口号不同,则使用以下命令:
scp -P 2022 myfile.doc remote_username@101.155.10.20:/remote/directory
同样,我们可以通过使用命令中的-r 选项将目录复制到远程服务器。请参见下面的命令。
scp -r mydirectory remote_username@101.155.10.20:/remote/directory
将文件从远程服务器复制到本地主机
以下命令用于将文件从远程服务器复制到本地主机。
scp remote_username@101.155.10.20:/remote/directory/myfile local/directory
除了首先使用远程地址,然后使用本地目录路径之外,它类似于上面的命令,我们将本地复制到远程服务器。
将文件从远程服务器复制到另一台远程服务器
以下命令用于使用本地系统将文件从一台远程服务器复制到另一台远程服务器。
scp remote1_username@101.155.10.20:/remote/directory/myfile.txt remote2_username@15.150.15.10:/remote/directory
它将询问两个远程系统的密码。因此,请为成功的数据传输提供密码。
使用本地主机将文件从远程服务器复制到另一台远程服务器
以下命令用于通过使用本地系统将文件从一台远程服务器复制到另一台远程服务器。
scp -3 remote1_username@101.155.10.20:/remote/directory/myfile.txt remote2_username@15.150.15.10:/remote/directory
注意,通过本地主机传输时使用 -3 选项。
将文件从本地主机复制到 AWS 服务器
如果您在 AWS 服务器上工作,想要将文件从本地复制到 AWS,请使用以下命令。
scp -i key-name.pem myfile.doc bitnami@40.13.23.10:/remote/directory
在上面的命令中,我们使用了。pem 文件,包含服务器的私钥。我们可以用它通过 ssh 命令访问 AWS 服务器,同样也可以用来在本地和 AWS 服务器之间传输文件。
结论
在本文中,我们已经了解了scp
命令及其在不同场景中的用法,例如在本地到远程服务器之间传输数据,远程服务器到本地机器,以及本地到 AWS 服务器之间的传输。
通过服务器非常安全地传输数据是一种简单且更好的方法。
在 Linux 上创建符号链接
原文:https://www.studytonight.com/linux-guide/creating-symlinks-on-linux
符号链接,也称为软链接或符号链接,是 Linux 系统上的一个特殊文件,它指向系统上的另一个文件或文件夹。在 Linux 系统上,这些大约相当于一个 Windows 快捷方式。
符号链接和快捷方式的区别
符号链接不像快捷方式那样充当指向不同文件或文件夹的指针。符号链接的作用就像对象实际存在一样。
例如,我们想将一个文件夹同步到 dropbox,但不想将其移动到 dropbox。创建快捷方式将使 dropbox 引用该文件位置,因此如果我们在另一个系统上访问它,它将失败。但是有了符号链接,Dropbox 认为文件就在那里,并同步文件夹内容,让我们甚至可以访问其他系统。
符号链接的应用
- 内存高效快捷方式。从不同的文件夹中执行相同的应用,但是只消耗几个字节来创建符号链接。
- 将数据或应用移动到另一个驱动器,而不中断工作。
创建符号链接
要从命令行创建符号链接,基本命令格式如下。
ln -s <path to file/folder> <path of link>
**ln**
,是链接命令。-s
用于指定我们的链接是象征性的和/或软的。默认情况下**ln**
只创建硬链接,所以我们需要记住指定-s
标志。依次是源文件/文件夹,然后是快捷方式的目标。
符号链接文件
以符号链接一个文件为例,将你的 ~
目录中的.bashrc
文件,链接到**Documents/**
目录中的一个.termrc
文件,我们运行如下。
ln -s .bashrc Documents/.termrc
要检查文件是否是符号链接,请运行命令
ls -l Documents/.termrc
如果第一列是l
,说明是链接。
符号链接文件夹
例如,要对文件夹进行符号链接以访问~/Documents/projects/
中的~/.local/bin/
(用户本地可执行文件),我们将运行以下命令。
ln -s ~/.local/bin/ ~/Documents/projects/lbin
删除符号链接
符号链接可以通过两种方式取消链接。一种是使用**unlink**
命令。
取消符号链接
**unlink**
有以下语法。
unlink <path to link>
如果过程成功,这将删除链接。需要记住的一点是,即使符号链接是针对某个文件夹的,我们也不会添加尾随的“/
”,因为 Linux 假设它是一个目录,并且 unlink 不能删除目录。
删除符号链接
因为符号链接只不过是 Linux 文件系统上的一个特殊文件,所以它可以像 Linux 文件一样被删除。通过使用**rm**
。就像**unlink**
一样,如果符号链接是指向某个文件夹的,则不会添加尾随的“/
”。
**rm**
(删除)符号链接的语法如下。
rm Documents/projects/lbin
使用**rm**
优于**unlink**
的好处是可以使用**rm**
同时删除多个链接。
查找和删除断开的链接
有时有太多的链接需要跟踪,我们已经多次修改了我们的文件,由于丢失文件或重命名文件夹等原因,我们最终会出现悬空/断开的链接。为了解决这个问题,我们可以在 Linux 上使用方便的 **find**
程序找到所有断开的链接。**find**
是一个 Linux 实用程序,可以搜索符号链接,也可以删除符号链接。
要搜索断开的符号链接,请使用命令
find . -maxdepth 1 -xtype l -print # Max Depth to be used to find links, only in current folder, without recursive search
find . -maxdepth 1 -xtype l -delete # Delete after confirmation of files using -print
因此,例如,下面的命令被用来创建一个符号链接,然后移动原始文件,我们得到。
ln -s abc.cpp acbd
ll acbd # Check on link
mv abc.cpp a.cpp
ll acbd
我们可以看到,文件acbd
,现在是一个断开的链接。要搜索和删除它,我们使用**find**
命令和-delete
标志。
结论
本教程讲述了如何使用带有-s
标志的 ln
命令创建软/符号链接,以及如何使用**unlink**
和**rm**
处理这些链接。它还涵盖了如何找到任何因事故而中断的链接,并删除它们。
如何在 Linux 中列出目录内容
原文:https://www.studytonight.com/linux-guide/how-to-list-directory-contents-in-linux
在 Linux 中,dir
(目录)、ls
(列表)命令已经可以用来检查目录内容的列表,但是除此之外,Linux 还提供了vdir
(虚拟目录)来列出目录内容。
vdir
命令用于列出 Linux/Unix 操作系统中文件的相关信息。
vdir
代表虚拟目录。vdir
命令类似于ls -l -b
命令。- 默认情况下,文件以长格式列出,特殊字符由反斜杠转义序列表示。
- 如果没有指定-cftuvSUX 或- sort,它将按字母顺序对条目进行排序。
Linux vdir 命令的语法
以下是 Linux 中 vdir 命令的语法。
vdir [OPTION]... [FILE]...
Linux vdir 命令选项
下表简要描述了vdir
命令的可用选项。
[计]选项 | 描述 |
---|---|
-所有人 | 它用于显示带有点(.)的文件。)在名字的开头。基本上是一个隐藏文件。 |
-一个,-几乎所有 | 不要列出隐含的。和.. |
-作者 | 它用于显示每个文件的作者。 |
-B,-忽略-备份 | 它用于忽略备份文件的列表。 |
分类 | 它用于将指示符(一个*/=>@|)添加到条目中。 |
-文件类型 | 同样,除了不要附加' * ' |
-我,伊诺德 | 它用于打印每个文件的索引号。 |
-r-倒车 | 它用于在排序时以相反的顺序列出文件。 |
-R,-递归 | 它用于递归列出子目录。 |
救命 | 它用于显示帮助。 |
-版本 | 它用于打印版本信息。 |
示例:在 Linux 中显示隐藏文件
在目录 hope 中,有一个文件 .dubey.txt 有 dot(。)的名义。该文件是一个隐藏文件,如果不使用 -a 或 -所有 vdir 命令中的选项,该文件将无法显示,但当我们使用这些选项时,该文件将会显示。
示例:用-l 显示文件的作者
在本例中,通过使用**vdir -l --author**
命令,我们显示了包含所有者详细信息、组详细信息等的文件。请参见下面的输出。
示例:显示不包括备份文件的文件(以~)结尾
我们知道备份文件以一个 ~ 符号结束,像 bfile.txt~ 是当前文件夹中的一个备份文件,默认可见。如果我们想排除这些文件,那么在 vdir 命令中使用 -B 或 -忽略-备份选项。请参见下面的输出。
示例:显示帮助并退出
在上面的选项表中,只有几个重要的选项给出了描述,但是通过使用vdir --help
命令,您可以使用描述来探索更多的选项。
示例:显示 vdir 命令的版本信息
要显示 vdir 命令的版本信息,请使用vdir
命令和--version
选项。
结论
在本教程中,我们介绍了如何在 Linux 操作系统中使用vdir
命令列出目录内容,并提供了可用的选项和合适的示例。在 Linux 中,ls 和 dir 也可以用于相同的目的。
在 Debian 10 上安装 VSCode
原文:https://www.studytonight.com/linux-guide/install-visual-studio-code-on-debian-10
今天,我们介绍如何在 Debian 10 巴斯特上安装 VSCode 或更新现有 VS 代码;Visual Studio Code 是由微软创建的开源跨平台代码编辑器。Visual Studio 提供内置调试帮助、Git 集成控件、语法突出显示、代码完成、集成终端、代码重构和代码片段。
在 Debian 10 上安装 Visual Studio Code 的最快且推荐的方法是激活 VS Code 仓库,并使用命令行安装 VS Code 包。
本指南描述了在 Debian 10 Buster 上安装 VSCode 编辑器。更新 Debian 10 上的 VS 代码
前提
要在 Debian 10 上安装 Visual Studio Code,您必须以具有 Sudo 访问权限的用户身份登录。
在 Debian 10 上安装 VSCode
在 Debian 10 系统上安装 VSCode 的最快和推荐的方法是激活 VS 代码仓库,并使用命令行安装 VS 代码包:
首先更新包索引并通过键入以下命令安装依赖项:
sudo apt update
sudo apt install software-properties-common apt-transport-HTTP curl
使用以下命令 curl 导入微软 GPG 键:
curl -SSL https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
该命令将产生一个输出 OK。
将 VSCode 仓库添加到您的系统中:
sudo add-apt-repository "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"
安装 VSCode包,使用:
sudo apt update sudo apt install code
Visual Studio Code 安装在 Debian 桌面上,可以开始使用了。
启动 VSCode
通过输入代码或点击 VS 代码图标(“应用- >编程- > VSCode”),可以从命令行打开 VS 代码。
你现在可以开始添加扩展并根据你的喜好定制 VS 代码。
如何更新 VSCode
发布新版本的 Visual Studio Code 时,您可以通过桌面使用软件更新工具或在终端中键入以下命令来更新软件包:
sudo apt update && sudo apt upgrade
结论
我们已经教过你如何在 Debian 10 系统上安装 VSCode或者更新 VS 代码。您的下一步是安装附加组件并个性化您的用户和设置工作区。
如何在 Ubuntu 18.04 上安装 Kodi
原文:https://www.studytonight.com/linux-guide/how-to-install-kodi-on-ubuntu
Kodi(以前叫 XBMC)是你的家庭影院。这是一个免费的开源 (GPL)软件媒体播放器和娱乐中心,大多数操作系统都可以访问,包括 Linux、OSx、视窗、iOS 和安卓。
你可以通过遥控器在电视上使用它,因为它提供了一个 10 英尺的用户界面。
Kodi 功能
- 不仅是媒体播放器,更是终极娱乐中心软件。
- 每个操作系统都可以访问的跨平台
- 从本地和网络存储媒体以及互联网播放几乎所有类型的电影、音乐、播客和其他数字媒体文件
- 良好的界面
如何在 Ubuntu 18.04 上安装 Kodi
在 Ubuntu 上安装应用有多种方法。您可以使用 apt-get 命令和 Ubuntu 软件管理器安装 Kodi。
让我们详细探索每一种方法,尽管您应该利用任何方法。
注意:这些方法应该适用于 Ubuntu 17.04、Ubuntu 16.04 或者其他基于 Debian 的 Linux 发行版。
用 apt-get 安装
您需要管理员或 Sudo 权限才能安装。登录 Ubuntu,按 CTRL + ALT + T 并执行以下指令打开终端。
首先,使用 apt-get update 命令更新源列表。
$ Sudo apt-get update
运行以下命令安装 Kodi 。
$ Sudo apt-get install Kodi
购电协议代码
Kodi 团队提供 PPA 进行安装。这些仓库是,
最终版本构建——这是稳定的版本。
(PPA:team-xbmc/PPA)–https://launch pad . net/~ team-xbmc/+archive/PPA
测试版和发布候选版–
ppa:团队-xbmc/不稳定-https://launchpad.net/~team-xbmc/+archive/unstable
夜间构建–
ppa:团队-xbmc/xbmc-每晚-https://launchpad.net/~team-xbmc/+archive/xbmc-nightly
注意:这个 PPA 只提供 Ubuntu i386 和 Ubuntu amd64 版本,不提供可以运行在树莓 Pi 上的 Ubuntu armhf 版本。
我们要安装一个稳定的版本。所以使用以下说明。
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:team-xbmc/ppa
sudo apt-get update
sudo apt-get install Kodi
税务更新
只需执行一个通用的系统/包,或者在终端中使用以下命令来升级 Kodi 的最新版本。
sudo apt-get update
sudo apt-get upgrade
正在卸载 Kodi
如果您需要删除和清除程序,并最终删除/清除应用设置文件,请使用以下命令:
sudo apt-get update
sudo apt-get uninstall Kodi*
sudo apt-get purge kodi*
然后删除设置文件夹以清除所有设置和库数据。这不会抹掉任何电影或音乐,而只是设置和库数据本身:
rm -r ~/.kodi/
使用 Ubuntu 软件安装
如果不熟悉命令,可以利用 Ubuntu 软件进行安装。
点击应用,打开 Ubuntu 软件。搜索 Kodi,然后单击安装按钮。
应该会在一段时间后安装。你可以注意到 Ubuntu 软件中的运行和删除按钮,你可以用它来启动或删除 Kodi 。
如何在 Linux 中复制文件或目录
原文:https://www.studytonight.com/linux-guide/how-to-copy-a-file-or-directory-in-linux-cp-command
在 Linux 中,如果我们想要复制一个文件或目录,我们使用cp
命令。
cp
(复制)命令用于复制 Linux/Unix 操作系统中的文件或文件组或目录。在 Linux 中,install
命令也可用于在 Linux 操作系统中复制文件和设置任何文件或目录的属性。
cp
命令在以下模式下工作:
-
如果您为文件的路径名提供了两个参数,该命令会将第一个文件的内容复制到第二个文件,创建第二个文件,如果该文件不存在,则
cp
命令会创建它。 -
如果您想要复制多个文件或目录,那么源路径将包含所有要复制的文件名,而目标路径必须是一个目录。
-
如果源是一个目录,而目标也是一个目录,那么 cp 命令会将第一个目录的所有内容复制到第二个目录中。
cp
命令的一般语法如下:
cp [ option] source destination
Linux cp 命令选项
cp
命令可用选项的简要说明。
|
[计]选项
|
描述
|
| --- | --- |
| -b | 它用于创建每个目标文件的备份。 |
| -f | 如果需要,可以通过删除目标文件来强制复制。 |
| [构成来自拉丁语、结尾为-us 的名词的复数] | 它用于获得用户交互。 |
| -我-s | 它用于创建硬/符号链接,而不是物理副本。 |
| -我 | 它用于跟随符号链接。 |
| 同-EN | 它用于设置无文件覆盖。 |
| -右 | 它用于递归复制(包括隐藏文件)。 |
| -你 | 它用于更新。仅当源比目标新或目标丢失时,它才会复制。 |
| -v | 详细(输出发生的每个步骤) |
示例:在 Linux 中复制文件
这里,我们使用cp
命令将一个文件复制到一个文件夹中,然后通过使用cd
命令进入来验证它。cd 命令用于改变 Linux 中的目录。查看命令。
文件在 Linux 中的复制和备份
-b(备份) -这个带有 cp 命令的选项在目标目录中创建一个或多个备份文件。我们可以使用如下命令:
cp -b hello.txt myfolder
它将复制文件 hello.txt 作为目标文件夹以及一个备份文件,该文件包含一个带有文件名的平铺符号。
hello.txt ~ 是前一个 hello 的备份文件。txt 文件。
在 linux 中强制复制文件
-f (force) - 此选项用于强制复制文件或目录。如果任何文件或目录受到写权限的保护,那么通过使用 cp 命令的 -f 选项,我们可以成功地从源复制到目标。
在 Linux 中复制多个文件
Linux 允许将多个文件或目录复制到任何目的地。
在此命令中,当前目录中以. txt 扩展名结尾的所有文件都被复制到另一个目录中。
结论
在本教程中,我们介绍了如何使用 cp 命令复制文件、文件组或目录,以及 cp 命令中可用的各种选项和合适的示例。
如何使用df
命令检查 Linux 中的磁盘空间
原文:https://www.studytonight.com/linux-guide/how-to-check-disk-space-in-linux-using-df-command
可以在 Linux 和 Unix 操作系统上使用df
命令获取系统磁盘空间消耗的完整报告。
使用测向命令
df
命令的一般语法如下:
df [OPTIONS]... FILESYSTEM...
在没有任何参数的情况下使用时,df 程序将提供所有已装载文件系统的信息:
$df
输出
Filesystem 1K-blocks Used Available Use% Mounted on
dev 8172848 0 8172848 0% /dev
run 8218640 1696 8216944 1% /run
/dev/nvme0n1p3 222284728 183057872 27865672 87% /
tmpfs 8218640 150256 8068384 2% /dev/shm
tmpfs 8218640 0 8218640 0% /sys/fs/cgroup
tmpfs 8218640 24 8218616 1% /tmp
/dev/nvme0n1p1 523248 107912 415336 21% /boot
/dev/sda1 480588496 172832632 283320260 38% /data
tmpfs 1643728 40 1643688 1% /run/user/1000
每行都有以下几列:
“文件系统”–文件系统的名称。
“1K 块”-1K 块中文件系统的大小。
【已利用】-1K 区块的已用空间。
【可用】-1K 区块的可用空间。
“使用百分比”–已利用空间的比例。
“挂载于”是挂载文件系统的目录。
要专门显示特定文件系统的信息,请向df
命令提供其名称或装载点。
例如,要查看装载到系统根目录(/)的文件系统上的可用空间,可以使用 df /dev/nvme0n1p3 或 df /来查看。
$df /
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/nvme0n1p3 222284728 183057872 27865672 87% /
以人类可读格式显示磁盘空间使用情况
默认情况下,df 程序以 1 千字节块显示磁盘空间,以千字节显示已用和可用的磁盘空间。
要以人类可读的格式(千字节、兆字节、千兆字节等)显示有关磁盘设备的信息,请使用带有-h 选项的 df
命令:
$df -h
Filesystem Size Used Avail Use% Mounted on
dev 7.8G 0 7.8G 0% /dev
run 7.9G 1.8M 7.9G 1% /run
/dev/nvme0n1p3 212G 176G 27G 88% /
tmpfs 7.9G 145M 7.7G 2% /dev/shm
tmpfs 7.9G 0 7.9G 0% /sys/fs/cgroup
tmpfs 7.9G 24K 7.9G 1% /tmp
/dev/nvme0n1p1 511M 106M 406M 21% /boot
/dev/sda1 459G 165G 271G 38% /data
tmpfs 1.6G 16K 1.6G 1% /run/user/1000
文件系统类型
-T 选项指示 df 列出文件系统类型:
df -t
该报告添加了一个名为“ Kind ”的额外列,指示文件系统的类型:
输出
Filesystem Type 1K-blocks Used Available Use% Mounted on
dev devtmpfs 8172848 0 8172848 0% /dev
run tmpfs 8218640 1744 8216896 1% /run
/dev/nvme0n1p3 ext4 222284728 183666100 27257444 88% /
tmpfs tmpfs 8218640 383076 7835564 5% /dev/shm
tmpfs tmpfs 8218640 0 8218640 0% /sys/fs/cgroup
tmpfs tmpfs 8218640 24 8218616 1% /tmp
/dev/nvme0n1p1 vfat 523248 107912 415336 21% /boot
/dev/sda1 ext4 480588496 172832632 283320260 38% /data
tmpfs tmpfs 1643728 40 1643688 1% /run/user/1000
如果您希望将列表限制为特定类型的文件系统,请使用-t 选项,后跟类型。
下面是一个演示如何显示所有 ext4 分区的示例:
df -t ext4
输出:
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/nvme0n1p3 222284728 183666112 27257432 88% /
/dev/sda1 480588496 172832632 283320260 38% /data
与上面类似,通过-x 选项,您可以将输出限制为非指定类型的文件系统:
df -x tmpfs
输出:
Filesystem 1K-blocks Used Available Use% Mounted on
dev 8172848 0 8172848 0% /dev
run 8218640 1696 8216944 1% /run
/dev/nvme0n1p3 222284728 183057872 27865672 87% /
/dev/nvme0n1p1 523248 107912 415336 21% /boot
/dev/sda1 480588496 172832632 283320260 38% /data
显示信息节点使用情况
inode 是 Unix 和 Linux 文件系统中的一种数据结构,它保存文件或目录中的信息,如其大小、所有者、设备节点、套接字、管道等。,除了爸爸。
当与 -i 选项一起使用时,df
命令提供关于文件系统信息节点使用情况的信息。
以下命令将以人类可读的格式显示装载到系统根目录 /的文件系统上的信息节点信息:
df -ih /
输出:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/nvme0n1p3 14M 1.9M 12M 14% /
当使用 -I 选项时,输出的每一行包含以下列:
“文件系统”–文件系统的名称。
“索引节点” -文件系统上的索引节点总数。
“我使用了” -已使用的索引节点数。
“IFree”-可用(未使用)索引节点的数量。
“利用率百分比”–已利用信息节点的比例。
“挂载于”是挂载文件系统的目录。
输出格式
df
命令还使您能够更改输出格式。
要定义希望在命令输出中显示的字段,请使用—输出[=字段列表] 选项。
字段列表是输出中以逗号分隔的列列表。每个字段只能使用一次。有效的字段名是:
源 -文件系统源。
fstype -文件系统类型。
itotal -索引节点总数。
使用的 -使用的索引节点数。
无效 -可用信息节点的数量。
ipcent -已用信息节点的百分比。
大小 -总磁盘空间。
已用 -已用磁盘空间。
可用 -可用磁盘空间。
百分比 -已用空间的百分比。
文件:文件名在命令行给出。
目标 -挂载点。
例如,以人类可读的格式显示每个 ext4 分区的输出,只显示文件系统名称和大小以及您将使用的已用空间百分比:
**```sh
df -h -t ext4 —output=source,size,pcent
输出:
```sh
Filesystem Size Use%
/dev/nvme0n1p3 212G 88%
/dev/sda1 459G 38%
结论
我们已经教了你如何使用 df
命令来接收文件系统磁盘空间使用的报告。通过在终端上输入 man df 来读取所有可能的df
命令选项。
要了解文件和目录的磁盘空间利用率,请使用 du 程序。
如何在 Linux 中移动文件或目录
原文:https://www.studytonight.com/linux-guide/how-to-move-a-file-or-directory-in-linux
在 Linux 中,如果我们想移动一个文件或目录,可以使用mv
命令。例如,
$ mv myfile.txt /destination/folder
mv
(移动)命令用于移动一个或多个文件或目录。
mv
命令也用于重命名文件或目录,mv
命令的主要优点是在重命名过程中不会消耗磁盘上的额外空间。
mv
命令的一般语法
mv [OPTION]... SOURCE... DIRECTORY
Linuxmv
命令选项
下表简要描述了 mv 命令的可用选项。
选择 | 描述 |
---|---|
-备份[=控制] | 它用于备份每个现有的目标文件。 |
-b | 它类似于- backup,但不接受参数。 |
力 | 覆盖前不会提示。它移动有力。 |
-不-不,笨蛋 | 不要覆盖现有文件 |
-带尾斜线 | 它用于从每个 SOURCE 参数中移除任何尾随斜线。 |
-S,后缀=后缀 | 它覆盖了通常的备份后缀。 |
目标目录 | 它将所有 SOURCE 参数移动到 DIRECTORY 中。 |
-T,- no-target-directory=DIRECTORY | 它将 DEST 视为正常文件。 |
u 更新 | 只有当源文件比目标文件新时,它才会移动。 |
-v,-冗长 | 它用来解释正在做的事情。 |
-Z,-上下文 | 它用于将目标文件的 SELinux 安全上下文设置为默认类型。 |
救命 | 它显示帮助。 |
将文件从一个目录移动到另一个目录
在本例中, snow.sh 文件在阴影目录中可用,并通过使用 mv 命令 snow.sh 文件移动到目标目录。
使用mv
命令重命名文件
这里使用mv
命令后的文件 hello.cnf 被重命名为 dubey.cnf 文件,该文件已经不存在了。如果目标文件已经存在,那么它将被覆盖,并且源文件将被自动删除,不会有任何提示。
备份现有文件
在本例中,使用mv
命令的 -b (备份)选项,更容易对mv
命令将覆盖的现有文件进行备份。我们可以看到,执行这个命令后 stn.sh文件是用波浪号字符()创建的。
结论
在本教程中,我们介绍了如何在 Linux/Unix 中使用mv
命令移动一个或多个文件或目录,mv
命令中提供了相应的选项。
如何使用grep
命令排除
原文:https://www.studytonight.com/linux-guide/how-to-exclude-using-grep-command
grep 命令行工具对于在文本数据中搜索匹配特定字符串、字符、短语或正则表达式的行和片段非常有帮助。虽然 grep 的大多数用户都支持对数据进行语法匹配排序,但是如果您希望使用 grep 来排除某个单词或字符串呢?用 grep 排除行匹配就像在 grep 中发现并打印匹配一样有帮助,所以我们来探讨一下如何用 grep 排除字符串匹配和排除单词。
显然,你会想要一些命令行知识和 grep 的接触来发现这是有帮助的。如果你想跟着做,你可以启动终端程序,自己试一试。由于 grep 是一个操作系统中立的应用,你可以在苹果操作系统、Linux、Unix 或其他任何使用 grep 的系统上使用排除方法。
如何用grep
命令排除一个单词
排除具有字符串或句法匹配的行的最基本方法是使用 grep 和-v 参数。
例如,假设我们使用 cat 在命令行显示一个文件,但是我们想要省略任何包含短语“ ThisWord ”的行,那么语法如下:
cat example.txt | grep -v "ThisWord"
结果将是示例. txt 文本文件,但省略了包含与“ ThisWord 匹配的字符串的每一行。
您也可以直接在文件上使用 grep,并根据术语或语法排除行匹配,如下所示:
grep -v "ThisWord" example.txt
使用最适合你的独特的套路的东西。
如何用grep
命令排除多个字符串或单词
现在你知道了如何排除单个单词的匹配,下一个自然问题是关于使用 grep 省略几个单词。这也很简单,还有其他一些方法可以利用-v 选项和 -e 标志来实现。
首先,我们举前面的例子,在一个管道连接到 grep 的文件上使用 cat,并消除匹配两个术语的任何行;“单词 1”和“单词 2”,如下所示:
cat example.txt | grep -v -e "Word1" -e "Word2"
任何包含“字 1”或“字 2”的行都将从打印结果中省略。
**您也可以直接在与之前相同的文件上使用 grep :
grep -v -e "Word1" -e "Word2" example.txt
另一个选项是通过使用管道分隔每个匹配项,使用 grep 分割要排除的内容,如下所示:
grep -Ev "word1|word2" example.txt
如果您在一个示例文本文件中尝试这些选项中的任何一个,您将看到结果是相同的,无论您选择什么技术,每个都省略了具有指定短语、语法、单词或文本匹配的行。
如何删除 Linux 中的文件或目录?
原文:https://www.studytonight.com/linux-guide/how-to-remove-files-or-directories-linux
在 Linux 中,如果我们想删除文件和目录,可以使用rm
命令。
以下命令用于递归删除目录,这意味着它也将删除其子目录,这意味着完全删除:
rm -rf /path/of/directory/
-r
标志为递归删除,-f
为强制删除。所以使用这个命令来完全删除一个目录以及其中的任何内容。
要删除单个文件,运行以下命令:
rm myfile.txt
rm
(删除)命令可用于删除文件和目录。您可以使用完整路径或相对文件路径来指定要删除的文件的位置。
rm
命令默认不删除目录,要删除目录,我们应该使用 -d 标志或 -r 标志,我们在上面的例子中使用了这两个标志。
rm
命令是无声杀手,就是它无声工作,成功完成后不会在屏幕上打印任何输出消息。rm
命令仅在出现错误时生成消息,因此使用该命令时应小心。
rm
命令的语法:
下面是如何使用这个命令,
rm [OPTION]... FILE...
Linux rm
命令选项:
下表简要描述了可通过rm
命令使用的选项。
选择 | 描述 |
---|---|
-f 、--force |
添加此标志将删除目录或文件,无论如何。这意味着强制拆除。 |
-i |
它用于显示信息,并在每次移除前与用户确认。 |
-I |
用于删除三个以上文件前提示一次(与-i 标志相同)。 |
--interactive[=WHEN] |
它用于根据我们提供的条件进行提示。 |
--one-file-system |
它在递归移除层次结构时使用。 |
--no-preserve-root |
它用于指定不应区别对待根,也可以将其删除。 |
--preserve-root |
此标志也是默认选项,不允许删除根目录。 |
-d 、--dir |
它用于删除空目录。 |
-r 、-R 、--recursive |
它用于递归删除目录及其内容。 |
-v 、--verbose |
它用来解释正在做的事情。每个文件名都打印在控制台上,该命令会将其删除。 |
--help |
用于显示与rm 命令相关的帮助。 |
--version |
它用于从rm 命令获取版本信息。 |
示例:使用rm
命令从存储器中删除文件。
在这个例子中,通过使用rm
命令,我们将删除一个在阴影目录中可用的文件。
示例:删除空目录
在这个例子中,我的文件夹是一个空目录。仅仅使用rm
命令是不可能删除目录的。所以要删除一个目录,你必须使用-dir
选项和命令。
示例:使用带有-i
(交互式删除)选项的rm
命令删除文件
在本例中,我们将-i
选项与rm
命令一起使用,该命令要求用户在删除每个文件之前进行确认。
示例:删除以-(连字符)符号开头的文件
如果任何文件在其名称中使用-(连字符),那么我们不能使用rm
命令直接删除它。我们必须在文件名前单独使用--
( 双连字符),就像选项一样,删除文件。
这是rm
命令不会将文件名误解为选项的方式。
结论
在本教程中,我们介绍了如何使用 rm 命令删除文件和目录,以及可用的选项和合适的示例。rm 命令类似于 MS-DOS 和 Windows 操作系统中的 del 命令。
如何使用rsync
排除文件和目录
原文:https://www.studytonight.com/linux-guide/how-to-exclude-files-and-directory-using-rsync
Rsync(远程同步)是一个功能强大的命令行应用,用于同步本地和远程文件和目录。它预装在大多数 Linux 发行版上。它是备份和保持许多站点上的文件和文件夹同步的最强大的应用之一。sync 最令人满意的一点是,它通过仅传输已修改的数据,减少了复制到远程站点的数据量。rsync 还有另一个优秀的特性,我们今天要研究;它从同步中省略了文件或目录。当您不想复制一个或多个文件或目录时,这在备份过程中非常有用。
我们将通过几个例子向您展示如何同步排除文件或目录。这里展示的例子已经在 Ubuntu 20.04 LTS 上试用过了。然而,它们同样适用于安装了 rsync 的其他 Linux 发行版。
排除特定文件
同步目录时,您可能希望排除放置在其中的特定文件。您可以使用–exclude 选项,后跟用逗号包围的文件名。
该命令的语法为:
$ rsync -a —exclude ‘file name’ source directory/ destination directory/
这里,一个选项用于递归同步。
例如,在同步 src 目录和 dest 目录时,要从源中排除名为 sample.txt 的文件,命令应该是:
$ rsync -a —exclude ‘sample.txt’ src dir/ dest dir/
排除特定目录
要在同步源目录和目标目录时从源目录中排除特定目录(及其子目录),请使用以下语法:
$ rsync -a —exclude ‘directory name’ src dir/ dest dir/
例如,要在同步 src 目录和 dest 目录时排除名为 sampledir 的目录,命令应该是:
$ rsync -a —exclude ‘sampledir’ src dir/ dest dir/
如果您希望排除目录的内容,但不排除目录本身,请使用目录名后跟/*:
$ rsync -a —exclude 'sampledir/* ' src dir/ dest dir/
上述命令会将目录传输到目的地,但不会传输其内容。
排除多个文件或目录
要在同步操作期间排除多个文件或目录,请按如下方式定义每个文件或目录:
$ rsync -a —exclude 'file name' —exclude 'directory1 —exclude 'directory2' src dir/ dest dir/
不要为每个文件或目录单独提供–exclude选项,您可以使用单个–exclude 选项,将所有文件或目录放在花括号中。
$ rsync -a —exclude={'file name' ,'directory1’,'directory2'} src dir/ dest dir/
另一种排除多个文件或目录的方法是通过将它们列在一个文件中,然后将文件名提供给-从选项中排除:
$ rsync -a —exclude-from ‘list’ src dir/ dest dir/
这里,列表包含我们希望排除的文件和文件夹名称。该命令将 src 目录同步到 dest 目录,同时省略“list”文件中指示的文件和目录。
排除符合模式的文件或目录
使用 rsync ,您也可以排除符合指定模式的文件或文件夹。例如,当同步一个目录时,您可能希望排除任何以. txt 后缀结尾的文件。在这种情况下,命令是:
$ rsync -a —exclude ‘*.txt’ src dir/ dest dir/
按大小排除文件
使用 rsync,您可以根据文件的最小或最大大小排除文件。在这里,我们将不使用–exclude 选项,而是根据最大和最小大小分别使用–最大大小=
假设我们想要将所有文件同步到目标目录,不包括那些大小超过 100MB 的文件。在这种情况下,命令将是:
$ rsync -av —max-size=100m src dir/ dest dir/
同样,为了排除小于指定大小的文件,假设 50 MB,命令将是:
$ rsync -av —min-size=50m src dir/ dest dir/
结论
这就是全部!本文检查了几个实例,以排除同步中的文件或目录。我们已经展示了如何排除单个文件或目录、多个文件和目录、符合指定模式的文件,这取决于它们的最小/最大大小。
如何在 Linux 中列出用户?
原文:https://www.studytonight.com/linux-guide/how-to-list-users-in-linux
如果你是一个系统管理员,或者一般来说想看到你的 Linux 机器上的所有用户,那么在本教程中,你将学习 3 种不同的方法来做到这一点。
如果你只是希望这个命令没有任何废话,那么这里有一个命令,你可以在你的 Linux 机器上运行,列出用户,以及其他一些信息:
cat /etc/passwd
/etc/passwd 文件保存了用户的所有信息。在这个命令中,我们使用了cat
命令来读取这个文件。
如果你想通过一些额外的提示和技巧来学习这三种不同的方法,那就继续阅读。
以下是列出 Linux 用户的三种方法:
-
读取 /etc/passwd 文件
-
使用
getent
命令 -
使用
compgen
命令
让我们一个接一个地讨论它们,在讨论时分享一些关于每一个的独特见解。
1.正在读取/etc/passwd 文件
我们可以使用cat
、less
或more
命令读取 /etc/passwd 文件,列出所有用户。以下是命令:
cat /etc/passwd
less /etc/passwd
more /etc/passwd
当您运行以上任何一个命令时,您将获得系统上所有可用用户的列表,以及其他相关信息,用冒号(:
)隔开。每行都有一个用户的信息。
**注意:这是您机器上所有可用用户的列表,并不意味着登录用户。要检查当前登录的用户,请使用 who 命令。
/etc/passwd 文件存储了所有用户的列表,以及关于他们的以下信息:
-
用户名。
-
加密密码(值
x
表示密码存储在 /etc/shadow 文件中)。 -
用户标识号。
-
用户的组标识号(GID)。
-
通常仅作为用户名的注释。
-
用户主目录-对于某些用户,该目录可以为空。
-
登录 Shell(默认值为
/bin/bash
)。
如何使用/etc/passwd 只显示用户名?
我们可以使用awk
命令或cut
命令。要使用这些命令,我们首先使用 cat 命令列出 /etc/passwd 文件的内容,然后使用管道操作符,然后使用cut
或awk
命令仅显示第一列数据,这是用户名。
运行以下命令之一:
cat /etc/passwd | cut -d: -f1
或者使用以下命令:
cat /etc/passwd | awk -F: '{print $1}'
运行以上任何命令,您将看到以下输出:
2.使用getent
命令列出用户:
在 Linux 机器中,文件 /etc/nsswitch.conf 存储配置的数据库列表。您可以使用cat
命令查看该文件的内容。
正如您在上面的输出中看到的,输出中还列出了 passwd 数据库。使用getent
命令,我们可以访问它并列出所有用户。下面是命令:
getent passwd
getnet
命令的输出类似于 /etc/passwd 文件的内容。
如何使用getent
命令只显示用户名?
如果您想使用getent
命令列出用户名,我们可以使用awk
命令或cut
命令。
以下是使用cut
命令的命令:
getent passwd | cut -d: -f1
或者用awk
命令:
getent passwd | awk -F: '{print $1}'
3.使用compgen
命令列出用户
如果我们只想列出用户名,那么我们也可以使用compgen
命令。这个命令更容易用来列出你的 Linux 系统中所有可用的用户名。
下面是如何使用这个命令:
compgen -u
如何检查用户名是否存在?
在创建任何新用户之前,您可以使用compgen
命令检查用户名是否已经存在。我们可以使用grep
命令从所有可用的用户名中搜索任何特定的用户名。
如果要搜索守护程序用户名,请运行以下命令:
compgen -u | grep 'daemon'
我们也可以在其他两种方法中使用grep
命令,但是命令会变得复杂,这一种更容易。
检查 Linux 中的当前活动用户
以上 3 种方法将列出您的 Linux 系统中所有可用的用户。但是如果你想看到当前的活跃用户,可以使用who
命令。
例如,
who
今晚研究 pts/0 2021-07-13 12:14(62 . 27 . 117 . 907)
在上面的输出中,我们获得了当前活动的用户,我们使用该用户登录了系统。如果多个用户登录到同一个 Linux 机器上,输出可以有多个用户名。
结论:
至此,本指南到此结束。我们介绍了在 Linux 中列出用户的 3 种不同方法,以及各种其他快捷方式,如仅列出用户名和搜索特定用户名。
如何在 Linux 中使用mv
命令移动文件
原文:https://www.studytonight.com/linux-guide/how-to-move-files-in-linux-using-the-mv-command
有些行动是例行公事;人们理所当然的恰恰他们是多么的容易。但是,当你转移到一个新的平台,同样简单的动作开始需要你大脑一小部分的执行能力。其中一项工作就是将文件从一个区域转移到另一个区域。当然,这通常被认为是在电脑上完成的最简单的任务之一。然而,当你切换到 Linux 平台时,你可能会发现自己在想,“现在,我如何传输文件?”
如果你熟悉 Linux,你就会知道通向同样结果的道路总是数不胜数。移动文件也不例外。你可以选择命令行的强度或者图形用户界面的易用性——无论哪种方式,你都会重新定位那些文件。
让我们来看看你是如何把那些文件传送出去的。
命令行移动
许多初入 Linux 的人面临的挑战之一是不得不使用命令行的想法。一开始可能会很可怕。尽管当代的 Linux 界面可能有助于保证你很少不得不使用这个“老派”工具,但是如果你忽视它,你将会失去很多力量。重新定位文件的命令就是一个很好的例子。
重新定位文件的命令是 mv 。这是基础,也是你将在平台上学习的第一批指令之一。与其简单地为命令设置语法和常规开关,然后让您处理剩下的事情,不如让我们来看看如何使用这个工具。
mv
命令做了一件事——它将文件从一个地方复制到另一个地方。这可能有点欺骗性,因为 mv 也用于重命名文件。怎么做?很简单。这里有一个例子。假设你在/home/jack/,有文件 testfile ,你想把它重命名为 testfile2(同时保持它在同一个地方)(同时保持它在准确的位置)。为此,您可以使用mv
命令,如下所示:
mv /home/jack/testfile /home/jack/testfile2
或者,如果你已经在 /home/jack: 里面
mv testfile testfile2
上述指令将把 /home/jack/testfile 重新定位到 /home/jack/testfile2 -本质上是重命名文件。但是如果你只是想重新定位文件呢?假设您希望保持您的主目录(在本例中为/home/jack)没有丢失的文件。您可以使用以下命令将测试文件传输到/home/jack/Documents:
mv /home/jack/test file /home/jack/Documents/
您已经使用上述命令将文件移动到新的位置,同时保持旧文件名。
如果你有一堆你想移动的文件怎么办?幸运的是,您不必为每个文件执行 mv 命令。您可以使用通配符来帮助您。这里有一个例子:
您的 ~/Downloads 目录中有很多. mp3 文件(/–是表示您的主目录的一种简单方法–在我们前面的示例中,它是/home/jack/),您希望它们出现在/Music 中。您可以通过一个命令快速重新定位它们,如下所示:
mv ~/Downloads/*.mp3 ~/Music/
该命令将从下载目录传输以. mp3 结尾的每个文件,并将它们放入音乐目录。
如果您希望将文件重新定位到当前工作目录的父目录中,有一种简单的方法可以实现。假设你有文件测试文件存储在~/Downloads 中,并且你希望它在你家目录中。如果您目前在~/Downloads 目录中,您可以将其向上移动一个文件夹(到~/),如下所示:
mv testfile ../
“那个../"表示将文件夹上移一层。如果你被埋得更深,比如说 ~/Downloads/today/ ,你仍然可以通过以下方式快速重新定位该文件:
mv testfile ../../
只要记住,每一个../表示向上一级。
可以看到,从命令行传输文件一点都不难。
如何在 Ubuntu 18.04 上安装 PyCharm
原文:https://www.studytonight.com/linux-guide/how-to-install-pycharm-on-ubuntu-1804
PyCharm 是 Python 编程最优秀的 IDE。这个 Python IDE 有专业版和社区版。社区版可以免费访问,而专业版包含更多功能。访问此处了解社区版和专业版版的区别。
本文告诉你如何在 Ubuntu 18.04 LTS Linux 电脑中安装 PyCharm。
先决条件
使用 Ubuntu 机器上的 sudo 特权帐户登录。然后,从所有应用中启动一个终端或使用 CTRL+ALT+T 快捷键。
步骤 1–在 Ubuntu 18.04 上安装 PyCharm
PyCharm 有 2 个版本;第一个是社区版,免费提供给用户。建议学生为 Python 开发者学习者。专业版还带有专业开发人员所需的各种功能
根据您的要求安装以下版本之一:
安装社区版:社区版包含许多功能,可以开始使用 PyCharm IDE。
sudo snap install pycharm-community —classic
安装专业版:专业版包含各种尖端功能的软件开发者。它配有 30 天的试用许可证。
sudo snap install pycharm-professional —classic
就这样。给定的程序将在 Ubuntu 系统上安装 PyCharm 。
第 2 步–推出 PyCharm
点击左下角的显示应用图标。然后在搜索框中输入“py charm”;你会看到一个 PyCharm 启动器图标。
点击启动器图标,在你的 Ubuntu 机器上启动 PyCharm IDE 。
步骤 3–卸载 PyCharm
Make 还允许从系统中删除包。如果不再需要,可以随时用以下命令删除 PyCharm 。
sudo snap remove pycharm-community
结论
本说明帮助您在 Ubuntu 18.04 LTS 电脑上安装 PyCharm 。享受 Python 应用功能丰富的IDE的开发。
如何在 Debian 9 上安装 PostgreSQL
原文:https://www.studytonight.com/linux-guide/how-to-install-postgresql-on-debian-9
PostgreSQL 是一个开源的对象关系数据库系统。它是用于生产服务器的顶级数据库服务器之一。这篇文章将允许你在 Debian 9 伸展 pc 机上安装 PostgreSQL 数据库服务器。
步骤 1–启用 Apt 仓库
首先,需要在机器上导入 PostgreSQL 包签名密钥。使用以下命令导入密钥。
wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O - | sudo apt-key add -
现在根据您的操作系统在您的系统上添加 PostgreSQL apt 仓库。使用以下命令在官方 PostgreSQL 网站上显示这些内容。
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main" >> /etc/apt/sources.list.d/pgdg.list
步骤 2–在 Debian 9 上安装 PostgreSQL
此时此刻,您已经成功地将 PostgreSQL 官方仓库添加到您的系统中。现在更新仓库列表。之后,按照以下说明在我们的 Ubuntu 系统中安装最新的 PostgreSQL 服务器。
sudo apt-get update
sudo apt-get install PostgreSQL PostgreSQL-contrib
步骤 3–连接到 PostgreSQL
安装完 PostgreSQL 数据库服务器后,创建一个角色为“Postgres”的用户“ Postgres ”。它还创建了一个同名的系统帐户“Postgres”。因此,要连接到 Postgres 服务器,请以 Postgres 用户的身份登录您的电脑,并连接数据库。
sudo su - postgres \spsql
现在您已经登录到 PostgreSQL 数据库服务器。使用数据库命令提示符中的以下命令验证登录详细信息。
postgres-# \conninfo
要断开与 PostgreSQL 数据库的连接命令提示符,编写以下命令并按回车键。它将带您回到 Debian 命令提示符。
postgres-# \q
第 4 步–结论
您的 PostgreSQL 安装已经在您的德比安 9 机器上成功完成。
如何设置 Nginx 反向代理
原文:https://www.studytonight.com/linux-guide/how-to-setup-a-nginx-reverse-proxy
在 Linux 操作系统中,反向代理作为主机(客户端)和服务器之间的连接运行。它收集客户端请求并将其传递给其他服务器,最终将服务器的答案提供给客户端,看起来好像它们来自代理服务器本身。在本指南中,我们将教您什么是 Nginx 反向代理,以及如何在您的 VPS 上设置它!
客户端和服务器不断交换信息以有效运行。通常反向代理由网络服务器使用。反向代理或网关在客户端看来就像普通的 web 服务器一样,不需要额外的设置。客户端执行典型的查询,而反向代理选择传递信息,将最终结果提供给客户端,就像它是原点一样。
Nginx 反向代理提供了多种功能。它是互联网上最常用的开源服务器之一。
如何设置 Nginx 反向代理?
现在,我们将在一个 Apache 网络服务器前设置 Nginx。我们选择了 Apache 服务器,因为它更擅长管理动态材料。
所以,所有的惰性素材都会去 Nginx ,而动态内容则去了 Apache。这将通过根据搬运标准优化材料交付来提高性能。
接下来,我们将指定 Nginx 代理服务器的 IP 地址为 192.x.x.1 ,后端 Apache 服务器的 IP 地址为 192.x.x.2。
1 .安装 engine〔t1〕
我们将在 Ubuntu 18.04 上使用 apt 命令:
sudo apt-get update
sudo apt-get install nginx
2。禁用默认虚拟主机
安装 Nginx 后,运行以下命令停用虚拟主机:
sudo unlink /etc/nginx/sites-enabled/default
3。创建 Nginx 反向代理
停用虚拟主机后,我们需要在 etc/Nginx/sites-available 目录中创建一个反向代理文件. conf 来保存反向代理信息。
为此,我们需要首先使用 cd 命令输入目录:
cd etc/nginx/sites-available/
然后我们可以使用 vi 编辑器创建文件:
vi reverse-proxy.conf
在文件中我们需要放入这些字符串:
server {
listen 80;
location / {
proxy_pass http://192.x.x.2;
}
}
在前面的命令中,值得注意的一点是代理传递使通过 Nginx 反向代理到达的请求能够传递到 192.x.x.2:80 ,这是 Apache 远程套接字。因此,两个网络服务器- Nginx 和 Apache 共享材料。
完成后,保存文件并关闭 vi 编辑器。您可以通过键入 wq 来实现这一点。
要将信息传输到其他服务器,您可以使用控制台中的 ngx http 代理模块。
现在,通过使用以下命令连接到/站点启用/ 来激活指令:
sudo ln -s /etc/nginx/sites-available/reverse-proxy.conf /etc/nginx/sites-enabled/reverse-proxy.conf
4。测试 Nginx 和 Nginx 反向代理
最后,我们需要运行 Nginx 配置测试并重启 Nginx 以评估其性能。键入以下命令以验证在 Linux 终端上运行的 Nginx:
service nginx configtest
service nginx restart
请记住,如果您获得的未通过测试,这可能意味着 Apache 设置不正确。
结论
在 Linux 操作系统上设置一个 Nginx 反向代理有几个好处。它可以有效地提高速度和加强对病毒的保护。在 Linux 终端中,Nginx 反向代理设置是一个简单的操作。尽管安装和配置它有各种不同的方法,这完全取决于您的需求,但以下说明很容易帮助您开始反向代理设置。
如何在 Ubuntu 18.04 上安装和配置 GitLab
原文:https://www.studytonight.com/linux-guide/how-to-install-and-configure-gitlab-on-ubuntu-1804
GitLab 是一个基于 web 的开源 Git 资源库管理器,在 Ruby 中开发,集成了 wiki、问题管理、代码审查、监控以及持续集成和部署。它允许开发人员构建、评估和启动他们的项目。
有三个主要版本的 GitLab 可用,社区版(CE),企业版(ee),和一个 GitLab 托管的版本。
如果你想摆脱git lab 是第一选择。它可以从包括 GitHub 在内的众多来源导入项目和问题,这简化了迁移过程。GitLab UI 设计良好、清晰、直观,在用户体验和功能方面接近 GitHub。
根据必要的用例,有很多方法可以安装 GitLab。本指南涵盖了使用综合软件包在 Ubuntu 18.04 机器上安装和配置 GitLab (CE)所需的步骤。
先决条件
本指南假设您安装了全新的 Ubuntu 18.04 。根据 GitLab 需求页面,建议使用具有以下功能的服务器:
-
至少 4GB 的内存容量。
-
2 个彩色 CPU。
-
至少 2GB 的交换空间。
-
(可选)链接到服务器 IP 地址的域或子域。
为了获得额外的保护,建议设置一个简单的防火墙。您可以按照我们在 Ubuntu 18.04 教程如何使用 UFW 设置防火墙中的说明进行操作。
在继续操作之前,请确保您以具有 sudo 权限的用户身份登录。
安装必需的依赖项
使用以下命令刷新本地包索引并安装依赖项:
sudo apt update
sudo apt install curl openssh-server ca-certificates
为了让 GitLab 能够发送通知邮件,您可以安装并使用 Postfix,或者使用一些事务性邮件服务,如 SendGrid、MailChimp、 MailGun 或 SES,在这种情况下,您可以在安装完成后跳过以下步骤并配置【GitLab SMTP 设置】(https://docs.gitlab.com/omnibus/settings/smtp.html)。
运行以下说明在您的 Ubuntu 服务器上安装 Postfix:
debconf-set-selections <<< "postfix postfix/mailname string $(hostname -f)"
debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Internet Site'"
sudo apt install postfix
关于如何建立自己的邮件服务器的更多详细信息,请阅读本系列。
安装 GitLab
GitLab 安装是一个相对简单明了清晰的程序。我们将使用 apt 包管理器安装 GitLab CE 包。
首先,使用以下 curl 命令将 GitLab 仓库添加到系统源列表中:
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
仓库启用后,通过执行以下命令安装 GitLab 包。
sudo apt install gitlab-ce
安装过程可能需要一段时间,安装成功后,您会看到以下输出:
感谢您安装 GitLab!
调整防火墙规则
关于设置简单防火墙的说明在需求部分给出。为了能够访问 GitLab 接口,我们需要打开端口 80 和 443:
sudo ufw allow OpenSSH
sudo ufw allow http
sudo ufw allow https
为确保相关端口处于打开状态,您可以通过以下方式验证防火墙的状态:
sudo ufw status
输出
Status: active
To Action From
-- ------ ----
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
OpenSSH ALLOW Anywhere
80/tcp (v6) ALLOW Anywhere (v6)
443/tcp (v6) ALLOW Anywhere (v6)
OpenSSH (v6) ALLOW Anywhere (v6)
设置 GitLab 网址
在使用 GitLab 网络界面之前,我们需要配置 GitLab 可用的网址。打开 Gitlab 的配置文件,进行以下更改:
sudo nano /etc/gitlab/gitlab.rb
在配置文件的顶部附近,您会发现一行以外部网址开始。更改该值以匹配您的域/子域或 IP 地址。如果你有一个使用 HTTP 的域,如果你想通过你的服务器 IP 地址访问 GitLab 接口,使用 HTTP 。
/etc/gitlab/gitlab.rb \sexternal url 'https://gitlab.example.com
接下来寻找“让我们加密集成”,取消对以 letsencrypt['enable']开头的行的注释,并将其更改为 true。如果您希望收到来自“让我们加密您的域名”的电子邮件,请取消注释以 letsencrypt [“联系电子邮件”]开头的行,并输入您的电子邮件地址。
如果您将外部网址指定到一个 IP 地址,那么不要激活我们加密集成。
/etc/gitlab/gitlab.rb
letsencrypt
['enable'] = true \sletsencrypt['contact emails'] = ['admin@example.com'] #
这应该是一组电子邮件地址**添加为联系人
最后,保存并关闭文件,并执行以下命令重新配置 Gitlab:**
**```sh
sudo gitlab-ctl reconfigure
该程序将修改你的 **GitLab** 设置,并产生一个免费的让我们加密 **SSL** 证书。
用网络接口配置 GitLab
现在您已经指定了 **GitLab UR** L,您可以使用 GitLab web 界面从基本配置开始。
启动您的网络浏览器并转到:
```sh
https://your gitlab domain or server IP.com
如何在 CentOS 7 上安装 Anaconda
原文:https://www.studytonight.com/linux-guide/how-to-install-anaconda-on-centos-7
** Anaconda ** Python 是一个 Python 发行版,包含了几个供数据科学家使用的工具。这些也是 Python 包。在 Python 上,您可以手动安装它们。然而,默认情况下,Anaconda Python 会附带它们。这篇文章将教你如何在 CentOS 7 上安装 Anaconda Python。
Anaconda Python 是一个 Python 发行版,可以下载。
- 首先,去蟒蛇的官方网站,https://www.anaconda.com。
- 在页面右上角,点击绿色“下载”图标。应该看到下面一页。
- 现在再向下滚动一点,找到下一部分。查看是否选择了“ Linux ”。要下载蟒蛇,点击“下载”根据您的需要,您可以选择 Python 2.7 或 Python 3.6。不确定的话选择 Python 3.6。
- 浏览器会提示您保存文件。选择保存文件,然后选择确定下载过程现在应该开始了。这是一个相当大的文件。因此,下载可能需要一些时间才能完成。
验证下载文件的完整性:在这一部分,我将教你如何检查下载文件的完整性。
这是一个关键点。因为尝试从错误文件安装软件可能会导致安装失败。不检查文件的完整性也是一种安全风险。如果我们正在下载的程序的网站上提供了校验和,我们应该检查它。鉴于蟒蛇蟒蛇给了它们,我认为使用它们是谨慎的。
完成下载后,转到你下载文件的地方。在我的情况下,这是我的主页目录中的下载目录。
要将目录更改为主页/下载,请使用以下命令:
cd /Downloads cd /Downloads cd /Downloads cd
如果我显示/Downloads 目录的内容,你可以看到 Anaconda Python 的安装文件。“anaconda 3-5 . 0 . 1-Linux-x86 64 . sh”是编写时的安装文件。
要生成下载文件的 SHA256 哈希,请使用以下命令:
Anaconda3-5.0.1-Linux-x86 64.sh $ sha256sum
沿着这些线应该可以看到一些东西。
使用任何浏览器,进入https://docs.anaconda.com/anaconda/install/hashes/all。应该看到下面一页。本页提供了每一个已经出版的蟒蛇蟒蛇版本的散列。这个页面可能是可信的,因为它是 Anaconda Python 官方文档的一部分。
要验证散列,只需复制我们之前制作的散列,并在这个网站上查找。如果匹配,哈希有效;否则,它是不正确的。
要调出搜索栏,请使用 Ctrl+F 。搜索栏显示在屏幕底部。
在框中,放入我们之前创建的哈希。找到了匹配项,如屏幕截图中的绿色所示。因此,下载的文件状况良好。
蟒蛇安装
我们现在准备安装蟒蛇蟒蛇。打开终端,进入蟒蛇下载的目录。
要转到下载目录,请使用以下命令:
cd /Downloads cd /Downloads cd /Downloads cd
要启动安装,使用以下命令:
Anaconda3-5.0.1-Linux-x86 64.sh $ bash Anaconda3-5.0.1-Linux-x86 64.sh
要继续安装,请按进入 >。按回车键后,您应该会看到以下窗口。这是 Anaconda Python 的许可协议。点击进入或空格键,您可以阅读许可协议。
若要继续,请输入“是”,并在您缔结许可协议时按下“回车”>。
Anaconda Python 现在应该会提示你它将安装在哪里。/家庭/您的用户/蟒蛇 3 是默认位置。如果您愿意,您可以选择更新它。但我会坚持默认。完成后,点击进入>继续。
蟒蛇安装现在应该开始了。因为安装文件有些大,可能需要一些时间才能完成。
Anaconda Python 安装程序可能会询问安装后是否要将 Anaconda Python 添加到 CentOS 7 PATH 变量中。然后,您可以运行 anaconda python,而无需给出整个安装路径。这是大多数人想要的。要继续,输入“是”并点击“输入>”。
安装完成时,应该会看到类似这样的内容。
**## 安装检查:
打开一个新的终端,执行以下命令查看蟒蛇蟒蛇是否安装成功。
—version conda
这就完成了 CentOS 7 上蟒蛇的安装。
如何在 CentOS 7 上设置或更改时区
原文:https://www.studytonight.com/linux-guide/how-to-set-or-change-timezone-on-centos-7
当启动一个新的服务器时,你几乎总是需要建立时区。在某些情况下,您可能希望调整时区。
我们很多人忘记在服务器上设置正确的时区。如果选择不正确的时区,服务器的报告和日志将受到影响。因此,在本文中,我们将教您如何在 CentOS 7 中配置时区。
为基于 CentOS 的 VPS 设置正确的时区对于可靠地记录时间戳至关重要;否则,您可能最终会报告带有错误日期和时间戳的事件或错误日志。
除了记录和报告,为 crontabs 和计划流程指定的时间也很重要。时区设置不正确可能会导致操作执行与计划不同。幸运的是,您需要运行一些可访问的命令来更改 CentOS 7 中的时区!
总的来说,未能选择正确的时区不会损害您的操作,但会显著提高您的工作效率并消除日志中的任何歧义。
我们来看看如何在 CentOS 7 中更改时区。
在 CentOS 7 中,如何检查设置的时区?
首先,我们必须使用 SSH将连接到我们的 VPS 服务器。如果您遇到问题,请参考 PuTTY 说明!
日期命令,如下图所示,可用于确定您当前的时区:
时间将以以下格式显示:
现在时间是 2019 年 3 月 15 日星期五 14:52:20 UTC。
或者,可以使用时间日期命令。该命令可用于:
- 检查时间戳和日期。
- 更改日期和时间。
- 设置系统时区,并启用与远程服务器的自动时钟同步。
基本命令如下:
以下是输出示例:
当地时间为 2019 年 3 月 15 日星期五 14:54:51 UTC。
Fri, March 15th, 2019 at 14:54:51 UTC
n/a n/a n/a n/a n/a n/
Host (UTC, +0000) is the time zone.
n/a n/a n/a n/a n/a n/
是, NTP 同步。
当地时区 RTC:无夏令时生效:不适用
当地时间、世界时、时区均包含在此部分。
在 CentOS 7 中,如何列出时区?
一旦看到当前时区,您可能希望显示所有可能的时区设置。要查看所有可能的时区,请使用以下命令:
你会得到一份详细的列表,上面按字母顺序列出了所有的时区。使用 grep 模式,您可以进一步缩小搜索范围。例如,考虑以下情况:
如何在 CentOS 7 中更改时区?
一旦你整理了一份时区的列表,你可以选择最适合你需求的一个。在 CentOS 7 中,您可以使用以下命令更改时区:
在上面的命令中,您可以根据需要更改时区。我们也可以从这里指定一个特定的时间和日期。这可以通过以下格式完成:
例如,如果您希望时间为2019 年 3 月 16 日**,当前时间为 09:20:00 ,您可以键入:
进行这些更改后,使用 timedatectl 验证时区信息。
在 CentOS 7 中,如何设置硬件时钟?
系统时钟由 Linux 内核处理,与硬件时钟不一样。BIOS 时钟是这个的另一个名字。当系统关闭时,硬件时钟被激活。硬件时钟可以使用 Linux 命令设置。
使用以下命令查看硬件时钟是否配置为本地时区:
这将提供以下结果,表明硬件时钟没有设置时区:
附近的 TZ 没有 RTC。
然后,使用下面的命令,将您的硬件时钟调整到本地时区:
您可以使用以下命令撤消更改:
如何同步CentOS 7****网络时间协议 (NTP)是一种互联网协议,用于同步多台计算机上的系统时钟。timedatectl 命令可用于使用 NTP 自动将系统时区与远程服务器同步。
为此,我们必须首先在系统上安装 NTP 。使用以下命令开始与远程 NTP 服务器同步:
如果您希望撤消这些修改,请使用下面的命令。时间同步将因此被禁用:
结论
我们学习了如何在 CentOS 7 上配置时区,以及如何使用 NTP 设置系统时间、日期、硬件时钟时间和同步系统。选择合适的时区对于准确的日志记录、自动化程序等至关重要!
在 CentOS 7 上,更改时区很简单。是的,您可以随时查阅 timedatectl 命令的文档页面来了解更多参数。
ElasticSearch
基础知识
什么是 ElasticSearch?
原文:https://www.studytonight.com/elasticsearch/what-is-elasticsearch
如果让一群开发人员从一个传统的 RDBMS 中搜索匹配一些文本来查找一些数据,初学者会在 SQL 查询中使用 LIKE 子句,稍微热情一点的开发人员可能会编写一个 PL/SQL 过程,或者有人甚至会选择所有的数据,放入一个数据结构中,然后应用一些搜索算法,这样的技术还有很多。但是随着数据量的增长,所有这些都将慢慢地失去作用。一旦数据达到百万行的数量级,可能需要几秒钟才能成功对数据执行文本搜索。
为了快速存储和搜索(全文搜索)大量的半结构化或非结构化数据,我们可以使用 ElasticSearch 服务。
Elasticsearch 不是数据库,而是分布式搜索引擎服务,用于以 JSON 对象(文档)的形式存储数据,进行超快速的全文搜索,可扩展性很高,即使是初学者也非常容易使用。
Elasticsearch 附带一个简单但复杂的 API ,可用于执行各种操作,预配置的默认值,可在生产中使用,无需对简单用例进行任何更改,以及一个小的学习曲线。
您可以在您的 Windows 笔记本电脑、MacOS、任何 Linux 机器上安装 Elasticsearch,也可以将其部署在集群中的多个物理或虚拟服务器上。
ElasticSearch 即服务可以使用 docker 映像安装在 Docker 上,并且可以在 Kubernetes 环境中运行。
为什么我们需要 ElasticSearch?
正如本教程介绍中提到的, RDBMS 在查询海量数据以获取结果方面有所欠缺,这在数据量不断增长的今天是一个有效的用例。
例如,任何电子商务网站都很容易列出成千上万种产品,每个客户在购买任何东西之前,都要搜索它,如果搜索需要时间,在大多数情况下,用户会去其他电子商务网站。因此,拥有一个快速搜索系统,已经成为拯救企业的必要条件。
从本质上来说,关系数据库管理系统将数据分布在标准化的表中,这为数据提供了适当的结构,但是很难搜索到任何东西。因此,软件行业慢慢向 NoSQL 转移,ElasticSearch 也以 NoSQL 为基地。
Elasticsearch 提供了一种查询语言 Query DSL (领域特定语言),可以用来查询存储的数据。
理解 ElasticSearch
Elasticsearch 服务是分布式的,这意味着它部署在一个集群中,多个节点运行在不同的物理或虚拟服务器上。虽然我们也可以运行单个节点设置。让我们试着用相当简单的语言来理解这一切意味着什么。
ElasticSearch 集群是指运行在不同物理或虚拟机上的一组 ElasticSearch 节点。当我们设置 ElasticSearch 集群时,一个节点被分配为主节点,用于对集群进行配置更改,集群中的其他节点知道哪个是主节点。
我们可以通过发出 HTTP 请求,使用 REST API 与任何节点进行通信,而在内部,每个节点都通过传输层进行通信。
下面我们有一个简单的图表来解释一个简单的 ElasticSearch 服务集群。
ElasticSearch 集群的默认名称是ElasticSearch。我们可以在运行 ElasticSearch 时指定初始启动的节点数量,也可以在配置/ElasticSearch. yml 文件中指定物理或虚拟服务器的 IP 地址,您也可以在其中找到所有其他配置。
以下是 ElasticSearch 服务的主要逻辑单元:
集群 -ElasticSearch 集群由一个或多个节点组成,并可通过其集群名称进行识别。
节点 -单个 ElasticSearch 实例。在大多数环境中,每个节点都运行在单独的机箱或虚拟机上。
索引 -在 Elasticsearch 中,索引是文档的集合。你可以理解它,就像一个表是为关系数据库管理系统准备的,同样,我们在 ElasticSearch 中有索引。
碎片 -正如已经讨论过的,Elasticsearch 是一个分布式搜索引擎,因此索引通常被分成更小的单元,称为碎片,分布在多个节点上。
副本 - Elasticsearch 还保留了所有碎片的副本,作为一种故障安全机制,称为副本。
我们将在单独的教程中详细介绍所有这些内容。
弹性研究的应用
当我们使用 Kubernetes 在云上移动企业软件时,我第一次与 ElasticSearch 相遇,我们有一个用例,将每个 docker 容器中的日志聚合到一个数据存储引擎中,从该引擎中可以在一些用户界面上显示日志。显然,我们使用 ElasticSearch 来存储日志,并使用 Kibana(同一公司的另一款产品)作为可视化的用户界面。
但这是 ElasticSearch 的一个非常特殊的用例,但也是一个流行的用例。
以下是 ElasticSearch 可以使用的一些主要用例,它将获得成功。
-
应用或网站搜索有大量数据的社交网站或有大量产品目录的电子商务网站等。
-
企业搜索为其他产品提供大量数据的任何 Saas 产品。
-
日志和日志分析,正如我上面提到的。
-
Docker 中的系统度量和容器监控,以关注容器的运行状况。
-
应用性能监控
-
和各种其他形式的分析,收集实时数据,然后进行分析。
支持 ElasticSearch 的编程语言
它支持许多编程语言,但官方客户端提供以下编程语言:
-
爪哇
-
JavaScript
-
去
-
。NET (C#)
-
服务器端编程语言(Professional Hypertext Preprocessor 的缩写)
-
Perl 语言
-
计算机编程语言
-
Ruby
下载并安装
您可以从这里下载并安装 elastic search:https://www.elastic.co/downloads/elasticsearch
有多种不同的方法可以做到这一点,它们是:
1.通过下载。zip 文件并执行 shell 文件 /bin/elasticsearch ( 使用 Kibana 和 Fluent Bit 在 Linux 机器上安装 elasticsearch)来运行 elastic search 服务,或者在 windows 的情况下运行 /bin/elasticsearch.bat 文件。
2.通过使用任何软件包管理器,如苹果电脑的百胜、易捷或家酿。
3.在 Docker 中,使用 Elasticsearch docker 映像。
结论:
所以 Elasticsearch 是一个分布式存储引擎,即使存储的数据量在几十 GB 或几百 GB,它也能超快地搜索存储在其中的数据。在下一个教程中,我们将尝试理解它的体系结构,以便更好地理解它的工作原理以及它在搜索数据方面的速度。
Docker
Docker 基础
容器和 Docker 介绍
原文:https://www.studytonight.com/docker/introduction-to-containers-and-docker
为了理解什么是 Docker 以及为什么使用它,我们必须首先知道什么是容器,以及它们解决了什么问题。容器是完全隔离的环境,设置在现有操作系统之上,为运行在其中的应用提供与外部世界的虚拟隔离。docker 是一个帮助我们控制这些容器生命周期的软件。
如果你不能理解它,不要太担心。让我们举一个简单的日常生活例子来帮助你理解容器的概念。
假设一个房客住在他/她与房东家合租的房子里,或者假设是另一个房客。房客有一个单独的房间、浴室和厨房来满足他的基本需求。现在,如果我们把房子看作一个操作系统,把租户可用的区域看作一个容器,那么租户就独自生活在他的区域内,按照自己的要求管理它,不受其他人的干扰,但它共享房子的一些公共资源,如电、水等。
同样的,容器是建立在操作系统之上的一个孤立的环境(用户空间),其中利用了同一个 OS Kernel 但是有自己的进程、服务、网络、存储挂载就像虚拟机一样,但是容器不是虚拟机(我们很快就会了解到 VM 和容器的区别。).
Docker 软件帮助我们管理这些容器的生命周期,包括设置容器、监控容器、销毁容器、将容器连接到网络等。
容器化是一个古老的概念,因为有一些技术可以实现容器设置,并且已经使用了 10 多年。创建容器的其他方法有:
-
LXC
-
旗舰版
-
LXCFS 等。
Docker 最初是在 LXC 的基础上创建的,但后来转向了自己创建容器的方式。按照 LXC 的方法,容器被创建为 Linux 内核之上的隔离环境,使用cggroups(控制组)进行资源管理,如 CPU、内存、网络等,以及隔离的名称空间,为运行不同容器的应用创建单独的用户空间。
是的,容器是一个古老的概念,是的,我们只能使用 Linux 内核来创建容器,因为只有 Linux 提供了对 cgroups 和名称空间的支持。
组限制容器可以使用的空间,而命名空间限制容器可以看到的空间。
既然你已经理解了容器,让我们来谈谈 docker。
什么是 Docker 或 Docker 引擎?
Docker 或 Docker Engine 是一个软件,它帮助我们管理容器的生命周期,定义它们将如何设置,它们将在其中运行什么应用/软件/服务,它们的网络需求,它们的存储需求,以及如果需要,如何轻松销毁容器并重新开始。
Docker 使用 docker 图像来运行容器内的进程。稍后我们将详细了解 docker 映像,现在,将它们视为在 docker 容器中安装任何服务所需的文件。
注: 由于容器化是 Linux OS 的特性,因此 docker 只能安装在像 Ubuntu、Fedora、Redhat 等 Linux 操作系统上。如果你想在 Windows 操作系统上使用 docker,你必须设置一个 Linux 虚拟机,在上面你可以安装 docker。Docker Windows 应用将自动安装一个虚拟机,并在其上运行 Docker 引擎。
在客户机-服务器体系结构中,Docker 或 Docker 引擎由 3 个组件组成:
-
带有守护进程的服务器(
dockerd
) -
一种应用编程接口,由程序用来与 docker 守护进程进行交互。
-
以及一个命令行界面
docker
,使用它我们可以运行 docker 命令来对 docker 守护进程执行不同的操作。
命令行界面使用应用编程接口与Docker 守护程序进程交互。docker 守护程序负责创建和管理 docker 对象,如容器、映像、网络和卷。我们将在接下来的教程中了解所有这些 docker 对象。
为什么要用 Docker?
由于对微服务和 devops 的需求不断增加,docker 如今在软件行业非常受欢迎,因为它帮助开发人员和系统管理员在容器中构建和运行应用。以下是让 docker 如此受欢迎的一些事情:
1.它很灵活:
您可以使用 docker 在容器中运行一个简单的 hello world 程序,可以在 docker 容器中运行一个像 Apache HTTP 服务器或 Nginx 这样的 web 服务器,可以在 docker 容器中运行任何重量级的应用,甚至可以使用 docker 在容器中运行操作系统。
虽然 docker 不建议在容器内运行操作系统,但是你可以这样做。
2.不同服务的轻松设置
如果你必须在一个服务器上安装多个小服务,比如一个网络服务器、一个数据库、一些编程语言以及一些其他需要的服务,传统上我们只需要把它安装在一个服务器上,在那里它们将互相共享所有的服务器资源,并为相同的资源而战。
但是有了 docker,我们可以为每个服务创建一个单独的容器,根据他们的要求为他们分配资源,建立彼此之间的通信,这样就完成了。
即使一个服务获得太多的负载,它也绝不会影响在其他容器中运行的服务。
3.它是可移植的-不用担心一次又一次的环境设置
当我们在本地机器上开发完一些应用,并且必须在生产中部署这些应用时,我们会面临很多环境设置问题。但是如果您正在使用 docker,您可以定义容器设置的步骤,docker 将确保每次无论您在哪里运行它,环境都以相同的方式进行设置。
4.Docker 容器是松散耦合的
容器是一个自给自足的单元,具有自己的资源配额、自己的网络设置等,这使得它完全封装,从而使系统管理员更容易在不影响其他容器的情况下替换或升级一个容器。
5.高度安全
Docker 自动确保容器与外部进程完全隔离。
6.码头容器很轻
与虚拟机不同,docker 容器是轻量级的,因为它们只是利用运行它们的机器的底层操作系统内核来创建一个单独的用户空间。
结论:
在本教程中,我们了解了容器、容器化、docker 或 docker 引擎、docker 客户机-服务器体系结构的概念,以及为什么 docker 在当今软件行业如此受欢迎。在下一个教程中,我们将深入了解这些容器与虚拟机有何不同。
容器与虚拟机
原文:https://www.studytonight.com/docker/container-vs-virtual-machine
Docker 容器和虚拟机在体系结构上是完全不同的,但是经常混淆为相似。在本教程中,我们将通过了解 docker 容器和虚拟机的体系结构以及它们如何在主机操作系统上工作来了解它们之间的区别。
我们已经介绍了 docker 容器是如何工作的,使用相同的操作系统内核,资源限制使用cggroups和命名空间来决定 docker 容器的边界。让我们深入一点去理解这一切意味着什么。
码头容器
在下图中,我们有一个运行在主机上的基本 Docker 设置的体系结构,其上运行着 3 个容器,其中运行着 3 个不同的应用。
Docker 引擎利用主机操作系统内核(Linux)与底层硬件进行通信。在 docker 上运行的所有容器共享同一个主机操作系统内核,因此它们不必设置自己的操作系统内核,这使得它们轻量级。
此外,在 docker 容器中,应该只运行一个应用进程,正如 docker 所建议的那样,并且容器应该有其所需的库和依赖项。
码头上运行的每一个容器都是完全相互隔离的。
容器在 Linux 上本地运行,如果您想在 Windows 操作系统上安装它,windows docker 应用将为自己安装一个 Linux 虚拟机。
虚拟计算机
与容器不同,虚拟机不利用主机操作系统内核,相反,它安装自己的客户操作系统。虚拟机还模拟硬件层,通过虚拟机管理程序虚拟利用主机资源。
这使得虚拟机沉重且缓慢。
一个虚拟机与另一个虚拟机完全隔离。就虚拟机而言,您甚至可以在不同的虚拟机上安装不同的操作系统。
容器与虚拟机
现在您已经理解了容器和虚拟机之间的区别,让我们看看两者之间的主要区别:
容器 | 虚拟计算机 |
---|---|
尺寸较小 | 尺寸较大,一般以 GB 为单位。 |
启动速度很快。 | 启动缓慢。 |
共享由操作系统内核通过用户组管理的资源。它也共享相同的操作系统内核。 | 彼此完全隔离。 |
Docker 并不意味着用其内核来虚拟化操作系统,而是将应用打包到一个冻结的应用状态中,该状态可以在一个容器中运行。
在大规模基础架构设置中,我们将运行操作系统的虚拟机安装在服务器机架上,在其顶部运行 docker,其容器运行各个服务。
在下一个教程中,我们将学习如何在不同的操作系统上本地安装 docker。
在 Windows 上安装 Docker
原文:https://www.studytonight.com/docker/install-docker-on-windows
Docker 提供了一个桌面应用,非常容易在 Windows 操作系统上安装和运行。我们知道 docker 容器是基于 Linux 内核的,并且所有在 Docker 中运行的容器都使用相同的 OS 内核,那么 Docker 设置在 Windows 环境下是如何工作的呢?
从 Windows 10 开始,虚拟机与 docker 用于其设置的操作系统一起打包。对于 Windows 10,Docker 桌面应用可以从 Docker Hub - Docker 桌面应用 Windows 下载。
对于 Windows 10 之前的 Windows 版本,我们将不得不遵循 docker 安装的传统方法,这需要在 Windows 上安装 docker 工具箱。你可以从 Docker 工具箱的官方 Github 资源库中找到所有不同版本的 Docker 工具箱。docker 工具箱包括一个 Oracle VM Virtualbox (以及其他必需的组件),它用它来设置容器所需的 Linux 内核。
因此,让我们先一步一步地为 Windows 10 安装 Docker Desktop 应用,然后我们将介绍更多关于为旧版本的 Windows 设置 Docker 工具箱的内容。
窗口系统要求:
对于 Docker 桌面应用,您应该拥有 64 位 Windows 10 ,并且必须启用 Hyper-V 和容器窗口功能。
就内存而言,至少需要 4 GB 内存。不要担心启用 Windows Hyper-V 功能,docker 桌面应用将在安装过程中处理此问题。
注意: 在 Windows 上启用 Hyper-V 后,系统上任何配置的 VirtualBox 都将停止工作。
在 Windows 上安装 Docker
-
下载 docker 桌面的 windows 可执行文件双击开始安装。
-
按照安装向导上的说明接受许可、授权安装人员、继续安装。
-
您可能需要在安装过程中提供系统密码,因为安装程序需要特权访问才能安装各种组件和管理 Hyper-V 虚拟机。
-
设置完成后,点击完成,启动 Docker 桌面应用。
在 Windows 上运行/启动 Docker 应用
一旦您成功安装了 docker 桌面应用,您将必须启动该应用,因为它在安装后不会自动启动。
进入开始菜单,搜索 Docker ,点击 Docker 桌面。
你会看到一个移动鲸鱼图标出现在你的任务栏中,这意味着 docker 桌面应用正在启动。等待这个鲸鱼图标停止移动并变得稳定,这意味着 docker 已经开始。
一旦 docker 桌面应用启动,您可以使用窗口命令提示符运行 docker 命令。
要验证安装,请运行以下命令来检查安装的 docker 版本:
docker --version
Docker 版本 19.03.1
您应该会看到 docker 的版本号,如上面的输出所示。
卸载 Docker 桌面
就像我们卸载 Windows 中的任何其他应用一样,我们也可以卸载 docker 桌面应用。
-
从窗口开始菜单中,选择设置>应用>应用&功能。
-
从应用&功能列表中选择 Docker 桌面,然后选择卸载。
-
点击卸载确认选择。
一旦您从 Windows 机器上卸载 docker 桌面应用,它将销毁所有容器,删除所有 docker 映像以及与 docker 引擎和 docker 桌面应用相关的所有其他文件。
旧版视窗/苹果电脑的 Docker 工具箱
如本教程开头所述,如果您使用的是 Windows 7 或更早的版本,那么您将不得不遵循不同的方法在您的 Windows 机器上安装 docker。
docker 工具箱包含以下内容:
-
Docker 机器运行
docker-machine
命令 -
Docker 引擎用于运行
docker
命令 -
Docker 编写运行
docker-compose
命令 -
Kitematic ,Docker 图形用户界面
-
预配置用于 Docker 命令行环境的 Shell
-
Oracle VirtualBox
我们强烈建议在学习 docker 时,使用适用于 Windows 10 的最新桌面应用,以获得最佳体验。
在下一个教程中,我们将介绍如何在 Mac OS 上安装 Docker。如果您是 Windows 用户,您可以跳过下一个教程。
在 Mac OS 上安装 docker
Docker 提供了一个桌面应用,非常容易在 Mac 操作系统上安装和运行。就像我们在 windows 10 上安装 docker 桌面应用和老版本的 docker 工具箱一样。同样,最新的 docker 桌面应用适用于 Mac OS,而适用于旧版本的 Mac OS我们将不得不设置 docker 工具箱来运行 Docker。
Docker 电脑系统要求
你应该让你的 Mac OS 运行不早于 2010 年的硬件,因为 docker 桌面应用将需要英特尔对内存管理单元(MMU)虚拟化的硬件支持,包括扩展页表(EPT)** 和无限制模式。**
Mac OS 版本应为 10.13 或更新版本,为以下版本之一:卡特琳娜****莫哈韦或高塞拉**
以及最少 4 GB 内存。
在 Mac OS 上安装 docker
从Docker 中心-Docker 桌面下载Docker. dmg 文件。
点击下载的 docker.dmg 文件到打开并挂载。打开后,您将看到以下弹出窗口:
按照弹出窗口中的指示,将 docker.app 图标拖放到应用文件夹中,开始安装。
安装完成后,卸载 docker.dmg 文件。
Mac 上的“开始坞站桌面”
双击应用文件夹或启动面板中的 Docker 图标。
由于 docker 应用需要特权访问,您将被要求输入您的系统密码。
点击确定,并提供您的系统密码继续。
一旦 Docker 开始工作,你会看到鲸鱼图标出现在顶部导航栏中,你可以点击它查看更多 Docker 相关选项。
要验证 Docker 是否已成功启动,在终端运行以下命令:
docker --version
卸载坞站(Mac OS)
要从 Mac OS 卸载 docker desktop 应用,请单击顶部导航栏中的 Docker 鲸图标,从 Docker 菜单选项中,单击故障排除,然后单击卸载卸载 Docker Desktop 应用。
因此,在本教程中,我们学习了在 Mac OS 上安装 docker 桌面应用。从下一个教程开始,我们将开始玩 docker,并开始学习 docker 的概念。
你好世界应用
原文:https://www.studytonight.com/docker/docker-hello-world-app
在 docker 中运行 hello world 应用示例非常简单,您可以在不编写一行代码的情况下完成。我们只需要docker run
命令。在本教程中,我们将学习如何从Docker 中心下载 Docker 图像,然后运行该 Docker 图像来启动Docker 容器。
因此,在本教程中,我们将主要使用 docker pull 和 docker run 命令。别担心,我们会在接下来的教程中介绍这些命令。
你好,世界应用
Docker 提供了一个【hello-world 示例应用,它将为您设置一个裸的最小容器,在该容器中运行一个 C 程序 hello.c,该程序具有以下代码:
#include <sys/syscall.h>
#include <unistd.h>
#ifndef DOCKER_IMAGE
#define DOCKER_IMAGE "hello-world"
#endif
#ifndef DOCKER_GREETING
#define DOCKER_GREETING "Hello from Docker!"
#endif
#ifndef DOCKER_ARCH
#define DOCKER_ARCH "amd64"
#endif
const char message[] =
"\n"
DOCKER_GREETING "\n"
"This message shows that your installation appears to be working correctly.\n"
"\n"
"To generate this message, Docker took the following steps:\n"
" 1\. The Docker client contacted the Docker daemon.\n"
" 2\. The Docker daemon pulled the \"" DOCKER_IMAGE "\" image from the Docker Hub.\n"
" (" DOCKER_ARCH ")\n"
" 3\. The Docker daemon created a new container from that image which runs the\n"
" executable that produces the output you are currently reading.\n"
" 4\. The Docker daemon streamed that output to the Docker client, which sent it\n"
" to your terminal.\n"
"\n"
"To try something more ambitious, you can run an Ubuntu container with:\n"
" $ docker run -it ubuntu bash\n"
"\n"
"Share images, automate workflows, and more with a free Docker ID:\n"
" https://hub.docker.com/\n"
"\n"
"For more examples and ideas, visit:\n"
" https://docs.docker.com/get-started/\n"
"\n";
int main() {
//write(1, message, sizeof(message) - 1);
syscall(SYS_write, STDOUT_FILENO, message, sizeof(message) - 1);
//_exit(0);
//syscall(SYS_exit, 0);
return 0;
}
上面的代码只是为了让你了解 hello-world 应用运行的程序。没有必要浪费时间去理解它,因为我们在这里是为了理解 docker 容器是如何运行的。
运行 Docker Hello World 应用
打开您的终端(如果使用 Mac OS)或命令提示符,并执行以下命令:
docker run hello-world
本地找不到图片【hello-world:最新】
最新:从库/hello-world
拉取 1b930d010525:拉取完成
摘要:sha 256:F9 dfddf 63636d 84 ef 479d 645 ab 5885156 AE 030 f 611 a 56 F3 a 7 AC 7 F2 FDD 86d 7e 4e
状态:下载了 hello-world 的更新图片:最新
来自 Docker 的 hello
此消息显示您的安装似乎工作正常。
为了生成这条消息,Docker 采取了以下步骤:
1。Docker 客户端联系了 Docker 守护程序。
2。Docker 守护程序从 Docker 集线器中提取“hello-world”映像。
(amd64)
3。Docker 守护程序根据该映像创建了一个新的容器,该容器运行产生您当前正在读取的输出的
可执行文件。
4。Docker 守护程序将该输出流式传输到 Docker 客户端,该客户端将其发送到您的终端。
要尝试更有野心的东西,你可以用:
$ Docker run-it Ubuntu bash
运行一个 Ubuntu 容器,用一个免费的 Docker ID:
https://hub.docker.com/
共享图像、自动化工作流等等。要了解更多的例子和想法,请访问:
https://docs.docker.com/get-started/
由于我们有一个新的 docker 安装,并且我们没有编写任何代码,也没有下载任何项目,那么上面的命令将如何运行 hello-world 应用?它是否可用于默认的 docker 安装?
答案是否定的,我们没有 hello-world 应用的代码或 docker 术语 docker 图像。但是当我们运行docker run
命令时,docker 会查找 docker 镜像,在本例中,docker 镜像的名称是 hello-world locally,如果找不到镜像,那么 docker 会通过互联网连接 docker hub,下载镜像后运行。
我们也可以使用docker pull
命令手动下载运行 docker 容器的任何图像。因此,如果您想从 docker hub 手动下载名为 hello-world 的 docker 映像,请运行以下命令:
docker pull hello-world
使用默认标签:最新
最新:从库中拉出/hello-world
摘要:sha 256:F9 dfddf 63636d 84 ef 479d 645 ab 5885156 AE 030 f 611 a 56 F3 a 7 AC 7 F2 FDD 86d 7e
状态:hello-world 的图像是最新的:最新的
docker.io/library/hello-world:latest
这将下载 docker 映像,并将其本地存储在您的机器上。在上面的输出中,它表示图像已经是最新的,因为在此之前我运行了docker run hello-world
命令,并且下载了 hello-world docker 图像。
不要担心什么是 Docker Hub 或者什么是 Docker images ,我们将在接下来的教程中了解它们。只是给大家简单介绍一下,Docker Hub 是一个在线平台,开发者可以上传自己的 Docker 图片,供任何人下载使用。因此,你将需要一个互联网连接来下载你好世界 Docker 图像。
因此,在本教程中,我们在 docker 中运行了一个简单的 hello-world 应用,并使用了两个命令,docker run
和docker pull
。在下一个教程中,我们将学习如何使用 Docker Hub,然后我们将开始学习各种 Docker 命令。
Git
GIT 基础知识
GIT 简介
大家好,欢迎来到Git Basics
课程。
今天,我们将讨论一个全世界软件开发人员都信赖的工具。不仅仅是大型跨国公司,甚至是小公司和初创企业。从课程名称中你可能已经猜到了,我们将讨论Git
但是,Git 是什么?为什么是 Git?是什么让 Git 如此受欢迎?我们有你所有问题的答案。继续读下去!
Git 是一个Version Control System
(VCS),一个使用起来极其聪明的工具,即使听起来过于势不可挡。简单来说,一个VCS
就是一组被监控访问的文件。这是什么意思?让我们考虑一个小例子来帮助你理解。
如果你是一名平面设计师或网页设计师,并希望保留图像或布局的每个版本(这是你最想做的),使用 VCS 是一件非常明智的事情。它允许您将文件恢复到以前的状态,将整个项目恢复到以前的状态,比较一段时间内的更改,查看最后是谁修改了可能导致问题的内容,谁引入了问题以及何时引入,等等。使用 VCS 通常也意味着如果你把事情搞砸了或者丢失了文件,你可以很容易地恢复。此外,你只需要很少的开销就能得到这些。
许多人选择的版本控制方法是将文件复制到另一个目录中(如果聪明的话,可能是一个带有时间戳的目录)。这种方法非常常见,因为它非常简单,但也非常容易出错。很容易忘记你在哪个目录下,不小心写错了文件或者复制了你不想复制的文件。
让我们在下一章看看版本控制如何节省我们的时间和减轻压力。
VCS 是如何工作的?
那么VCS
到底是做什么的呢?在我们继续之前,让我们先了解一些基本术语。
你可能会遇到诸如源代码管理或修订控制这样的交叉术语,而不是版本控制,但这些是可互换的术语,请记住它们的含义是一样的。然而,在本课程的剩余部分,我们将坚持使用版本控制系统。
你和你的团队正在处理的所有文件的集合被称为Repository
。它还包含一些特殊数据,如变更发生的顺序、变更的描述以及负责该特定变更的人员。
项目的变更可能需要几个小时、几天甚至几周才能完成。将未完成的工作视为一件事是不公平的。您需要告诉 VCS,您已经完成了更改,并且希望将其保存为版本,以便它可以为您跟踪。告诉 VCS 一个版本已经完成的行为叫做committing
。因此,版本通常被称为commits
。
VCS 隐藏了多次提交的复杂性,因此您的项目看起来干净整洁。它通过将所有数据存储在标记为隐藏的文件夹中来做到这一点,这样在您需要与它们交互之前,您不会意识到它们存在于您的计算机上。
但是如果你的仓库在一个隐藏的文件夹里呢?这是 VCS 的第三大功能。它允许您查看项目历史记录。您可以检查项目昨天、一个月前甚至一年前的样子,通常只需一个命令。
它们还允许您与其他团队成员共享您的仓库,以便于协作。开发人员经常在一个项目上一起工作,VCS
只是让他们更容易。
所以现在让我们理解为什么我们使用Git
。有很多可用的版本控制系统,但 Git 是其中最受欢迎的。让我们看看为什么!
我为什么要用 Git?
Git
是 Linus Torvalds 开发的版本控制系统,听起来耳熟吗?是的,你说得对,Linux 操作系统之父。Linux 内核还是由他维护。
考虑一下 Linux 内核项目。
- 它有超过 1500 万行代码。
- 每天新增约 3500 条线路。
- 每当新内核发布时,大约有 1000 名开发人员参与到这个过程中。
Git
最初是为了帮助管理 Linux 内核,从一开始就让协作变得容易。如果 Git 能有效地管理一个像 Linux 内核一样大的项目,它就能轻松有效地管理你的项目。
此外,Git 的架构是分布式版本控制,而不是集中式的网络访问 VCS。集中式 VCS 需要网络连接才能工作,中央故障可能会导致您的所有工作被破坏。像 Git 这样的分布式 VCS 不需要网络连接来与仓库交互。每个开发人员都有自己的仓库,这使得协作变得又快又容易。
最后,继续GitHub
。GitHub 很容易成为与合作者或全世界分享你的项目的最受欢迎的网站。这就像是你项目的社交网络。Repositories
可以公开,这样任何人都可以提交一个提交,帮助你的项目变得更好。
Git 使用校验和来保护您的数据。这使得 Git 在没有得到一点点信息的情况下不可能对数据进行更改。这一功能在最低级别被构建到 Git 中,并且是其理念的组成部分。基本思想是,在 Git 无法检测到的情况下,您不能在传输过程中丢失信息或损坏文件。Git >使用 SHA-1 哈希系统,您可能知道,它是一个由十六进制字符组成的 40 个字符的字符串,并且是根据内容计算的。Git 广泛使用这些值,并通过该散列而不是名称将文件存储在数据库中。
GitHub
在软件开发领域越来越受欢迎,如果你想成为一个项目的合作者,你可能需要了解 Git,这本身就是了解 Git 的一个原因。
GIT 安装
现在我们已经知道了什么是版本控制系统,让我们确保您的计算机上已经安装了Git
版本,这样就可以很容易地进行操作。
吉卜赛人
如果你有一台苹果电脑,好消息!默认情况下,它会出现在您的系统上。直接进入下一章。
Windows 中的 GIT
前往这个链接。您会注意到网站会识别您的操作系统,并提示您下载最新版本。
继续从软件包安装。打开安装程序后,只需点击下一步,使用默认设置安装 Git,因为它们是推荐设置。如果需要,您可以更改安装目录。
- 安装完成后进入开始菜单,寻找 Git 文件夹/图标。您可能会看到两个选项,
Git GUI
或Git Bash
。有些人更喜欢使用图形用户界面,但我们将在本课程中重点介绍命令行。但是随时可以查看 Git GUI。 - Git Bash 是一个类似于 Unix Bash 的命令行界面。它将运行我们在课程中使用的几乎所有命令。继续,通过在命令行中键入 $git - version 进行测试。
不同之处在于,我们将使用纳米编辑器来编辑文件,而这在 Windows 操作系统上是不可用的。
例如:我们将输入 $ nano filename 来打开一个文件,但是在 Windows 机器上输入这个将导致命令未找到错误。相反,你可以输入 $记事本文件名,就可以工作了!
Linux 中的 GIT
如果您想通过二进制安装程序在 Linux 上安装基本的 Git 工具,您通常可以通过发行版附带的基本包管理工具来完成。
- 例如,如果你在 Fedora 上,你可以使用 yum: $ sudo yum 安装 git-all 。
- 如果你在一个基于 Debian 的发行版上,比如 T2 Ubuntu,试试 apt-get: $ sudo apt-get 安装 git-all
好了,现在我们有了最新的版本,让我们开始使用 Git。
进阶
使用 Git 仓库
每当我们开始一个项目时,我们都需要将所有文件存储在一个repository
中。让我们首先创建一个仓库。我们建议您在单独的专用路径中工作。
要创建仓库,请使用 $ git init 命令。继续键入以下命令来创建您的第一个仓库。
$ git init my_first_repository
您将获得一条消息“在”中初始化了空的 Git 仓库,以及您的仓库的路径。要检查,输入ls
,果然,这是你的第一个仓库。
Go into your repository and type ls.
嗯。那里什么都没有。回想一下,当我们谈论 VCS 的特征时,我们讨论了隐藏文件。让我们通过输入 $ ls -a 来检查这些隐藏文件,其中列出了隐藏文件。
。git 文件夹是您的本地仓库,它存储所有历史和版本控制信息。
但是,如果您已经在进行您的出色项目,并且没有首先初始化 git 仓库,该怎么办呢?别担心。转到该目录,输入 $ git init ,不输入仓库的名称。Git 将假设您需要为这个项目目录创建一个仓库。如果你现在输入 $ ls ,你会看到那个奇妙的小 git 文件夹正坐在那里等着你开始你的令人敬畏的项目。
仓库的名称没有那么重要。git 目录里面。重命名您的仓库就像使用mv
命令一样简单。
$ mv my_first_repository awesome_project
移除仓库很容易,但却是致命的。在迈出这一步之前要三思。如果您决定继续并移除您的仓库,删除。git 目录会为你做这项工作。
**```sh
$ rm -r awesome_project/.git
![Deleting Git Repositories](https://gitee.com/OpenDocCN/studytonight-zh/raw/master/docs/misc/img/d5f0349c8b6d9eb6a3a96b88e81d51dc.png)
完成了。是的,就是这么简单。既然您已经对仓库有了足够的了解,那么让我们来了解一下如何将更改提交给它们。
* * *
* * ***
# 暂存区
> 原文:<https://www.studytonight.com/github/staging-area-in-git>
到目前为止,我们要么只向仓库中添加一个文件,要么一次添加多个文件。如果我们想要控制我们提交给仓库的内容,该怎么办?如前所述,Git 为我们提供了一个`Staging Area`,使得控制我们的提交变得更加容易。首先,确保你已经回到了我们令人敬畏的项目库。
```sh
Now, run the following command on your terminal: $ git status
正如您可能已经猜到的,该命令将给出该仓库的状态。输出现在看起来很无聊。
请注意“工作目录清理”语句。换句话说,没有跟踪的和修改的文件。Git 也看不到任何未跟踪的文件,否则它们会列在这里。最后,该命令会告诉您所在的分支,并通知您它没有从服务器上的同一个分支分叉。目前,该分支始终为"master"
,为默认;在这里你不会担心的。
但是我们已经将自述文件添加到我们的仓库中,并且在状态中似乎没有它的迹象。
Git 状态将只显示分配了一些特殊状态的文件。自提交自述文件以来,没有对其进行任何修改。因此,到目前为止,该文件的状态对它来说并不重要。如果它显示了仓库中所有文件的状态,那么当您在处理一个大项目时,这将是一个漫长而乏味的任务。
我们的项目目录有点空,只包含自述文件。继续创建一些文件(空的也可以)。再次运行状态命令看看有没有什么激动人心的事情在等着我们!
确实有!注意我们这次没有得到‘工作目录清理’消息,你能猜到为什么吗?
没错。我们向项目中添加了一些尚未添加到仓库中的新文件。继续将文件 1 添加到仓库中(回想一下,我们可以使用 git add 命令)。再次运行状态命令将会发出新的信息。事情越来越令人兴奋了!
现在,您可以提交这个文件,或者将文件 2 和文件 3 添加到仓库中,然后将它们一起提交。在我们继续之前,在编辑器中打开文件,并向其中添加一些内容。当您再次检查状态时,Git 会明确告诉您这些文件已经被修改。这项功能有助于您在处理大型项目时保持冷静。
尝试创建更多的文件,并四处寻找自己!在下一章中,我们将研究更多的 Git 基础知识。走吧!
GIT:回顾我们的仓库
原文:https://www.studytonight.com/github/more-about-repository-in-git
在本教程中,我们将学习更多关于仓库的知识,如仓库日志、在 repo 中提交、检查提交的差异等。
信息技术:仓库日志
好吧。因此,我们现在对 Git 及其命令有了很多了解。Git 不仅为您提供了一种维护文件的方法,还为您提供了在需要时签出旧版本文件的工具。开始之前,请确保我们所有的文件都在您的目录中。
我们将使用的第一个命令是git log
,正如您所料,它向您显示了您在仓库中的所有提交的日志。log 命令首先显示最近的提交。向下滚动将显示我们添加的关于自述文件的第一个提交。让我们分解这个日志的输出。
它以每次提交的唯一标识符开始。回想一下,我们讨论过 Git 使用阿沙-1 散列来保证安全性。这被用作唯一标识符。您可能认为用数字来命名提交更容易。虽然这是真的,但是有些仓库是公共的,并且有大量的人参与其中,所以在提交发生时很难对它们进行编号。
标识符下面是发起提交的作者姓名。这使得跟踪谁对你的项目有贡献成为可能。下面是关于提交日期时间信息。
最后,我们看到提交消息本身。请注意,每条消息都提供了关于该提交中所做工作的足够信息。现在考虑这样一种情况,您在项目中添加了一个特性,但是被客户拒绝了。有了这个日志,您可以准确地检查这个特性是什么时候添加的,以及与之关联的提交标识符。
签出一个提交
现在你知道这个功能是什么时候添加的了。但是如何检查该特性的代码呢?别担心,我们不需要真正的时间机器来获取代码。Git 为我们提供了回到过去并检查这段代码的功能。
Git 使用‘git check out’命令来恢复早期版本。为此,它需要提交标识符。我们实际上不必键入长哈希值,因为让我们面对它,我们很懒。我们只需要提交标识的前 5-6 个字符,我们就可以开始了(大多数时候)。
哦哦。一个可怕的信息。一种超然的精神状态。好吧,Git 只是告诉你,你已经签出了文件的早期版本!同样,在这里进行改变也可能是危险的。让我们检查我们的第一个承诺。继续输入ls
。如果您已经遵循了教程的步骤,您可能只会看到自述文件。嗯。太奇怪了。没有文件,文件 2,文件 3 的踪迹。
在我们被它吓到之前,让我们理解我们正在检查一个旧版本的仓库。当我们第一次启动提交时,我们根本没有文件,文件 2,文件 3!这解释了为什么没有这些文件。
GIT:检查提交中的差异
让我们回到现在。我们可以再次使用【git 结账】,但是我们回到哪里呢?如果你还记得“git status”命令,它会显示一条信息“在分支机构主机上”。
Running the following command will bring you back to the current repository state:
$ git checkout master
再次键入ls
以确保您的所有文件都可用。我们有另一种方法来检查旧版本。git diff
派上用场了。它显示了两个州之间的差异。只需使用第一次提交和最后一次提交的标识符运行命令。跳过输出中的前几行。勾选+ sign
表示添加了内容。然后,它继续显示实际的变化。
有更清晰、更容易使用的图形界面,但这是它的基础。这都是关于 Git 的基础知识。让我们深入一点,好吗?
GIT:分叉
几乎每个 VCS 都有某种形式的分支支持。Branching
的意思是,你偏离了发展的主线,继续做工作,而不打乱那个主线。在许多 VCS 工具中,这是一个有些昂贵的过程,通常需要您创建源代码目录的新副本,这对于大型项目来说可能需要很长时间。
以一棵树为例。一棵树总是有一些树枝和大树干。类似地,Git 中的分支是项目的较小部分,不需要干扰主分支(召回主分支)。它们有自己的提交,一旦完成就会被添加到 master 中。主枝就像树干。在大多数情况下,包含在主分支中的代码通常是正在部署的代码。
有些人将 Git 的分支模型称为其"killer feature"
,这无疑让 Git 在 VCS 社区中脱颖而出。为什么这么特别?Git 分支非常轻量级,使得分支操作几乎是即时的,并且在分支之间来回切换通常也一样快。与许多其他风投不同,Git 鼓励经常分支和合并的工作流,甚至一天分多次。理解和掌握这个特性给了你一个强大而独特的工具,可以完全改变你的开发方式。
让我们考虑一下我们的牛逼项目是基于一个网络开发项目。您目前在主分支上,进展很顺利,但是您需要在项目中添加一个登录功能。现在,您肯定不希望这段代码干扰您当前的代码,是吗?让我们给这个特性一个自己的分支。您可以使用git branch
命令创建一个新分支。检查仓库的状态,确保您没有任何要提交的内容。
命名新的分支登录功能:$ git branch signin_feature
再次检查状态。嗯,我们还在主分支。我们如何切换到我们的新分支?还记得我们以前的朋友吗?此命令可用于在分支之间切换。当您没有为它提供哈希值时,Git 假设您想要切换到一个分支。继续切换到我们刚刚创建的新分支,检查状态以确保正确。
$ git checkout signin_feature
继续创建一个新文件,这里是文件 4,并提交它。成功提交后,请检查日志。当然,您可以看到新提交的条目就在那里。
让我们切换回 master 并再次查看日志。哦哦。缺少提交。我们擦掉了吗?别担心承诺还在。Git 足够聪明,知道这个提交是在signin_feature
分支中,主分支与它无关。
请记住,无论何时分支,新分支都是当前分支的副本。到目前为止,我们从主服务器分支出来,因此所有的主服务器提交在日志中都是可用的。
还有一种方法可以创建新的分支。我们的朋友git checkout
帮助我们完全绕过分支命令。继续并在命令行中键入以下内容。让我们创建一个新的订阅功能:
$ git checkout -b subs_feature
-b 选项允许您创建一个分支,并在一个命令中切换到所有分支。
现在我们已经创建了一些分支,让我们了解更多关于管理它们的知识。我们现在总共有 3 个分支机构,但更大的项目有数百甚至数千个分支机构。我们如何跟踪哪些分支存在?
Git 允许我们通过使用“git 分支”命令来查看仓库中的所有分支:
$ git branch
这将为您提供所有分支以及您当前分支的列表。假设我们决定跳过订阅功能并将其删除。不是你的每一个想法都能进入最终项目。
您可以使用分支命令中的 -D 选项来删除您的分支:
$git branch -D subs_feature
哎呀!我们无法删除当前正在工作的分支。切换回主机,然后重试。
唷!这是一个漫长的过程。干得好。你应该得到一块饼干!接下来,我们研究合并。这是什么意思?继续读...
GIT:合并分支
你可能已经猜到了未来会发生什么。在最后一章中,我们创建了几个分支来帮助我们组织工作。我们创造了树枝,希望有一天它们能帮助这棵树长成它的最终形态。让我们继续上一章的例子。
回想一下,我们创建了两个新分支signin_feature
和subs_feature
,由于不再需要后者,所以删除了后者。到目前为止,我们只有两个分支,但是在一个更大的项目中,您可能有数百甚至数千个分支。所以你的项目看起来可能有很多平行的分支。最终目标是将所有这些分支合并成一个最终副本。你可以考虑合并作为分支的对立面。
Merging
结合两个分支的变化,形成一个内聚分支。它还结合了来自分支的所有提交。正在合并的分支不会被删除,它仍然可用,即使在合并后,您也可以继续处理它。
但是我们如何处理两个分支中被更改的文件。我们如何决定我们希望将哪个版本延续到最终项目?这种情况被称为合并冲突。虽然大多数 VCS 提供了合并的选择,但他们把解决合并冲突的责任留给了你。不太聪明。这是 Git 比大多数 VCS 更好的另一个领域。
Git 在解决合并冲突方面相当聪明,并且大多数情况下会尝试自动解决它们。当它无法确定选择哪个文件时,它可能会要求您解决问题,让我们稍后再讨论这个问题。在本章中,我们将看到 Git 如何围绕合并工作并自动解决合并冲突。
假设我们一直在进行signin_feature
的工作,您最终感觉到需要提交它并将其添加到主项目中,即主分支。我们还没有改变任何事情,所以不存在合并冲突的可能性。让我们继续将登录分支合并到我们的主分支。在这种情况下,合并是一个快速而无痛的命令。快速运行状态命令来知道你在哪个分支上。我们希望在主分支上,所以如果您还没有这样做,请切换到主分支。
继续运行 $ git 日志查看提交历史在主节点上的样子,并运行以下命令将分支“sign _ feature”合并到主节点。
$ git merge signin_feature
运行 $ git 日志命令并检查更改。果然,我们的提交历史现在已经合并了。这很容易,因为没有冲突需要解决。
让我们开始设置一个让 Git 解决的冲突。打开自述文件,更改第一行。将此变更提交给主节点并检查signin_feature
分支。
再次更改自述文件的内容。这次在一条不同的线上。提交它并签出主分支。像以前一样运行合并命令。
这次输出不一样。Git 告诉我们它正在自动更新 README。它已成功检测到两个分支中的文件都已更改。但是因为它们在不同的线上,Git 能够合并它们。运行 $ git 日志这次也给了我们一个新的提交消息!
Merge branch 'signin_feature'
分支signin_feature
仍然可用。该分支的日志显示没有任何更改。它只影响了主分支。所以这在 Git 看来既简单又聪明。但是 Git 不能决定做什么的时候呢?地狱破会输吗?让我们在下一章找到答案...
GIT:合并冲突
我们在上一章看到的合并对 Git 来说相对容易解决。但在现实中,并不是所有的冲突都会变得容易。早些时候,我们在两个分支中对同一文件中的不同行进行了更改。你能猜到什么会构成一场激烈的冲突吗?
完全正确!在同一行,或者更确切地说,在文件的相同区域所做的更改将导致硬冲突。Git 无法确定您希望在最终项目中保留哪个版本。在一个简单的冲突中,Git 方便地将两个版本合并到文件中。
让我们继续为 Git 设置一个硬冲突。看看你在哪个部门,以确保万无一失。假设你在signin_feature
分支。打开您的任何一个文件并进行一些更改。请记住提交此更改。
然后,签出主分支,并对同一个文件进行更改,但方式不同。
现在您已经在 master 上了,提交这个更改并尝试合并两个分支。就像上一章一样,我们看到 Git 检测到了一个合并冲突,并尝试自动启动它,但是失败了。呃-哦。
Git 检测到对同一行的更改,并且不理解您希望在最终项目中保留哪个文件。每当 Git 遇到这样的冲突时,它就把它留给用户(你!)手动解决冲突。打开冲突的文件,嗯?文件里面好像有一些奇怪的标点符号。这些不是我们写的,那是谁写的?
没错,Git 标记了冲突发生的区域。相当聪明而且乐于助人,是吧?它们被称为冲突标记。带角度的括号表示整个区域有冲突。等号行是两个版本之间的分隔符。顶部版本标记为head
,这是最近一次提交的特殊术语。最下面的版本标着signin_feature
,没有奖品猜猜是什么意思。
Git 给了我们全部的权力来编辑和保留我们在最终项目中想要的任何版本。既然我们已经解决了冲突,我们需要告诉 Git 已经完成了。解决所有其他冲突(如果有)。让我们将更改添加到临时区域,并运行 $ git commit 。
请注意,Git 知道我们正在解决一个冲突,并且已经为我们准备了一个提交消息。在那里,冲突得到了解决,两个分支机构成功合并。请记住,在这种情况下,Git 放弃了对合并解析的所有控制,它完全依赖于您来解决它。
手动处理合并可能看起来有点困难和复杂,但是它可以确保您在最终的项目中有正确的版本。所以这一切都是为了合并。
当你在个人项目上工作时,像 Git 这样的 VCS 是有用的,但是当你和其他人合作时,它们显示了它们真正的力量。当您协作时,您需要远程存储您的仓库。接下来让我们了解更多关于与远程仓库交互的信息!
高级
GIT:使用远程仓库
又见面了。到目前为止,我们非常确定您对 Git 基础知识已经足够了解,并且可以非常轻松地处理自己的仓库。如果只有你一个人在做你的项目,这很好。您可以提交您的更改,创建和合并分支,以保持您的仓库干净。
但是我们还是错过了一些东西。如果不是只有你一个人在做这个项目呢?喘息!别担心,我们是来教您如何使用远程仓库的。你会问,什么是远程仓库?考虑一下这个...
你目前正在做你的令人敬畏的项目,并决定引进一个能帮助你并和你一起工作的人。但是...但是...他们不能在您的仓库中工作,他们需要在自己的机器上访问它。他们可以创建仓库的副本并继续工作。这个过程叫做Cloning
。所以现在,你们都做得很好,你们经常承诺,使用分支机构等。但是在不同的机器上。那么,我们如何将所有这些工作结合起来呢?
就像合并分支一样,您也可以合并仓库。有些人更喜欢坚持 Git 的分散性质,而有些人更喜欢将仓库托管在其他地方的中央服务器上。
在接下来的章节中,我们将了解更多关于远程仓库的信息。当你在做一个大项目时,你必须和别人分享你的进展。这是通过使用远程仓库来实现的。让我们进入下一章,开始使用远程仓库。
GIT:克隆
除非您自己启动项目,否则开始基于 Git 的流程的第一步是克隆您将要使用的仓库。Git 提供了一些简单的命令来帮助我们开始。
通常,远程仓库是位于您可以通过网络访问的计算机上的仓库。对 Git 来说,远程只是意味着其他地方。但是由于你手边可能没有另一台计算机,我们将使用位于同一台计算机上但路径不同的仓库。让我们继续克隆我们当前的仓库awesome_project
。Git 对此有一个命令,是的,你猜对了,它的 $git 克隆。当然你需要指定你需要克隆什么。
如果您在不同的计算机上工作,这可能是一个网络地址。如果仓库托管在某个服务器上,这将是一个网址。现在,我们可以为它提供一条通往我们的 awesome_project 仓库的路径。让我们命名我们的克隆体our_clone_project
。
看看这个仓库,你会发现一切都如你所料。Git 已经自动为我们建立了一个出色的仓库作为远程仓库。运行 $ git remote ,您将看到它打印出origin
,这是我们最初的仓库。让我们切换回原来的仓库,再次运行 $ git remote 。
什么都没有打印出来。如您所见,我们的原始仓库完全不受克隆的影响。这很好,因为如果有人决定查看您的代码,您不希望您的仓库改变。
但是这里的问题是,我们希望我们的两个仓库相互通信,而我们的awesome_project
不知道我们的 _clone_project 存在。让我们通过使用 $ git 远程添加命令来解决这个问题。您需要为此添加提供一个名称,在这里使用origin
没有意义。让我们称之为our_clone
并提供我们的仓库的路径。噗!完成了!
我们现在可以创建新的分支、文件并一起工作。但是我们如何跟上两个仓库中的变化呢?在下一章中,我们将讨论在仓库之间推和拉我们的变更。
GIT:推送拉取
现在我们已经建立了彼此对话的仓库,让我们看看它们之间的pushing
和pulling
变化。假设我们将开发一个数据库特性。
推送命令
创建一个名为data_feature
的分支和一个你选择的文件并提交。我们想向我们的合作伙伴展示我们的新功能,但是他们的本地机器上还没有我们的更改。
The easiest way to do this is to push our changes to the remote repository: $ git push
哇哦。这是一个很大的错误信息。总结一下:
matching
表示 git push 将把你所有的本地分支推到远程的同名分支。这使得你很容易不小心推了一个你不想推的树枝。simple
表示 git push 将仅将当前分支推送到 git pull 将从中拉出的分支,并检查它们的名称是否匹配。这是一种更直观的行为,这就是为什么默认值被更改为。
此设置仅影响本地客户端的行为,并且可以通过显式指定要在命令行上推送的分支来覆盖。其他客户端可以有不同的设置,它只影响当您没有指定要推送哪些分支时会发生什么。
因此,让我们通过键入以下内容将 push.default 设置为新的方式:
$ git config --global push.default simple
在我们继续之前,请记住我们的新分支还不存在于我们的远程仓库中。我们需要明确要求 Git 通过向push
命令提供分支名称来跟踪这个新分支的变化。
默认情况下, $ git push 的第一个参数必须是一个遥控器的名称。如果你不提供一个,Git 会自动假设你说的是原点。继续输入 $ git 推送原始数据 _ 功能
啊!成功的信息。终于。转到您的awesome_project
并检查分支是否已创建。很好,都在那里。当您在原点时,签出新分支,编辑文件并提交它。现在回头对同一个文件再做一些更改(是的,我们知道这很混乱,但我们保证这一切都是值得的)。现在试着推动改变。
哦哦。错误。看起来我们没有及时了解遥控器的变化,因此无法推送。那么我们如何随着遥控器的变化更新自己呢?
拉动命令
你可能已经猜到了,因为有一个 $ git push 命令,所以有一个 $ git pull 命令。语法与 push 命令非常相似。我们说我们想要拉,我们指定我们想要从哪个远程拉,以及我们想要为哪个分支获取历史。
Git 试图把这些信息拉过来,哦,对了。在两个仓库中,我们对同一个文件进行了编辑,git 不知道如何修复它。它的工作方式非常类似于合并,只是它合并了来自两个仓库的更改。召回合并冲突?我们这里有一个。
继续解决冲突(你现在很清楚这一点)。将文件添加到临时区域并提交。我们的 git 拉现在应该完成了,所以再次尝试推动。现在一切正常。
这一切都是关于从我们的克隆体推进到起源和从起源牵引到我们的克隆体。反过来呢?让我们回到我们的awesome_project
,进行编辑并提交。运行 $ git push 和呃-哦。
丑陋的错误信息。关于未配置推送位置的信息。在您与远程仓库的大多数交互中,您将从您的原点推动和拉动变更。在这种情况下,我们自己创建了这个仓库,这就是为什么我们需要指定我们要推送到的目的地。啊,一切都好。
一旦你得到一些练习,你会很容易做到这一点。接下来,我们将了解最受欢迎的仓库托管服务GitHub
。
GIT:使用 Github
有很多选项允许您托管您的仓库。如果你精通系统管理,你可以自己托管它们。如果你不介意你的仓库是公共的,那么有很多服务可以免费托管,例如 Bitbucket、CloudForge、Assembla 等。这些服务中最受欢迎的是GitHub
。
GitHub 拥有数百万开发人员的用户群,并提供优秀的工具来管理您的项目。去 GitHub 设置账号。一旦你注册了,GitHub 会为你提供所有他们必须提供的功能
我们建议您通过游览来更好地了解 GitHub。您可以搜索仓库,例如,继续并在搜索栏中键入“Linux”。第一个结果是 Linux 内核源代码树。它后面的小图显示了人们在一段时间内提交到仓库的频率。让我们去看看这一页。
我们看到了项目的简要描述以及关于仓库的一些统计数据。随着时间的推移,Linux 仓库已经有超过 50 万次提交和 452 次发布。那是巨大的!
如果 GitHub 不能轻松地提供这些信息,我们将不得不将仓库的一个副本克隆到我们的计算机上,以便能够发现 GitHub 项目的活跃程度,开始是什么样的项目,代码当前是什么样子,或者我们可能有任何其他问题。因为他们在 GitHub 上托管,所以我们可以从我们的网络浏览器中找到所有的信息。
GitHub 还提供了一些其他不错的特性。有些项目有自己的问题跟踪器。如果我们点击页面的问题标签,我们可以看到人们在哪里归档 bug 并询问关于所述项目的问题。如果您不熟悉问题跟踪器,它为人们提供了一个很好的地方来提出和讨论关于有问题的项目的问题,并且通常提供工具来帮助项目维护人员有效地解决这些问题。
拉请求是一个有趣的概念,起源于 GitHub。请记住,在 GitHub 中,提取代码意味着我们从远程仓库中合并变更。遵循这一逻辑,当您有代码想要某人拉进他们的项目时,您使用拉请求。这是一个非常有用的协作工具。
让我们停下来想想我们的awesome_project
。它远不如 Linux 活跃,但我们仍然希望在 GitHub 上发布它。在右上角,我们可以看到一个创建新回购按钮。就名字而言,我们现在只使用令人敬畏的项目。如果需要,请提供描述。这个库将是公开的,因为我们是免费的。
没关系,我们还是想和你们分享我们的仓库!GitHub 在创建一个全新的仓库方面提供了一些帮助。但是由于我们有自己的仓库,我们只需要完成最后两个步骤。我们需要添加 GitHub 作为一个远程,我们需要将我们的更改向上推。
让我们继续这样做:
$ git remote add origin https://github.com/joshvarun/awesome_project.git
$ git push -u origin master
我们将运行他们说在项目中运行的线路。我们需要提供用户名和密码。这种推动似乎奏效了。我们将切换回 GitHub,刷新页面,我们就有了我们的项目历史。你可以看到,在整个项目过程中,我们做了 11 次承诺。
像 GitHub 这样的许多托管服务提供了一个功能完善的界面来帮助您管理和探索您的项目历史。一些团队已经开始依赖这些服务来帮助他们更有效地合作。
GIT:尾注
那都是关于 Git & GitHub 的!从了解 VCS 到掌握 Git 的基础知识,我们已经取得了长足的进步。数百万开发人员和几乎所有主要公司都使用 Git 来简化协作和开发。
您对 Git 的了解将帮助您高效地完成个人项目,并为您节省宝贵的时间。此外,这是一个很好的技能添加到你的简历。
不要忘记继续练习,如果你需要复习基础知识,你知道在哪里可以找到我们!
我们祝贺您从StudyTonight
开始完成 Git 基础课程。直到下次!
Jenkins
介绍
什么是持续集成?
原文:https://www.studytonight.com/jenkins/continuous-integration-overview
持续集成是一个过程,在这个过程中,所有的开发活动(每天的活动)都通过编译和构建项目在给定的时间点进行集成,并经过良好的测试。持续集成背后的基本思想是通过团队中的开发人员进行大量的签入来确保最终没有编译问题。此外,这将有助于在开发过程的早期阶段识别任何编译问题。
在这个过程中,所有开发人员的活动都在中央系统(进行所有签入的仓库)进行协作和合并。在这个过程中,主要目标还是消除“集成问题”。每一个集成都是自动构建、部署和全面测试的。
关于竞争情报的一些历史
短语持续整合最早是由格雷迪·布奇在 1994 年创造的。他在面向对象分析&设计应用中创造了这个短语,以解释小的内部发布如何在开发微过程中发挥重要作用。1997 年,一个叫肯特·贝克的美国软件工程师和另一个叫罗恩·杰弗里斯的人,随着不断的集成,发明了极限编程。
连续集成(CI)最初是为了与在测试驱动开发环境中编写的自动化单元测试结合使用而发明的。即在开发人员机器的本地环境中运行所有单元测试,并确保在将所有测试推入主仓库之前,所有测试都成功通过,没有任何其他问题。这是一个额外的注意事项,以避免在主流的工作副本上出现任何损坏,尤其是当开发人员在同一个模块上工作时。
竞争情报的最佳实践
- 维护一个适当的代码库。
- 自动化构建过程。
- 确保每个开发人员每天都将文件提交给主流。
- 每一个承诺都应该建立。
- 构建的结果应该是透明的,这样所有的开发人员每天都会意识到构建的质量。
- 在生产环境中测试构建。
- 应该立即修复损坏的构件。
- 每个人都应该能够从主流获得最新版本。
- 自动化部署过程。
竞争情报的优势
- 降低风险水平。
- 不再整合流程。
- 许多糟糕的代码味道& bugs 可以在开发过程的早期阶段减少。
- 频繁的部署过程更容易、更快。
- 通过使用像 Jenkins(早期被称为哈德逊)和巡航控制这样的工具,很容易实现这个过程。
Jenkins 集成服务器
原文:https://www.studytonight.com/jenkins/jenkins-integration-server
在前一章中,我们研究了“持续集成”的概念。为了为启用了配置项的项目创建环境,需要一个工具。于是,Jenkins 投入了行动。Jenkins 是一个开源工具,用于实现持续集成。
由于甲骨文公司的一些问题,Jenkins 项目从哈德逊开始。Jenkins 基本上是一个运行在 servlet 容器中的基于服务器的系统,这个容器就是 apache tomcat。它支持许多工具,如 Git、SVN、Mercurial 和 Clearcase。Jenkins 最初是由一个名为“T2”的开发人员创办的。
Jenkins 是做什么的?
Jenkins 的主要工作是执行基于触发器配置的步骤列表。以下是 Jenkins 触发时执行的步骤/任务列表:
- 执行代码编译&用 ANT、Maven 或 Gradle 构建软件。
- 运行内部 shell 脚本
- 将生成的版本存档
- 最后开始集成测试的执行。
- 监控上述任务的执行。
- 在任何步骤失败的情况下停止构建。
- 通知用户每次构建的成功或失败。
Jenkins 关注什么?
Jenkins 主要关注 2 项重要活动:
- 软件的持续构建:只不过是创建一个持续的集成环境
- 监视外部作业的执行:这监视定义的作业- CRON 作业。
Jenkins 的特点
- 易于安装和配置。
- 构建细节的永久链接可读 URL。
- 通知的电子邮件集成。
- JUnit 测试报告。
- 标记支持每一个成功的构建。
- 分布式构建。
- 用于管理依赖关系的文件指纹
- 插件支持
Jenkins 最佳实践
以下是与 Jenkins 合作时的一些最佳实践:
- 始终确保 Jenkins-用户身份验证的安全。
- 使用文件指纹来管理依赖关系。
- 将 Jenkins 与 JIRA 这样的问题跟踪系统整合在一起。
- 始终配置 Jenkins 以生成趋势报告。
- 在磁盘空间较多的分区空间上安装 Jenkins。
- 为维护和开发项目设置不同的作业。
- 删除未使用的作业之前先将其存档。
- 向团队的所有开发人员发送电子邮件通知。
- 每次成功构建后的标记、分支、基线。
如何配置 Jenkins 构建服务器
在上一章中,我们详细研究了什么是 Jenkins,它的用法以及与 Jenkins 一起工作时的最佳实践。现在,让我们看看如何在本地机器上配置 Jenkins。
注意:下面的步骤展示了如何在 windows 环境中安装和配置 Jenkins,以及如何使用 Apache Tomcat web 服务器。
Jenkins 设置
-
从 https://jenkins-ci.org/下载最新的 Jenkins 战报。向右上方点击链接最新和最大的下载最新的战争文件。
-
在我们机器的本地网络服务器中部署 Jenkins.war 文件。例如雄猫
-
Start the server and open the browser and hit the URL http://localhost:8080/jenkins
-
Click on the create new jobs link to configure a project for build automation. Enter the details of the project as shown below and click OK.
-
In the next page, fill all the required details like - description, path of the project's pom.xml and other details and click save.
-
A project/job is created in Jenkins. As shown below:
- Click on the Build now option as shown above. This will read the pom.xml and pull out the latest code and executes a build process and generates the jar/war file accordingly.
- Click on the build number link and it opens up the build details. Click on the console output to see the logs of the build.
如何在 Jenkins 配置 JDK
原文:https://www.studytonight.com/jenkins/configuring-jdk-in-jenkins
在前一章中,我们学习了如何配置 Jenkins 并启动服务器,并查看其 GUI 了解其他基本配置。本章将学习如何在 Jenkins 配置 JDK。由于 Jenkins 通常用于构建和部署 java 应用,因此它为 Java 应用提供了出色的特性。
默认情况下,Jenkins 将使用从系统路径中找到的 java 版本。这就是 Jenkins 号本身运行的情况。但是,可能存在需要配置多个版本的 JDK 的情况。考虑一下,在生产系统中,应用可能在 JDK 5 上运行,在某些质量保证平台中,可能需要更高版本的 JDK,以便执行某些特定的测试,例如性能问题。
作为一种最佳实践,使用与生产环境中使用的版本接近的 java 版本来构建应用总是明智的。因为,在 JDK 5 下开发的应用可以很容易地与 JDK 6 一起运行,但反过来,失败的几率可能总是很高。
Jenkins 提供了一个很好的特性来配置多个 JVM,以克服上面提到的逆向 java 版本问题。
在 Jenkins 配置 JDK
以下是在 Jenkins 配置 JDK 应遵循的步骤:
- 将 Jenkins.war 部署到 tomcat 服务器中并启动服务器。
-
From the home page, click on the link Manage Jenkins and click on Configure System as shown below :
- From the next page, click on "Add JDK". The easiest way to configure JDK is to provide a name and path of the java installation directory. (Consider the same path used for JAVA_HOME). In the below screenshot JDK 6 and JDK 7 has been configured,
NOTE : The Jenkins will validate to check whether the installation directory exists for the specified JDK versions.* JDK can also be installed by intimating Jenkins to do the task. The check box install automatically needs to be checked in this case. Jenkins will download and installs the specified version of the JDK into the tools directory of the Jenkins home directory.
- 完成配置 JDK 的所有设置后,只需单击页面底部的“保存”即可保存配置。
保护 Jenkins
保护 Jenkins 构建服务器
这里需要理解的最基本的事情是确保 Jenkins 的安全,因为它是开放的。任何人都可以使用该网址访问 Jenkins,并在 Jenkins 执行各种可用的任务。因此,这需要得到保证。作为最佳实践,建议始终保护 Jenkins,然后配置全局安全性。最好的方法是通过配置到我们自己的本地数据库来使用 Jenkins。
以下是保护 Jenkins 应遵循的步骤:
-
部署 Jenkins.war 并启动服务器。
-
打开 Jenkins 主页,点击管理 Jenkins。
-
In the Manage Jenkins page, click on Setup Security button.
-
In the next page, select the enable security check box.
-
Here, the very first thing to be done is to set the security realm. The easiest way to do this is to have Jenkins with our own database. To achieve this, select the option Jenkins own user database. Also, ensure that Allow users to sign up checkbox is also checked. Save the configuration.
-
Now a link Sign up will be available. Click on the same and fill the form to sign up. Once successful, log in with the account created.
登录后,您可以在导航栏中看到详细信息。
-
现在点击管理 Jenkins &选择配置全球安全。在安全领域部分,取消选择允许用户注册选项。这将确保在您的许可下无法创建新用户。* Now, we need to configure the authentication for the accounts. The 2 best options preferred are Matrix-based security & Project-base project authorization strategy. This enables you to set per user for the actions which they can perform. Here, I have considered Matrix-based security
-
保存表单。注销并再次登录。* A login page will be displayed and login with the created account.
在 Jenkins 配置构建系统
原文:https://www.studytonight.com/jenkins/configuring-build-system
要配置构建系统,需要配置 JDK、ANT/MAVEN、SCM 配置细节、自动化构建选项电子邮件通知和其他重要的东西。下面是配置时要遵循的步骤。在下面的例子中,我们认为这个项目是一个 Maven 项目。
-
Deploy and start the Jenkins server and from the home page, click on New Item.
-
Then click on OK. Now a new page will be displayed where the details of JDK, ANT/Maven, SCM, automating build options, email notifications can be configured.
Jenkins:配置供应链管理
为了为构建系统配置配置管理,在“源代码管理”系统下,为所需的项目选择所需的配置管理选项,并相应地提供详细信息。
注意:可以在 Jenkins 中配置多个仓库 URL。
Jenkins:配置构建触发器
Jenkins 证明了触发构建的多种选择。以下都是一样的:
- 每当生成快照依赖项时生成
- 远程触发构建(例如,从脚本)
- 在其他项目完成后构建
- 定期构建(在 CRON 作业上运行)
- 轮询配置管理(在 CRON 作业上运行)
用户可以从上面的列表中配置多个选项。下面的屏幕截图显示了如何基于 CRON 作业配置构建(通过选择“定期构建”选项)
上面提到的 CRON 表达式触发器建立在每天早上 5 点和晚上 10 点,每个月重复!
Jenkins:配置马文
对于任何要在 Jenkins 中构建的 maven 项目,入口点都是 pom.xml。配置项目构建的简单方法是指向项目的 pom.xml,如下所示:
此外,还有许多其他选项也可以在这里配置,如上所示。
Jenkins:配置 Maven 构建设置
Jenkins 提供了通过发送为每次构建运行配置的邮件来配置通知服务的功能。它可以配置如下所示:
Jenkins:配置后期构建活动
Jenkins 还提供了配置构建后需要执行的活动的功能。以下是可用的选项:
-
Aggregate downstream test results.
-
Archive the artifacts.
-
Build other projects.
-
Deploy artifacts to maven repository.
-
Record fingerprints of files to track usage.
Jenkins 管理
Jenkins 插件管理
Jenkins 是这样一个方便的工具,可以通过添加额外的插件来轻松扩展,以适应更多的功能。例如,包括 Git 作为配置管理选项,JUnit 插件等。这可以通过选择选项管理 Jenkins-管理插件来轻松完成,如下所示。
从管理 Jenkins 屏幕点击管理插件。这将进入列出所有可用插件的页面。单击可用选项卡,从可用插件列表中选择需要安装的插件。例如,选择如下图所示的 Github 插件,点击页面底部的不重启安装按钮。这将下载 github 插件,并安装在 Jenkins。
当您单击“安装”时,下载将开始。
安装完成后,您将看到一条成功消息。
现在,打开任何创建的构建作业,点击配置。Git 选项将添加到源代码管理下。
在 Jenkins 服务器中设置作业
在 Jenkins,任何项目的构建都是由 JOBs 处理的。因此,为了构建一个项目,总是需要创建一个作业。这可以很容易地完成,如下所示:
从 Jenkins 主页点击新项目,只需输入项目名称,选择 Maven 项目,点击【确定】。
在下一页的构建下,只需指向 maven 项目的 pom.xml ,并在目标和选项下指定干净验证。然后应用并保存页面。
在下一页中,将创建一个作业。只需点击立即构建链接,可以看到将会触发一个新的构建,如下图所示,
Jenkins 服务器中的备份管理
众所周知,Jenkins 总是需要一些磁盘空间来执行构建作业并将其归档。这是通过使用 JENKINS_HOME 进行配置的。只要需要,就可以配置此路径。
备份和恢复
在 Jenkins 中,工件的所有设置、构建日志和档案都存储在 JENKINS_HOME 目录下。简单的方法是将这个文件夹作为新的备份单独保存,每当需要使用相同的文件夹时,只需将其复制回来。
在此目录下创建的构建作业包含在 Jenkins 安装中配置的每个单独作业的所有详细信息。只要复制作业,任何作业都可以从一个安装目录移动到另一个安装目录。
此外,Jenkins 还提供了动态重命名现有作业的功能。要反映应用的更改,只需从 Jenkins 的用户界面点击重新加载配置。
存档未使用的作业
有时可能会有一些构建作业长时间不使用。在这种情况下,有一种简单的方法来归档相同的内容。只需导航到 JENKINS_HOME 目录,为需要归档的作业创建一个归档文件夹。
精简备份插件
由于 Jenkins 可以通过使用几个插件得到极大的扩展,因此 Jenkins 中出现了一个可以用于备份管理的插件- ThinBackup 插件。该插件备份作业特定的配置文件。
从 Jenkins 主页,点击管理 Jenkins,在下一页点击管理插件。
在下一页的可用插件标签下,搜索/查找瘦备份插件。选择相同内容,点击不重启安装按钮。
只要重启 Jenkins 就能看到插件成功安装。从主页,点击管理 Jenkins链接,在下一页,从列表中如果可以发现 ThinBackup 插件安装。只要点击相同的,下面的页面就会显示出来。
点击设置链接,配置备份选项。
只需根据需要提供配置细节并保存设置即可。
Scrum
基础
Scrum 简介
原文:https://www.studytonight.com/scrum-framework/introduction
Scrum 是管理产品开发的几种技术之一,属于敏捷软件开发的大类。敏捷方法论旨在支持运行产品的迭代和灵活方法。
在多样的敏捷方法论中, Scrum 被很好地定义为开发软件、网站和信息技术工具等产品的组织类型。Scrum 鼓励团队在有限的时间内专注于一定数量的工作。它还允许团队建立和改进能力,以估计开发一个新功能需要花费多少努力,并且所学到的经验教训被记录在系统中。
Scrum 起源
当时,最适合软件开发的方法是瀑布模型。在瀑布模型下,产品开发分阶段进行- 设计、实施和发布。
20 世纪 90 年代末,电子媒体和互联网出现。为了支持这些,软件开发组织必须结合更多的灵活性来适应不同需求的平台的变化。此后不久,生活在台式电脑上的大型软件应用的开发让位于通过移动设备交付的更小、更灵活的应用。开发这些需要一个相同的方法。Scrum 开始以可持续和高效的方式合作,而不是等到整个周期结束。
Scrum——最热门的项目方法
原文:https://www.studytonight.com/scrum-framework/scrum-methodology
获得一门新语言的知识是获得一项新技能的最初步骤之一,语言的一致使用是团队努力合作的基础。Scrum 中定义了几个术语来清楚地理解它的含义,它们是:
Agile: 它是一套软件开发实践,旨在帮助开发人员协同工作,快速轻松地适应变化。
客户:谁雇佣了团队来创建产品。
开发人员:负责创建和维护产品的人员。
产品 Backlog:一个项目的潜在特性或变化的不断发展的列表。
产品负责人:帮助团队定义产品的人。
Scrum Master: 负责维护工件和监督 Scrum 仪式的人。
Sprint: 固定天数,在此期间团队可以一起工作,对产品进行一系列商定的变更。
故事:一种清晰一致的划分、措辞和讨论团队在产品上可能需要做的工作的方式。
快速失败技术
Scrum 希望你失败。事实上,它以口号“快速失败”而闻名。不,我没开玩笑。这听起来很奇怪,但这是有很好的理由的。传统上,项目经理和开发人员会工作数月或数年才能看到结果。大多数时候,事实上 80%左右的软件和项目都失败了。那么,你可能会问,为什么他们会报名参加更多的失败?嗯,真的,他们不是。
诀窍在于关注第二个词:快速。失败是可以的,只要你从中学习,但是如果你不得不等待太久,你就不会从中学到那么多。Scrum 采纳了敏捷宣言及其关键原则,将它们归结为一个非常简单的框架,鼓励小规模的关注和快速的学习周期。
软件开发的传统方法
原文:https://www.studytonight.com/scrum-framework/traditional-approach
传统上,瀑布项目团队面临三个约束:时间、成本和范围。一旦他们的项目开始,他们就无法改变这些事情。
问题是,在项目过程中,你周围的商业环境会发生变化。这意味着,当你完成时,你建造的东西不再有价值。这不是任何人的错。业务需求的变化比以往任何时候都要快。项目需求也在快速变化以跟上。
在传统方法中,首先详细记录客户需求,规划软件架构并将其概念化,然后工作开始产生最终产品。
用 Scrum 解决项目问题
在敏捷宣言出现之前,团队注定会在每个项目上失败。然后,我们将重点从约束项目的所有三个元素转移开来,并决定让其中一个变得灵活。
敏捷是众多遵循相同原则的方法论的大伞。Scrum 就是其中之一。Scrum 更进一步,创建了一个框架来帮助团队保持专注,保护他们不受干扰。Scrum 的两个关键角色是必不可少的,产品所有者和 Scrum 大师。
在 Scrum 框架中,客户在开发过程中不断参与,一次又一次地审查创建的点点滴滴。当产品被分开测试时,测试产品的成本更低。更容易测试,生产出更坚固的产品。
Scrum 敏捷原则
原文:https://www.studytonight.com/scrum-framework/agile-principles
瀑布作为一种方法论,并不是一件坏事。在少数情况下,这是很有意义的,就像开始建筑施工,在那里,一组明确的步骤,当按顺序实施时,将导致一个建筑。
事实工作更像是一个科学实验。你尝试一些东西,检查输出,如果它对你不起作用,尝试一些其他的方法。盖房子的时候你肯定做不到,但是有了软件或者其他产品,你每天都可以做到。这就是为什么瀑布没有很好地用于软件开发。
你不能预先计划发现的过程。从事瀑布项目的高技能软件开发人员的挫败感是导致敏捷革命的引爆点。
看看敏捷宣言及其基本原则。这群创新者用 12 个关键原则来支持这一宣言。这个宣言和原则成为了一套新的项目管理和软件开发方法的基础。
敏捷宣言: 查看
敏捷宣言背后的原则: 12 条神圣原则
是什么让敏捷与众不同?
有几个压倒一切的主题让敏捷与众不同。关键的变化之一是,我们要求我们的业务伙伴在整个项目中与我们合作。不仅仅是在开头出现描述他们想要什么,然后在结尾出现并告诉我们我们是如何错过目标的。我们需要直接的、持续的互动来提供他们真正需要的东西。
另一个关键是,我们不再希望使用里程碑和项目阶段来衡量成功。
Scrum 团队的角色
Scrum 是一个轻量级的框架,它可以非常灵活、高效和强大,但是,就像一辆车一样,如果没有一个强大的引擎来推动你前进,最好的车身和设计的框架将一无所获。每个 Scrum 团队都有两个主要的重要角色:产品所有者(PO) 和 Scrum 大师(SM) 。
产品负责人
采购订单是团队的业务代表。他们不是兼职团队成员。他们每天都会出现,因为他们每天都在为最终产品做贡献。
他们审查团队完成的所有工作,要么接受,要么要求团队做出改变,以确保实现最高价值。早些时候,业务人员是通过很少更新的需求文档来呈现的。
在 Scrum 团队中,PO 总是对工作进行排序,并确保团队成员清楚地了解请求的细节,但这只是他们工作的一部分。他们也每天与利益相关者互动。
PO 与团队互动是不够的,他们还必须与业务环境中发生的所有变化保持一致。因此,采购订单是产品愿景的守护者。他或她定义并管理要完成的工作的 Backlog 以及这些工作项目的优先级。
Scrum 大师
Scrum 大师是团队最显眼的代言人。Scrum Masters 重视透明度。他们会设计图表和板,与任何好奇或有兴趣知道他们如何做的人分享团队的进展。
当团队遇到困难时,他们也是第一个升级点。Scrum Master 将努力移除任何阻挡器,直到它们被清除,团队可以继续工作。当产品所有者关注需要做什么时,Scrum 大师关注团队如何工作。
还有一点,Scrum 大师还要求团队对他们对产品所有者的承诺负责。它们显示了团队绩效随时间变化的趋势,以帮助团队改进流程和实践。正如您所看到的,每个角色对于让框架正常运行都是绝对关键的。如果你缺少这些角色中的一个,Scrum 将远不如你同时拥有这两个角色的效果好。
建立你的 Scrum 团队
原文:https://www.studytonight.com/scrum-framework/building-scrum-team
Scrum 是关于日常协作和交流的。你应该尽一切努力让你的团队变得更容易,因为这将获得巨大的利润。这就是为什么,如果可能的话,将你的团队成员安排在同一个房间、过道或空间,以使合作更加有效。
在许多公司,由于建筑或距离障碍,这是不可能的。没关系。你仍然可以用 scrum 取得成功。你只需要再努力一点,就能确保充分的合作。您可以尝试的一些事情是:视频会议、专用聊天室和所有位置的会议电话。这些可以很容易地帮助你的团队保持联系。
现在,让我们来谈谈团队构成。你的首要任务必须是确保你有一个专门的团队。
构建强大的 Scrum 团队所需的资源
如果你的团队成员在你的项目和另一个项目之间多次交谈,他们会失去很多效率,从而减慢你的交付。
将您的核心团队投入到一项任务中,会带来更好的专注度、更高的效率和更快的交付。
- 团队成员数量
根据 Scrum 准则,理想的团队规模是七个成员,正负两个。我知道这听起来很具体,但研究表明,这些数字最大限度地提高了人们建立亲密关系和最有效合作的能力。
- 通信通道
大多数情况下,不可能将团队聚集在一个地方进行 Scrum 会议和其他与工作相关的问题。在这种情况下,沟通渠道在一个地方集合团队起着至关重要的作用。它可能是一个视频会议或音频会议,只是为了分享你目前的进展和讨论路障,如果有的话。
如果你花时间研究这些要素,并帮助你的团队做好准备,成功会很快到来。一旦你让你的团队为成功做好准备,你会惊讶于他们学习有效工作的速度有多快。
为你的项目设定愿景
原文:https://www.studytonight.com/scrum-framework/vision-for-project
愿景是地图/轮廓/蓝图,它将向你和你的团队展示通往最终目标的道路。在任何工作开始之前,产品所有者都要确定这一点。
项目的愿景告诉你,你的团队,每个人,你要去哪里,最终你会交付什么有价值的产品或改进。
愿景中包含的目标是我们所说的最小可行产品,或最有价值产品。
MVP 是关于开发一个足以让早期采用者得到它的产品。谁能为产品改进提供反馈。这种方法基本上是说,如果我们做一些小的工作来把我们可用的产品推出去,我们就达到了目标。以这种方式对待这项工作有几个很好的理由。
分解的第一个层次或设定项目愿景的第一步是确定你的主题。主题只是类似作品的一个广泛分组。所以,仔细分组类似的任务。
理解愿景和主题的真实世界示例
餐馆每天都这样。开胃菜、沙拉、主菜和甜点是他们工作的主题。这些不仅仅是为了吸引或帮助顾客阅读菜单。它们在整理厨房方面也很有用。你的主题也是如此。
考虑一个供顾客点午餐的移动应用的例子,我们的应用主题可能是:简介、订单、支付和送货等等。
这些主题在两个方面帮助了我们。首先,它们有助于引发关于需要开发什么来满足该主题的最有价值球员的想法。第二,他们帮助我们将我们的工作组合在一起,这样我们就可以提高效率并最大限度地降低风险,比如确保我们在完成概要文件开发之前已经建立了安全性。
一旦我们确定了我们的主题,我们就把它们进一步分解成特征。功能是我们可以用来帮助我们保持组织的下一个小部分工作。比如:一个好的 Profile 有用户图片,细节。因此,你需要一个用户上传他们的照片和其他细节的功能,显示在他们的个人资料上。
进阶
撰写用户故事
原文:https://www.studytonight.com/scrum-framework/writing-user-stories
我们已经讨论了主题和特性作为工作分组。这些都是非常有用的结构,可以帮助我们组织起来,但是对于团队来说,它们仍然太大了,无法在很短的时间内完成工作并交付价值。用户故事是可以快速交付的工作的战术层面。同时,它们也不会小到没有价值。
团队中的任何人都可以写用户故事,但通常是 PO。作为客户的利益相关者和代表,他们的职责是确保 Backlog 中的所有内容都为客户增加价值,因此他们通常编写用户故事。
创建用户故事时需要记住的要点
- 好的用户故事是独立的
首先,好的用户故事是独立的。它可以与其他故事分开传递,本身就有价值。如果你只有时间做一件事,这个故事可以单机。
- 可协商
用户故事也可以协商。在故事交付工作之前,可以随时重写、更改或取消。用户故事必须有价值。它为采购订单、利益相关方和客户提供价值。
- 有意义
用户故事应该有意义,应该给工作带来价值。
- 可尊敬的
你必须能够用故事点来估计故事的大小。这意味着这个故事有足够的描述性,所以你知道需要做什么来完成它。只有这样你才能明白需要付出的努力。
A 故事是一个任务,故事描述中提到了关于任务的所有细节。然后给故事分配一个时间(故事点,在这个时间内必须完成。它也被赋予了优先级,重要的任务可以被标记为优先处理的高优先级任务。
现在有很多软件可以使用,像亚特兰蒂斯的吉拉这样的完整的 Scrum 计划。
编写好的用户故事可能很有挑战性,但是如果需求和计划是好的,那么随着时间的推移会变得更容易。
在敏捷生命周期中,你的故事会不断发展。如果单个任务很大,需要在单次迭代中实现,那么大的故事可以被拆分成更小的故事。
多堆故事集中在一个史诗下。当我们说,有时,一个大故事可以分解成多个小故事,我们把所有的小故事归入一个史诗之下。就像一个大故事。
设定成功的阈值
原文:https://www.studytonight.com/scrum-framework/threshold-for-success
您的下一步是创建您的团队可以用来完成这项工作的边界。
每个故事都有自己的接受标准,这意味着当故事被标记为完成时。这个定义做到了,陈述了所有故事的最低要求。对于我们团队中被认为已经完成的故事,它必须在预发布环境中进行良好的测试,或者对于我们团队中被认为已经完成的故事,它已经过代码审查,并且所有错误都已修复。
这些验收标准可以在计划 scrum 时设定,也可以由产品所有者设定。
接下来,您的产品负责人需要对 Backlog 进行优先排序。这就是所谓的Backlog 整理。这仅仅意味着故事是按价值顺序连续排序的。故事的结果越有价值,它在 Backlog 中的优先级就越高。
最后,你需要建立你的Sprint 持续时间。Scrum 说你的 Sprint 可以是一到四周的长度,更倾向于较短的时间尺度。
Scrum 中的故事和评估
有两种估计。有实际估算和相对估算。实际估计是你在看地图时使用的。从 A 点到 b 点有 25 英里,这个很具体。然后,是相对估计,即将事物相互比较,以获得某事物的大致概念。像这个蛋糕和那个馅饼一样宽。
在 scrum 中,我们使用两种评估。我们使用相对估计,通过相互比较用户故事来获得我们工作的大致规模。这给了我们对事物有多大的整体感觉或估计。
故事本身是用户想要如何与我们的产品互动的粗略指南。因为这是对需求的粗略陈述,所以我们不能太具体地说它有多大。此外,由于这只是一个粗略的划分,我们不希望利益相关者认为我们确切地知道要做什么。
故事点是我们用来表达相对大小的度量单位。估计意味着轻量级和快速。不应该花几天甚至几个小时来决定你会在某件事上付出多少努力。虽然这可能需要一点点练习,但一旦你掌握了窍门,你就会飞过去。
理解的现实生活例子
让我们举一个例子,我们必须开发一个类似于study now的网站,具有一些基本的功能。我们将如何计划和分配工作:
- 首先,将向产品所有者提供所有重复使用的信息。关于项目的信息通常由客户提供,如果它是外包项目,并且如果它是公司本身的产品,则产品架构师设计需求并提供给产品所有者。
- 一旦所有的要求都清楚了,在我们的例子中是:
- 包含网站信息的主页
- 个人资料页面
- 登录/注册机制
- 等等...
- 在这种情况下,创建个人资料页面和登录/挑选机制将是史诗,因为这将涉及许多要完成的小子任务。然而,创建主页可以是一个故事。
- 当我们说登录/唤醒机制是一部史诗时,我们的意思是,它由以下故事组成:
- 为数据对象定义数据模型(创建表),如保存用户数据的用户表等。
- 为登录和注册创建用户界面
- 然后完成登录/注册系统的后端
- 集成测试开发的系统。这在 Scrum 中非常重要,无论你构建了什么小部分,你都要测试它。
- 所有创建的故事都被分配了故事点,如完成该任务所需的时间。这取决于以下标准:
- 需要完成的工作量
- 工作的复杂性
- 工作中涉及的风险或不确定性
- 故事点是时间的度量。斐波那契数列大多用于故事点。可以是 1、2、3、5、8、13 等等,其中 1 表示任务需要一个完整工作日的努力。
- 计划扑克是围绕 Scrum 计划创建的一项活动,旨在使其更具互动性。你可以很容易地谷歌如何玩规划扑克,或者访问这个链接
- 因此 scrum famework 只不过是我们在不知情的情况下已经在做的事情。这是在一个时间框架内计划和执行以产生最佳结果的最佳方式之一。是的,他们对任何事物都有特定的术语。
为您的项目创建路线图
原文:https://www.studytonight.com/scrum-framework/creating-roadmap
Scrum 也有路线图和发布计划的工具。我们在路线图和发布计划中使用了两种不同的机制。路线图是非常高级的,旨在随着时间的推移应用于您的主题。这样,在给定的时间范围内,每个人都会对重点有一个大致的了解。
如果我们举一个为送餐服务创建一个移动应用的例子,有太多的组件需要我们去处理。从下订单到付款和交货跟踪,我们需要决定处理此事的最佳订单。所以我们将从 App 设计和下单系统开始,稍后我们将转向支付系统,这是第三方集成,也是任何业务最重要的特征。像 Scrum 中的其他东西一样,这是一个指导方针,而不是规则。
路线图被认为是在每次 Sprint 结束时更新的。在整个 Sprint 过程中,团队将不断学习新东西,撰写新故事。所以路线图应该是一份有意义的文件。这只是一个指南,但它会帮助你专注于完成项目。
发布计划
一旦你完成了这个,你就可以围绕你创建的主题时间线来组织你的故事。这是您创建发布计划的方式。
发布计划是下一层细节。这是一个高层次的计划,旨在将路线图与 Sprint 阶段联系起来。它提供了我们如何交付的可见性。
在 Scrum 中,你必须在每一次Sprint结束时完成功能齐全的故事。但是,您不需要在每次 Sprint 结束时向涉众发布它们。这意味着你可以在两到三次 Sprint 中完成所有的工作,然后一起发布组合结果。您将使用您的故事点来帮助您的团队决定他们在每次 Sprint 中可以做什么。一旦你的团队在一起一段时间,他们会达到一个稳定的速度。
什么是 Scrum Sprint?
Sprint 是一个时间框架,不超过一个月,在此期间完成一个项目或子项目。最常见的 Sprint 是 2 到 3 周的时间。一次 Sprint 完成后,下一次 Sprint 立即开始。
在 Sprint 计划期间,故事、史诗被创建,并且在正在进行的 Sprint 期间,没有任何可能影响 Sprint 目标的改变。
每一次 Sprint 都以一次Sprint 计划会议开始,在每年春季结束时,召开一次Sprint 评审会议,由产品负责人评审已提交的任务是否完成。此外,还可以召开回顾会议,回顾上一次 Sprint 中面临的问题,并在接下来的 Sprint 中加以改进。
Sprint 预计划
原文:https://www.studytonight.com/scrum-framework/sprint-preplanning
Sprint Planning 的主要议程是让 Sprint 的执行更加有效。
为了提供正确的先决条件,需要在 Sprint 预计划期间采取以下行动:
- 澄清验收标准。一个故事必须有资格被标记为“完成”的标准。
- 提供对用户故事的估计,帮助产品负责人确定 Backlog 中的优先级。
- 将高优先级用户故事分解成适合 Sprint 的块。
- 考虑对团队中关键资源的依赖以及每个团队的工作量。
管理依赖关系
一个好的用户故事是独立的,它没有任何依赖性。
有 3 种类型的依赖关系:
- 简单依赖
- 外部依赖性
- 交织的依赖
简单依赖
当一个用户故事依赖于另一个用户故事时,就会发生简单的依赖关系。消除这种单向依赖的一种方法是以不同的方式组合或拆分用户故事。当这不可能实现时,另一种方法是为依赖项数量多于依赖项数量的独立用户案例设置更高的优先级。
外部依赖性
当一个故事依赖于外部团队时,就会产生外部依赖。在这种情况下,团队需要协商集成和交付日期,并调整故事的优先级。在其他团队交付他们的用户故事之前,从事相关故事的团队不应该承诺在 Sprint 中完成相关故事。
交织的依赖
这些依赖是指两个或更多的用户故事是相互依赖的,没有另一个就无法完成。理想情况下,团队应该寻找打破所有连接的方法,或者寻找将交织在一起的依赖关系转化为简单依赖关系的方法。处理这些跨 Scrum 团队的依赖关系是与 Scrum 团队一起工作的 PO(产品所有者)的重要职责。
产品所有者和 Scrum 开发团队需要将注意力集中在当前版本的高优先级故事上。这就是为什么 Sprint 预计划是有效 Sprint 计划的重要一步。
实际 Sprint 计划的 Scrum 准备
原文:https://www.studytonight.com/scrum-framework/actual-sprint-planning
充分的 Sprint 计划实际上是由所有团队成员完成的。团队代表在整个团队中承担工作是不合理的。
Sprint 规划要点
- 团队代表应该准备 Sprint 计划。
- 如果多个 scrum 团队在处理同一个产品 Backlog,他们必须聚集在一起,一起参与 sprint 计划。
使用优先化的 Backlog,采购订单按顺序向团队呈现最高价值的案例。目的是团队中的每个人都充分理解故事的意图和故事的具体接受标准。对于所有的用户故事,解释 done 的定义也是有帮助的。
每一次 Sprint 都从一次Sprint 计划会议开始,包括两次会议-什么会议和如何会议。在“什么”会议中,团队从 Scrum Backlog 中挑选用户故事,他们将处理这些故事。而且,在“如何”会议中,挑选出的用户故事被进一步分解成具有设定优先级和故事点的小任务。
规划的前半部分-决定要实现什么
回顾 Sprint 目标
Scrum 会议代表将展示项目的高水平愿景。产品所有者确定 Sprint 的目标,并证明它将如何向产品交付价值。
查看产品 Backlog
在 Sprint 计划会议之前,产品负责人将重新安排用户故事,并优先考虑这些故事。
在 Sprint 计划期间,PO 向团队呈现最高优先级的用户故事。利益相关者将对用户故事给出反馈。故事可能会根据利益相关者的反馈而改变。
计划的后半部分——如何完成工作
在计划的后半部分,团队决定如何完成工作。
创建 Backlog
PO 与团队一起回顾优先级最高的故事,并决定他们在每次 Sprint 中能做多少。每个人都应该在这个计划中投入自己的工作。如果有人不能提交,PO 和团队需要一起改变 Sprint 的形状,直到每个人都能提交。Sprint 计划是 scrum 中一个关键的协作努力。
更新发布计划
一旦团队致力于用户故事,产品负责人将重新审视用户故事到 Sprints 的发布计划映射。利用当前的信息、团队在前一次 Sprint 中完成的故事、从当前 Sprint 的产品 Backlog 中取出的故事,产品所有者更新发布计划。
Scrum 非常重视承诺这一步。每个人的承诺对实现你的 Sprint 目标非常重要。从评审 Sprint 目标到更新发布计划,每一步都必须认真执行。
跟踪 Scrum 进度
原文:https://www.studytonight.com/scrum-framework/track-scrum-progress
如果项目很关键,你的涉众问团队事情进展如何是很常见的。这很好,因为人们对项目的结果很投入。但是,如果只有一些团队成员对事情的进展有全面的了解,这可能会分散团队的注意力。
Scrum 通过发布信息辐射器来解决这些挑战。信息辐射器是你在团队网站上发布的任何东西,它帮助每个人理解你在做什么以及进展如何。遵循这种方法让涉众知道项目中发生了什么是一个很好的实践。它显示了 Sprint 阶段承诺的故事、任务及其当前状态,以及已经完成的任务。
分享进度信息的另一个主要工具是 Sprint燃烧图。团队使用这个图表来衡量他们在 Sprint 中的表现。在任务板告诉你任务完成情况的地方,它没有告诉你与你在 Sprint 阶段的情况相比如何。烧毁就可以了。
烧毁图表
典型的消耗图表从左上方到右下方以一条直线开始,显示 Sprint 的消耗率。消耗图上的线或列可以用来表示从团队在 Sprint 计划中承诺的工作开始,每天 Sprint 中实际剩余的努力点的数量。随着工作的完成,这些列应该变得更短,直到它们达到零。
下面你会发现一个非常简单的燃烧图:
这里的绿色直线代表理想的燃烧速率。Sprint 的每一天,都在努力完成所有的任务。
带圆圈的橙色线条,代表实际烧毁。当实际烧损高于 Idea 烧损线时,意味着团队会错过完成日期,需要增加更多的人来增加速度。
15 分钟的每日站会/每日 Scrum
原文:https://www.studytonight.com/scrum-framework/daily-standup-meeting
scrum 大师将建立你的每日 Scrum。这也通常被称为每日站会,简称为站会。为了让 scrum 工作,它依赖于三个 C:
- 协作
- 沟通
- 速度
单口相声包括这三个部分。这是协作的基础要素,因为它包括团队中的每个人:开发人员、测试人员、产品负责人和 scrum 大师。
它每天都在同一时间发生,所以你的 scrum 大师会选择一个对每个人都有效的时间站起来。对于位于同一地点或几个时区内的团队来说,这非常简单。对于国际球队来说,这可能更具挑战性。但是有了今天的视频会议功能,这也是可以实现的。底线是每日站立是 scrum 框架中不可协商的一项。这是任务全面转移的时候。
同时,你的单口相声也不是进度报告。任何人都不应该对自己的活动进行全面的解释,而应该只是概述。也鼓励涉众参加,但是要求他们保留他们的问题和评论直到 scrum 结束。
每日 scrum 很短。限 15 分钟。它可以更短,但不能更长。整个团队都在努力保持速度,因此有了这个简写的名字,standup。scrum 大师还将更新限制在每人三个问题:你昨天做了什么?、你今天打算做什么?,有什么阻碍你进步的吗?当个人经历这些问题时,整个团队作为一个单位理解他们的进展,并看到他们的工作如何融入整体。
Scrum 中的 Backlog
原文:https://www.studytonight.com/scrum-framework/backlogs-in-scrum
在 Scrum 方法论中,术语 Backlog 是一个包含项目所需功能的简短描述的优先列表。
利益相关者希望确保他们从您的项目中获得他们需要的东西。在整个项目中保持正确优先级的一个关键方面是对产品 Backlog 的不断细化。这意味着采购订单正在与利益相关方开会,以了解需要什么。随着业务需求和需求的变化,他们不断地转移工作。
在整个项目中,随着新特性和故事的发现和添加,您的 Backlog 在不断变化。其他故事正在被改变,甚至可能被删除。
随着新故事的发现,产品负责人会为每个故事制定细节和验收标准。但是每次 Sprint 至少一次,整个团队必须聚集在一起,看看有什么新项目出现。这通常是一个 30 到 60 分钟的Backlog 整理会议。它通常发生在 Sprint 的中点附近。产品负责人向团队朗读新故事,团队询问任何遗漏的细节。
产品所有者对 Backlog 的责任
- 如果团队需要任何澄清,应对他们的新故事。
- 设置 Backlog 的优先级。
- 允许 Scrum 团队在项目的整个生命周期中适应不断变化的业务需求。
- 在 Sprint 阶段与团队互动。
- 毫不拖延地填补需求中的空白。
scrum 团队的产品负责人就像一辆车的司机。为了让车辆平稳运行并完成旅程,驾驶员必须工作良好,并提供车辆所需的任何东西,无论是燃料还是修理。
高级
在 Sprint 中完成故事
原文:https://www.studytonight.com/scrum-framework/getting-stories-done
在 Scrum 中,团队非常认真地对待他们的 Sprint 承诺。他们每天都在努力合作,完成他们的故事。
请记住,在 Scrum 中, done 表示符合验收标准的可用产品。因为这是目标,团队一直在开发和测试,以确保整个故事符合验收标准。
然而,验收标准的批准必须来自产品所有者。由于产品所有者是团队中的业务代表,他们的接受或拒绝是最终的决定。
成功执行 Sprint 有四个关键要素:
- 日常计划
- 日常协作
- 专注并完成
- 尺寸
日常计划
每天和你的 Scrum 大师讨论,一起计划你的一天。开始一个新的故事,并开始努力。随着故事的完成,将工作流程传递给各自的测试团队,并为新任务做计划。
日常协作
与您的团队和产品负责人合作,并理解您正在处理的每个故事的 done 的定义。协作是团队在当前 Sprint 中取得进展所必需的。
专注并完成
保持专注于完成的最简单方法是经常向客户展示您的工作。你需要这种持续的反馈,以确保当你认为某件事已经完成时,其他人也这样认为。
尺寸
测量是成功 Sprint 的另一种方式。每天在燃尽表上追踪你的进度。
当团队完成任务时,Scrum Master 会跟踪已经完成的工作,并使用燃耗图向团队展示他们是否正在完成 Sprint 的承诺。
最常见的敏捷度量是速度。这仅仅是一个团队每次 Sprint 从他们的 Backlog 中完成的分数。
团队承认他们的进步,并密切关注即将发生的事情。这种协作有助于团队保持对整个项目的意识。它让团队专注于大局,同时在每一次 Sprint 中交付可用的产品。
演示团队的工作
原文:https://www.studytonight.com/scrum-framework/demo-team-work
在 Scrum 中,我们努力在每一次 Sprint 的最后交付一个有效的产品。但如果没人知道又有什么意义呢?Scrum 对此的回答是演示。
如您所知,采购订单负责接受或拒绝已交付的产品。他们接受的任何东西都可以展示给更多的观众。请记住,采购订单作为其他利益相关方的代表对他们负责,以确保他们得到他们想要的。
这就是传统瀑布设计和敏捷的 Scrum 方法论的区别。在瀑布模型中,一旦项目完成,我们就知道涉众的反馈,但是在敏捷模型中,在每次 Sprint 的最后,需要演示来获得涉众的反馈。
演示是采购订单和团队如何确保利益相关方对我们交付的内容感到满意。演示对于 Scrum 团队来说是一个强大的仪式。演示在团队和利益相关者之间建立信任。这是团队获得直接反馈的绝佳机会。
利益相关者可以亲眼看到代表他们所做的工作。他们向团队提供反馈,既有对所做工作的赞扬,也有对变化的建议,也称为新故事。采购订单将捕获这些,并在演示后开始添加细节,并为他们的 Backlog 设置新的故事。有时,涉众会看到一些已经展示的东西,并决定他们根本不想要它。完全没关系。
演示的另一个优点是让涉众知道谁在做他们的项目。他们可以亲眼看到每个团队成员为每一次 Sprint 所带来的技能和奉献。这是一个在团队和利益相关者之间建立关系的机会。这种可见性为利益相关者提供了一个更广泛、更平衡的视角来看待创造他们的产品所需要的东西。
此外,涉众将看到团队接收反馈并适应其不断变化的需求的意愿。最后,演示展示了最终目标的整体进展。每次 Sprint 后,您的采购订单将使您的产品路线图和发布计划保持最新。这是你向利益相关者展示它们的地方。您的团队正在带领利益相关者一起踏上旅程。利益相关者还可以对每个计划发布的时间和内容提供反馈。
注意:请确保您定期演示,以保持您的产品和利益相关方紧密一致。
评估您的团队
原文:https://www.studytonight.com/scrum-framework/evaluate-team
对于 scrum 团队来说,每一次 sprint 都 100%关注涉众和最终用户的需求,但是敏捷背后的原则是团队需要定期反思如何更有效,并相应地调整他们的行为。
在 scrum 中,这个原则已经形成团队回顾,简称回顾。这是每一次 Sprint 的重点不在产品上,而在团队本身的时候。
因为重点是团队和团队过程,Scrum 大师促进了这个仪式。为了有一个成功的复古,你必须有一个安全的环境。因此,这是一次闭门会议。团队必须知道只有专门的团队成员将出席,并且团队规范将被遵守。这种安全感对于确保坦诚评估团队合作方式所需的公开对话至关重要。
通常复古的议程很简单。它由三个问题组成。什么效果好?、有哪些做得不好?和我们将改进什么?
虽然这份清单上的一切都很重要,但一定要先从团队的成功开始。我知道这听起来很奇怪。我们是来变得更好的,为什么要专注于我们已经做得很好的事情呢?但是为了帮助球队远离防守反击,你需要先欣赏他们。
在你开始分享改进的地方之前,填写他们的情感银行账户。当你专注于第一个问题时,注意团队在他们控制范围内做得好的所有事情。这包括:
- 团队内外伟大合作的例子。
- 认可团队为互相帮助所做的事情。
- 确保完全专注于团队本身,而不是他们已经完成的故事。
通过专注于成功,团队创造了一个积极的行为循环。
他们会想变得更好,这样下次他们就有更多的东西可以庆祝了。当进入第二个问题,什么事情做得不好时,一定要关注那些你可以改变的事情,而不是你无法控制的外部团体或工具。例如,也许你的团队需要使用一个特定的测试工具,而这个工具很慢。您的改进领域不是修复工具,而是找到更好的方法来更有效地使用工具。
scrum 团队使用的所有其他工具都是关于产品的。复古之所以强大,是因为它关乎团队本身。记住,scrum 是一个框架,只有当团队健康并专注于提高自己和他们的产品时,它才能成功。
发现麻烦的迹象
原文:https://www.studytonight.com/scrum-framework/sign-of-trouble
就像传统项目一样,scrum 项目也会时不时地遇到麻烦。以下是一些特定于 Scrum 的技术,用于查找项目的潜在问题:
- 未达到目标:持续检查已完成的工作是否与计划相匹配,在 Sprint 阶段结束时,您没有任何剩余的功能添加到产品 Backlog 中。这就是著名的雪耕。这类似于第一次 Sprint 的结束和第二次 Sprint 的开始,此时您正在修改评估以匹配团队生产力。但是,如果这种情况在每次 Sprint 结束时继续发生,您必须召集团队讨论并理解为什么会发生这种情况,并采取适当的行动。
- 沟通不畅导致产品错误:问题的另一个值得注意的指标是团队经常生产某个特性的片段并将其扔掉。这可能是因为开发的功能被证明是低优先级的,不是必需的或不正确的,或者需要根据收到的新信息进行修改。这些问题的主要原因通常与业务代表没有提出正确的问题来理解业务问题有关。或者客户不理解您试图构建什么,或者您没有关于真实业务需求的准确信息。
如果您认为这些都是可能的,那么您应该与客户一起进行产品审查,以了解问题的根本原因。
根据客户在评审期间的输入,您应该适当地修改产品 Backlog。
避免麻烦的另一个重点项目是仔细观察团队出席会议的情况。你的核心团队成员是否都出席并参与了日常团队会议和后续活动?一个人偶尔精神或身体上的缺席可能有合理的原因,但反复缺席可能是问题的迹象。
在寻找 Scrum 问题点时,最后一个要考虑的问题是,你是你看到的所有问题的解决者吗?成功的 Scrum 团队是自我组织和自我管理的。所以你要有信心,一定要相信你的团队成员,给自治者留一些发挥作用的空间。这意味着要抵制住一直做修理工人的诱惑。
敏捷方法是强大的,并且能带来很好的结果。对常见故障点的仔细监控有助于确保您成功交付业务价值。
关闭项目
原文:https://www.studytonight.com/scrum-framework/closing-the-project
您即将结束项目,您必须全神贯注地完成这项工作,以理解并记录整个项目的经验教训。
在 scrum 术语中,这被称为回顾。你可以邀请更多的利益相关者参加回顾会,严肃地看待这个项目。一旦项目回顾完成,您现在可以开始项目的最终收尾。
基于所有必需的特性都已经实现的条件,您已经达到了项目中的这一点。
由于你已经在这个项目上花费了时间和资金,在结束这个项目之前,你还有一些额外的事情要考虑。您需要查看 Backlog 清单,并与业务部门合作,以了解剩余功能的重要性。此外,您还需要了解企业是否希望实现新功能。
如果 Backlog 特性集很重要,并且有额外的新特性需要考虑,那么如果能够获得资金,就有可能保证一个新项目。如果 Backlog 包含较低优先级的特性,则可能不会启动新项目。
在这种情况下,需要将 Backlog 转移给能够实现这些更改的人。企业可能想采取的另一种方法是,让我们拭目以待。如果 Backlog 很重要,但他们现在没有很多新功能,那么企业可能需要等待几个月来确定新功能是否出现,新项目是否有保证。无论如何,将 Backlog 清单还给企业是非常重要的,这样他们就可以维护该清单,直到做出未来的决定。
您可以关注项目的整体有效性,而不是项目开始以来发生的所有细节,并可以反思您作为个人和企业所做的改进。
Drools
基础
Drools 简介
原文:https://www.studytonight.com/drools/introduction-to-drools
企业系统通常有多层。从上到下分别是:表示层、业务逻辑层、持久层。中间层——业务逻辑代表应用的核心,所有的业务流程和决策都发生在这里。
我们有很多涵盖用户界面和服务层方面的框架,但是没有成熟的框架/工具来处理业务逻辑层。
此外,构建越来越复杂的系统的需求也在增加。我们正在努力实现各种业务流程的自动化,并实施复杂的业务决策。然而,使用传统的编程语言如Java
不能很好地表示这些过程和决策,因此业务层也需要一个框架/工具,这就产生了Drools (Rule Engine)
。
Drools
是 JBoss Enterprise BRMS 产品自 2005 年联合以来的一部分,是一个业务规则管理系统(BRMS) 和用Java
编写的规则引擎,实现并扩展了Rete pattern-matching algorithm
。现在我们来谈谈什么是Rule Engine
。
Drools:什么是规则引擎
很简单,这是一个我们可以评估业务规则的地方。没有它,我们的规则将被卡在纸上,我们没有办法把它们输入我们的系统。
A Rule Engine
是一个软件,它有一些知识,能够利用这些知识来执行结论。规则引擎是可插拔的软件组件,将业务规则与应用代码分开。规则引擎告诉你在任何情况下该做什么,而不是怎么做。
用
Drools
的技术语言,我们评估规则引擎中的所有规则。
对于所有微软 Outlook 用户来说,很容易联想到一个规则。它与上面描述的相同,当主题包含 Jboss 规则时,然后采取特定的动作。因此,当满足条件的“何时”部分时,规则的“然后”部分被触发并执行。
什么是 Drools?
Drools 是一个写在Java
的业务逻辑集成平台(BLiP) 。这是一个开源项目,但是也有社区和企业版本的产品。Drools 有助于将业务层与应用层隔离开来。规则被写入.drl
文件(域规则语言文件)
逻辑,在我们的例子中是规则,是业务知识的一部分,
When some conditions are true then do something
Drools 分为两个主要部分:
Authoring:
包括规则文件(.DRL)
的创建,规则文件包含被输入到解析器的规则。解析器检查规则的正确语法,并产生一个中间结构描述规则。Runtime:
创建工作记忆并处理激活,这意味着如何将规则加载到引擎以及如何执行它们。
Drools:传统方法的问题
原文:https://www.studytonight.com/drools/problem-trad-approach
Drools 广泛应用于 BFSI 行业(银行、金融服务和保险)。主要原因是不断变化的要求和不断增加的新规则,考虑到 BFSI 行业的波动性。
让我们举一个系统的例子,在这个系统中,交易以XML
的形式来自外部系统,JAXB
被使用并铸造成定制的Java Object
。现在有一些业务规则需要应用于 xml 中的某些参数。
所以代码应该是这样的:
if (trade.getProductInformation() == Product.IRS) {
// do something for IRS (Interest Rate Swap Trade)
}
else if (trade.getProductInformation() == Product.CDS) {
if (trade.getPartyIds() == null) {
// do something else for CDS trades with no Party Id
}
else {
if(trade.getTradeId() ! =null) {
//do something
}
}
}
现在 currrent java 代码处理两种产品类型( IRS 和 CDS )并且应用想要搭载第三种产品 (Bonds) ,每次必须引入新的条件时,上面的 java 代码将很难维护和更改。
救援的解决方案是使用Rule Engine
。使用规则引擎,您的业务逻辑被隔离在规则中,如果有新产品要加入,只需要添加新的规则。
例如:
if Trade( productInformation == Product.IRS)
then do something else for IRS Trade
if Trade( productInformation == Product.CDS)
then do something for CDS trade
现在添加了一个新系统,因此新规则将是:
if Trade( productInformation == Product.BONDS)
then do something for BONDS trade
上面的例子很简单(仅供参考)。当代码中有大量嵌套的if
和else
语句时,使用规则确实有助于轻松地向应用添加新的需求/更改,以及修改现有的规则。
进阶
规则引擎的优势
原文:https://www.studytonight.com/drools/advantage-rule-engine
以下是规则引擎的一些主要优势:
更容易理解
对于业务分析师或新开发人员来说,规则比用 Java 或其他命令式语言编写的程序更容易理解。
提高可维护性
由于规则更容易理解,开发人员可以花更多的时间来解决实际问题。
应对不断变化的复杂性
添加新规则、修改或删除现有规则比更改更容易,例如Java
程序。与命令式实现相比,这对其他规则的影响很小。
灵活性:
它能更好地处理需求的变化或数据模型的变化。更改或重写应用从来都不是一件容易的事情。然而,由于规则带来的形式主义,改变规则比改变一个Java
程序容易得多。
合理的性能
得益于 Drools 背后的 Rete 算法;理论上,系统的性能不取决于规则的数量。随着 Drools 的每一次发布,通过加入 Rete 节点共享、节点索引、并行执行等各种优化,引擎的性能越来越好。所有这些既有利于旧规则,也有利于新规则。
将需求转化为规则
业务规则的表示是一致的。比如,我们拿一些业务规则在Java
中实现。开发人员根据他们的经验,倾向于使用不同的方法来解决问题。我们会发现可能的解决方案会有很大的不同。而有了规则,这种多样化就不那么明显了。就是因为我们表达的是“什么”,而不是“怎么样”。因此,即使是新开发人员也更容易阅读代码。
能够将企业管理应用到我们的规则中
这建立在先前一致表示的优势之上。如果我们有一致的表示,引入适用于我们所有规则的新特性就容易得多(例如,审核、记录、报告或性能优化)
可重用性:
规则保存在一个地方(将业务逻辑与系统的其他部分分离),这意味着更容易重用。例如,假设您已经为您的应用编写了一些验证规则,稍后需要进行一些数据的批量导入,因此您可以简单地在您的批量导入应用中重用验证规则。
紧密建模应用
规则更紧密地模拟应用不变量。命令式的解决方案倾向于根据所选择的算法,在操作上强加任意的并且经常是不必要的排序。这就隐藏了应用的原始不变量。
统一
Drools 平台带来了规则和流程的统一。从进程调用规则很容易,反之亦然。
重新部署
甚至可以在不停止整个应用的情况下更改/重新部署规则和流程。
Drools:何时不使用规则引擎
规则引擎有很多优点,但这并不意味着它可以解决所有的应用。不是灵丹妙药适合业务层所以要明智使用。
以下是需要思考的要点:
- 如果你的项目很小,可能少于 T2 的 20 条规则,那么规则引擎可能是一个过度杀伤。但是,做决定之前要三思,因为很多系统都是从小处着手,但是随着更多需求的实现,突然变得不可收拾。
- 如果你的业务逻辑是定义明确的或者静态的,不经常变化;您不需要在运行时更改规则。
- 如果你的规则是简单的、独立的,通常只跨越一个单一的对象(例如,检查一个用户的年龄小于 21 岁)。你不需要一个规则引擎如果在伪代码中,你没有超过两个嵌套的 if-then 语句。同样,请仔细考虑这一点,因为每个系统的复杂性都会随着时间的推移而增加。
- 如果你最关心的是性能。您是否正在实现一些算法,您希望对其执行进行精确控制?你有记忆受限的环境吗?
- 如果你的项目是一次性的努力,并且它永远不会被再次使用或者随着时间的推移而被维护。
- Drools 有一个学习曲线。因此,开发人员必须了解语法和规则的执行。
为了更详细地阐述这一点,比如一个贷款授予应用,其中的规则是有限的,它们不会随着时间的推移而改变,或者在这类应用中没有添加新的参数或字段。可以改变的是可以从静态最终字段中读取的利率。
第二个例子,比如一个库管理应用,在设计应用时,有一组固定的规则,一旦实现,它们就不会频繁改变,或者根本不会改变。因此,在这种系统中,不使用Drools
是明智,因为这对性能和控制没有好处。
如果您打算使用每 3 个月就有新监管机构加入的交易应用,以及监管您的应用的新法律/规则和每天被告知要实施的新规则,并且更改非常频繁,建议使用 Drools 。
如何在 Eclipse 中添加 Drools 插件
安装 Drools 插件的先决条件:
- Java 1.5(或更高)SE JDK。
- Eclipse 4.2 或任何版本以及 Drools 插件。
由于 Drools 是用Java
编写的 BRMS(商业规则管理系统),因此我们将使用 eclipse 进行演示。下面是在 eclipse 中添加插件以使用 Drools 的步骤:
从以下链接下载二进制文件:
http://download.jboss.org/drools/release/5.3.0.Final/T3】
把它解压到你的硬盘上。然后启动 eclipse,转到帮助- >安装新软件
点击添加
单击本地并选择”.../binary/org . drools . updatesite "
选择 Drools 和 jBPM ,点击下一步
再次点击下一步
点击“我接受许可协议条款”,点击完成
然后软件安装开始:
安装成功后,您会看到一个弹出窗口
点击是
一旦 eclipse 重启,然后转到窗口- >首选项
你可以在你的喜好下看到Drools。你的 drools 插件安装现在完成了。
如何创建 Drools 运行时
原文:https://www.studytonight.com/drools/create-drools-runtime
Drools Runtime 需要告诉编辑用特定版本的 drools jar 运行程序。你可以用不同的Drools Runtime
运行你的程序/应用。
点击 Windows - > 首选项 - > Drools - > 已安装 Drools 运行时
然后点击添加
然后点击创建一个新的 Drools 运行时按钮
给出路径直到二进制文件夹,在那里你已经下载了droolsjbpm-tools-distribution-5 . 3 . 0 . final . zip
点击确定并给出Drools Runtime
的任何名称。drools 运行时被创建。
你好世界 Drools 程序
要创建一个基本的 Drools 程序,打开 Eclipse
转到文件 - > 新建 - > 项目
选择Drools 项目。给这个项目起一个合适的名字。例如:第一个 Drools 程序
下一个屏幕显示选择一些文件,你想要在你的第一个 drools 项目。
选择前两个文件。第一个文件是.drl
文件(Drools Rule File),第二个是 java 类,用于加载和执行 HelloWorld 规则。
点击下一步 - > 完成。
一旦你点击完成,一个 FirstDroolsProgram 项目将在你的工作空间中创建。
打开 java 类,然后右击并作为 java 应用运行。您可以看到如下输出:
我们将在下一节之后解释程序,让我们首先解释规则引擎的基本术语。
Drools 中使用的不同术语
在本教程中,我们将介绍 Drools 中使用的一些重要术语。这对初学者来说是很好的了解,这样你就可以开始理解 Drools 世界中的各种术语了。
-
Rules:
Rules
are the heart of the Rule Engine. In rules you specify the condition and then the execution part of the condition. Below is the syntax of the rule in drools: -
事实:发射规则的物体被称为
Facts
。它可以是一个简单的 Java POJO,也可以是一个复杂的对象。 Java 对象是 Drools 中事实的同义词 -
Session:
Knowledge Session
在 Drools 中是触发规则的核心组件。知识会话保存所有规则和其他资源。Knowledge Session
是从KnowledgeBase
创造出来的。为了触发规则,事实被插入到会话中,并且当满足特定规则的条件时,随后的规则被触发。Session
有两种类型:
a)无状态知识会话:当规则被触发时,无状态知识会话不会跟踪事实的变化。简单地说,一旦我们在会话中插入了所有事实并触发了所有规则,那么这些规则就不能在更新的事实上触发。打个比方,类似于网络应用,我们不跟踪会话。
b)有状态知识会话:在有状态知识会话中,一旦所有事实被插入并且规则被触发,并且一个规则正在更新事实并且发布事实的更新,另一个规则也可以被触发,因为事实仍然在会话中。类似于在网络应用中,直到会话激活,您添加到购物车的所有项目都是可见的。
-
仓库:这是一个管理规则、流程和内部类型集合的界面。在
Drools
中,这些通常被称为知识定义或知识 -
议程:这是一个逻辑概念。议程是规则等待被触发的合乎逻辑的地方。
-
激活:当时规则的一部分。
Activations
被放置在启动适当规则的议程中。
高级
Drools:规则编写或语法基础
如果你看到写在 FirstDroolsProgram 项目(Sample.drl)中的默认规则,有很多keywords
被使用。现在让我们一个一个解释:
- 包:每个规则都以包名开头。该包充当规则的命名空间。创建规则资源时,必须定义包名。包中的规则名称必须是唯一的。规则中的包类似于
Java
中的包。当您通过新建- >规则资源- > 创建新规则时,您需要在下面的窗口中提到规则名称和包名称。
- 进口对账单:进口对账单也类似
Java
。所有的 FACTS 类和任何助手类都需要被导入,这样规则才能起作用。例如:上例中的com.sample.DroolsTest.Message;
。
- 规则定义:规则定义由一些特定于
keywords
的 Drools 组成。帖子中你已经添加了插件,你可以看到 drools 特定的红色关键字。在上面的例子中,然后结束规则是不同的关键字。
规则关键字后面必须跟一个逻辑规则名。
时关键字后面必须跟一些条件。
那么关键字必须有结果部分,如果满足当条件。
There are lot of other keywords which will be covered in further sections.
- 全局变量:用全局你定义全局变量。它们用于使应用对象对规则可用。通常,它们用于提供规则使用的数据或服务,尤其是规则结果中使用的应用服务,并从规则中返回数据,如规则结果中添加的
logs
或values
,或用于规则与应用交互。
现在让我们带您浏览一下 Java 文件中用于加载 drools 和执行规则的术语。
Drools:规则语法
Drools 规则资源(DRL) 有不同的语法,涵盖了以下部分的语法:
Drools:规则中的条件
一个规则可以包含许多条件/模式:
- 学生(id == 001)
- 员工(姓名= =“Vivek”)
以上条件检查学生证是否为 1 ,员工姓名是否为维维克。
Drools:规则中的变量
Drools 中的变量名以$
美元符号开头。
$student : Student()
$student
是学生()班级的变量。
这类似于 java 中的Student student = new Student()
。Drools 可以处理所有的原生 Java 类型,甚至Enum
。
Drools:规则中的注释
在 Drools 5.x 中,#
或//
可以作为单行评论
对于多行注释:
/*
Another line
*/
Drools:规则中的函数
功能是一个便利功能。它们可以用于条件和后果。如果要对规则的 then 部分进行修改,可以调用一个普通的静态 java 助手函数。
function double calculateAreaofSquare(double value)
{
return value * value;
}
Drools:方言
方言指定任何处于条件或结果的代码表达式中使用的语法。默认值为Java
。Drools
目前还支持一种叫做mvel
的方言。
默认的方言可以在包级别指定如下:
package org.mycompany.somePackage
dialect "mvel"
Drools:MVEL 方言
mvel 是一种基于 Java 的应用的表达语言。mvel
支持字段和方法/getter 访问。它基于 Java 语法。
Drools:无循环属性
此属性通知规则引擎,对于每个匹配的事实,规则只能激活一次。如果规则中有一个通用条件,那么应该使用这个属性来避免无限循环的情况。
Drools:突出
Salience
是规则语法的一个非常重要的特征。
冲突解决策略使用它来决定首先触发哪个规则。如果有两个规则,并且两个规则都满足条件,则使用显著性来确定规则触发的顺序。它有一个属性,该属性接受任何返回 int 类型数字的表达式(正数和负数都有效)。该值越高,冲突解决策略就越有可能启动规则。
salience ($account.balance * 5)
salience 100
默认显著性值为 0 。当只给某些规则赋值时,我们应该记住这一点。在规则语法中还有很多其他特性/参数,但是我们已经讨论了重要的特性/参数。
Drools:规则结果关键字
规则结果关键字是指在规则的“然后”部分使用的关键字。
-
修改:可以在规则的随后部分修改事实的属性。
-
插入:基于某些条件如果为真,可以将新事实插入规则引擎的当前会话。
-
收回:如果规则中的特定条件为真,并且您不想对该事实采取任何其他行动,则可以从规则引擎中收回该特定事实。
注意:在规则结果中包含条件逻辑(if 语句)被认为是非常糟糕的做法。大多数时候,应该创建一个新的规则。
Drools 程序示例
原文:https://www.studytonight.com/drools/sample-drools-program
这里我们有一个 zip 文件中的示例 Drools 程序,在前面的课程中也有解释。
点击下载: 样本 Drools Zip
如何从.drl
文件中调用外部函数
原文:https://www.studytonight.com/drools/external-function-drl-file
让我们演示如何从DRL
文件中的 java 文件调用静态函数。在同一个包中创建一个类Utility.java``com.sample
public class Utility {
public static void writeHello(String name) {
System.out.println("HELLO" + name + "!!!!!!");
}
}
然后我们在 drl 文件中添加导入语句,从 drl 文件中调用writeHello
方法。同样,我们在使用的 drl 文件中添加了语法
此场景的用例:
以下是用例的逐步解释:
- 很多时候你需要计算你的对象的参数,这些参数是你在 DRL 的中使用的,或者为此你需要检查特定的变量是某个静态数据的一部分还是某个静态配置的一部分,基于这个决定你想要执行你的规则, 因此,在这些地方,最好在您的
DRL
文件或您的Utility
类中调用一个外部函数,以便可以在这些函数中进行处理,并且规则可以作用于您的函数的输出。 - Drools 主要是为业务层准备的,即评估如果满足特定条件下下一步该做什么,因此如果特定规则需要的话,处理部分可以在功能上完成,从而给出规定。
- 另一个例子是,Java 是一种面向对象语言,但它仍然允许您编写静态/助手函数来进行一些计算,并使用静态方法,而无需启动任何对象。它违背了面向对象的编程概念,但是我们仍然可以直接调用方法而不创建对象,所以类似地 Drools 也提供了这个特性。
如何调试 Drools 项目
有不同的方法来debug
一个 Drools 的项目。
在本教程中,我们将学习需要编写一个实用程序类来让您知道哪些规则被触发或激发。
通过这种方法,我们可以检查在 drools 项目中触发了哪些规则。
这是我们的实用类:Helper.java
package com.sample;
import org.drools.spi.KnowledgeHelper;
public class Helper {
public static void help(final KnowledgeHelper drools, final String message) {
System.out.println(message);
System.out.println("\nrule triggered: " + drools.getRule().getName());
}
public static void helper(final KnowledgeHelper drools){
System.out.println("\nrule triggered: " + drools.getRule().getName());
}
}
第一种方法 help
打印触发的规则以及一些额外的信息,您可以通过 drl 文件将这些信息作为字符串传递。
第二个规则 helper
打印特定规则是否被触发。
Maven
Apache Maven 教程
Maven 简介
Maven 是一个简单的构建自动化工具,基本上用于 java 项目。Maven 也被定义为一个全面的项目管理工具。它旨在为开发人员提供一个完整而详细的应用构建生命周期框架。
Maven 还简化了开发人员检查构建状态、生成报告(基本上是 javadocs)以及设置自动化构建过程并对其进行监控的任务。
通过使用 maven,源代码编译、分发、文档、与不同团队的协作以及其他重要任务变得非常容易。
Maven 旨在描述 2 件重要的事情:
- 软件是如何构建的?
- 项目在独立或分布式环境中关联的依赖项、插件和概要文件。
maven 还可以用于构建和管理使用 C#、ruby 和其他编程语言编写的项目。
马文历史
Maven 最初由雅加达涡轮机项目设计和开发。后来,阿帕奇团队开发了 Maven,以支持开发&一起构建多个项目,发布这些项目,部署它们并生成报告。
任何 maven 项目的 JARs/WARs 都可以在任何分布式环境中共享。
使用 Maven 相对于使用 Ant 的优势
- 管理依赖关系。
- 配置上的约定-配置非常少
- 可以实现多次/重复构建。
- 专注于自动化。
- 插件管理。
- 测试-运行 JUnit 和其他集成测试套件的能力。
- 使开发过程透明。
- 提供检查每个构建的状态。
- 避免不一致的设置。
- 项目间标准统一的基础设施。
设置 Maven 环境
Maven 是一个方便的工具,可以快速设置,并且可以在最多 10 分钟内为任何 java 项目做好准备。此外,maven 可下载包的重量也很轻。按照下面提到的步骤在 windows 环境中下载和设置 maven。
设置 Maven 的步骤 1
从http://maven.apache.org网站下载最新版本的 maven。
注:任何高于 3.2 的 maven 版本都要求 JDK 版本达到 1.6 及以上。
设置 Maven 的步骤 2
一旦下载成功。解压缩下载的 maven zip,并将其放入包含所有 java 相关工件的驱动器中。例如D:\ Java \ Apache-maven-3 . 2 . 5,万一你下载了任何其他最新版本,除了版本可能不同,但这不是问题。
设置 Maven
现在我们需要设置类路径 Java (JAVA_HOME) 和 Maven (M2_HOME) 。如果您已经设置了 JAVA_HOME,那么您只需要为 Maven 设置 M2_HOME。请确保已经安装了所需版本的 jdk。
现在编辑系统变量中的变量路径,以包括 JAVA_HOME 和 M2_HOME。
设置 Maven
如果以上步骤成功执行,那么我们就完成了 maven 工具的安装和设置过程。现在,在最后一步中,我们将验证相同的内容,并相应地确保一切正常。
只需从开始 - > 命令提示符打开命令提示符,在命令提示符中键入 maven 命令mvn -version
并按回车键。它将显示如下所示的结果,并确认我们的 maven 设置成功并完成。
什么是 POM?
描述 maven 项目中的 POM 最简单的方法是,它只不过是任何 maven 项目的核心元素。基本上,任何 maven 项目都由一个名为 pom.xml 的可配置文件组成,它代表缩写项目对象模型。这个 pom.xml 将总是位于任何 maven 项目的根目录中。这个文件代表了 maven 中最基本的单元。
pom.xml 基本上包含了已建或待建项目的相关信息。它包含了关于项目中包含的配置细节、依赖关系和插件的所有必要信息。简单来说,它包含了项目构建生命周期的细节。
以下是可以在 pom.xml 文件中处理的一些配置:
- 项目中使用的依赖项(Jar 文件)
- 使用的插件(报告插件)
- 项目版本
- 参与项目的开发人员
- 邮寄名单
- 报告
- 构建配置文件
示例 Pom.xml 文件
简单 java 项目的典型 pom.xml 如下图所示。
一个 pom.xml 总是从名为<project>
的根元素开始,在这个元素下所有其他需要的配置都将被创建。开发人员应确保在定义 pom.xml 文件之前定义以下元素列表,这些元素被称为 maven 坐标:
- groupId -正如名称本身所示,这是一个对组织中的任何项目都是唯一的 Id。
- artifactId -即使名字写为“Id”,这也基本上是定义了任何项目的名称。
- 版本 -该元素用于导出任何项目的版本,以便在项目开发阶段进行重大变更/实现时将版本分类。
每当执行项目任务时,maven 都会扫描 pom 中的条目。Xml 文件。这将使 maven 能够读取所有配置、定义的构建概要文件、配置的仓库以及所有其他重要细节,然后相应地执行任务。
注意:实际上 pom.xml 在 maven 1 中更早就被用在 project.xml 的名称中。随着 maven 2 版本的推出,它被重命名为 pom.xml
超级聚甲醛
所有 maven 项目的 pom.xml 文件总是扩展超级 pom.xml 文件。这个超级 pom.xml 基本上定义了所有 maven 项目共享和使用的一组默认配置。这个超级 pom.xml 不需要开发人员编写。这将是 maven 安装的默认设置。
一个典型的超级 pom.xml 可以在附件中找到。点击下面的链接下载。
马文的目标
maven 中的目标只不过是导致编译、构建和管理项目的特定任务。maven 中的一个目标可以与零个或多个构建阶段相关联。唯一重要的是在 pom.xml 中为给定项目定义的目标的顺序,因为执行的顺序完全取决于定义的目标的顺序。
什么是 Maven 中的仓库?
对于 maven 来说,要下载构建和依赖项(jar 文件)以及其他作为任何项目的一部分配置的插件所需的工件,应该有一个放置所有这些工件的公共位置。这个公共共享区域在 maven 中被称为仓库。
在 maven 中,仓库分为 3 个主要类别,如下所示:
- 本地仓库
- 远程仓库
- 中央仓库
本地仓库
驻留在我们本地机器上的仓库从远程/中央仓库下载并准备使用。可以在标签<localRepository>
下的 maven 文件夹的 settings.xml 文件中配置保存/放置本地所有依赖项的文件夹。
<settings
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>D:/m2repo</localRepository>
</settings>
远程仓库
顾名思义,这个仓库位于远程服务器中,可以通过使用不同的文件传输协议(如file://
或http://
)来访问。远程仓库将用于下载和上传依赖项和工件。
<repositories>
<repository>
<id>remote.repository</id>
<url>http://download.ogrname.com/maven2/</url>
</repository>
</repositories>
中央仓库
这是 maven 社区提供的仓库。这个仓库包含了许多 java 项目常用/必需的库。基本上,如果开发人员想要使用这个中央仓库,就需要互联网连接。但是,访问这个中央仓库不需要任何配置。
<repositories>
<repository>
<id>central.repository</id>
<url>http://repo1.maven.org/maven2/</url>
</repository>
</repositories>
本地和远程/中央仓库的组织
在下图中,您可以看到本地和远程/中央仓库的组织。
Maven 如何搜索依赖项?
基本上,当 maven 开始执行构建命令时,maven 开始搜索依赖项,如下所述:
- 它在本地仓库中扫描所有配置的依赖项。如果找到,则继续进一步执行。如果在本地仓库中找不到已配置的依赖项,它将扫描中央仓库。
- 如果在中央仓库中找到了指定的依赖项,那么这些依赖项将被下载到本地仓库中,以供将来参考和使用。如果没有找到,maven 就开始扫描远程仓库。
- 如果没有配置远程仓库,那么 maven 将抛出一个异常,说找不到依赖关系 &停止处理。如果找到了,那么这些依赖项将被下载到本地仓库中,以供将来参考和使用。
Maven 构建生命周期
Maven 构建生命周期
原文:https://www.studytonight.com/maven/maven-build-life-cycle
什么是构建生命周期?为了执行任何 maven 项目的任务和目标而定义的步骤序列在 maven 中被称为构建生命周期。Maven 2.0 版本基本上是一个面向构建生命周期的版本,并明确表示这些步骤已经被很好地定义,以在构建生命周期成功执行后获得期望的输出。
Maven 附带 3 个内置构建生命周期,如下所示:
- 清洁 -该阶段涉及项目的清洁(对于全新的构建&部署)
- 默认 -此阶段处理项目的完整部署
- 站点 -这个阶段处理生成项目的 java 文档。
现在,我们将深入研究上述内置构建生命周期中涉及的详细阶段。
Maven:构建清洁阶段的生命周期
如上所述,这个清理阶段用于清理项目,并为新的编译和部署做好准备。用于相同目的的命令是 mvn 后清理。调用此命令时,maven 通过在内部执行以下命令来执行以下任务:
- mvn 预清洗
- mvn 清洁
- mvn 后清洗
这个 maven 的清理是一个目标,在执行它时,通过删除所有编译的文件来清理输出目录(目标文件夹)。
注意:无论何时调用任何生命周期的 maven 命令,maven 都会一直执行到调用阶段。例如,当调用“mvn 清理”时,maven 将只执行阶段清理。但是,没有调用编译/部署/站点阶段。
Maven:构建生命周期(默认)
下面是 maven 构建生命周期(默认)中的阶段列表。这些阶段将通过 maven 命令调用。
| 生命周期阶段 | 描述 |
| 生效 | 考虑到构建所需的所有信息,验证并确保项目是良好和完美的 |
| 生成源 | 生成任何源代码以将其包含在编译过程中 |
| 过程源 | 处理源代码,以防需要应用某些过滤器 |
| 生成源 | 生成包含包的任何源代码 |
| 流程-资源 | 将资源复制到目标文件夹并准备打包的过程 |
| 编制 | 项目源代码的编译。 |
| 过程类 | 为编译生成的类文件执行字节码增强 |
| 生成测试源 | 复制和处理测试目标目录中的资源。 |
| 测试编译 | 编译测试目标目录中的源代码 |
| 试验 | 使用合适的测试框架执行/运行测试。注意:这些测试用例不考虑打包和部署 |
| 准备包装 | 在发送到最终包装前执行任何最终更改/验证。 |
| 包裹 | 将成功编译和测试的代码打包成一些可分发的格式——JAR、WAR、EAR |
| 集成前测试 | 在执行集成测试之前执行操作。这可能需要为应用设置一些环境更改。 |
| 集成测试 | 将应用部署到可以运行集成测试的环境中。 |
| 整合后测试 | 基本上,清理集成前测试阶段的环境。 |
| 核实 | 执行质量检查,并确保符合要求的标准 |
| 安装 | 在本地仓库中安装应用。任何其他项目都可以将此用作依赖项。 |
| 部署 | 最终的包将被复制到一个远程仓库中,可能作为一个正式的版本,也可以提供给其他开发人员。 |
Maven:站点生命周期(站点)
除了清理、编译源代码、构建应用的可部署格式之外,maven 还有比这些阶段做得更多的阶段。这个阶段是 maven 提供的重要特性之一,它生成任何 java 项目的详细文档。
本项目文件包含下列专用阶段:
- 现场前
- 位置
- 事后网站
- 现场部署
maven 中用于为给定项目生成 javadocs 的命令是“ mvn site ”。基本上,当这个命令被调用时,maven 会调用文档生成和其他报告生成插件。
Doxia 基本上是 maven 用于内容生成的框架。这会以静态和动态方式生成内容。
在 Maven 中构建概要文件
原文:https://www.studytonight.com/maven/build-profiles-in-maven
maven 中的 Profile 只不过是允许为特定环境定制构建的元素子集。概要文件对于不同的构建环境也是可移植的。
构建环境基本上意味着为生产和开发实例设置的特定环境。当开发人员在开发阶段工作时,他们打算使用生产实例中的数据库,对于生产阶段,将使用实时数据库。
因此,为了配置这些实例,maven 提供了构建概要文件的功能。可以配置任意数量的构建配置文件,也可以覆盖pom.xml
中的任何其他设置
这些定义的概要文件能够在构建期间修改 pom.xml。即为开发和生产实例配置单独的环境。根据传递的参数,相应的配置文件被激活。例如可以为开发、测试和生产阶段设置配置文件。
Maven:构建概要文件的类型
下表显示了 Maven 中构建概要文件的类型:
| 构建配置文件类型 | 定义于 |
| 每个项目 | pom.xml 文件 |
| 每个用户/开发人员 | maven settings . XML(% USER _ HOME %/. m2/settings . XML) |
| 全球的 | Maven 全局设置. XML(% M2 _ HOME %/conf/settings . XML) |
马文:构建可移植性
如上所述,可以根据给定项目的需求设置不同的环境。因此,通过这种方式,给定项目的可移植性可以得到保护和有效处理。
构建可移植性可以被定义为一个项目的能力,它可以在不同的环境中成功地编译和部署,这也涉及到为相同的环境应用不同的环境配置。任何可移植的项目应该总是倾向于在没有任何属性定制的情况下工作。
任何可移植的项目都会消除与项目相关的复杂性和问题。
马文:激活配置文件
以下是激活或触发 maven 构建概要文件的方法:
- 显式使用命令
- Maven 设置
- 基于环境变量
- 操作系统设置
- 存在/缺失的文件
Maven:显式使用命令
<profiles>
<profile>
<id>test</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using app.test.properties</echo>
<copy file="src/main/resources/app.test.properties"
tofile="${project.build.outputDirectory}/env.properties"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Maven 设置示例
下面是一个基本的 Maven 设置示例:
<settings
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<mirror>
<id>com.testorg.companyname</id>
<name>Internal Artifactory Maven repository</name>
<url>http://repo1.maven.org/maven2/</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
<activeProfiles>
<activeProfile>test</activeProfile>
</activeProfiles>
</settings>
基于环境变量
<profile>
<id>test</id>
<activation>
<property>
<name>env</name>
<value>test</value>
</property>
</activation>
</profile>
操作系统设置
<profile>
<id>test</id>
<activation>
<os>
<name>Windows 7</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
</activation>
</profile>
存在/缺失的文件
<profile>
<id>test</id>
<activation>
**<file>**
<missing>
target/generated-sources/axistools/wsdl2java/com/orgname/group
</missing>
**</file>**
</activation>
</profile>
Maven 插件
maven 中的 Plugin 是一个重要的特性,基本上用于在不同的项目中重用公共的构建逻辑。插件是执行所有任务的工具,比如编译代码、用 junits 测试代码、创建 jar/war/ear 文件和项目文档。maven 中的大部分工作都是使用插件完成的,因为依赖项(jar 文件)只在执行任务时添加到类路径中。
因此,maven 只不过是一个插件执行框架,在这个框架中,每项任务都是通过使用插件来完成的。
下面是 maven 中插件处理的基本任务列表:
- 创建 jar/war/ear 文件。
- 代码编译
- 代码的单元测试。
- 项目文件
任何插件的行为都可以通过使用每个插件目标(也称为 Mojo)公开的一组参数来改变。maven 中的一个 Mojo 只是一个目标,基本上指定了一个目标的元数据——目标名称、它适合哪个阶段以及目标期望的参数。
微型插件的类型
maven 中基本上存在两种重要类型的插件,如下所示:
- 构建插件 -基本上这些插件将在构建阶段执行。这些插件是在 pom.xml 的
<build>
元素下定义的 - 报告插件 -这些插件在站点生成(报告或 javadocs 生成)阶段执行。这些插件将在 pom.xml 的
<reporting>
元素下配置
一些常见的 Maven 插件
以下是使用 maven 构建的任何 java 项目中常用插件的列表:
| 插件名称 | 描述 |
| 干净的 | 用于删除目标目录,以便清理早期的构建工件 |
| 编译程序 | 编译 java 源文件 |
| 准不会有错的 | 执行 Junit 测试并生成报告。 |
| 冲突 | 构建项目的 jar 文件 |
| 战争 | 建立项目的战争档案 |
| 文档 | 生成项目的 javadocs |
| 蚂蚁 | 运行在构建的任何阶段指定的一组 ant 任务 |
pom.xml 中的示例插件
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.orgname.orggroup</groupId>
<artifactId>project</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>id.clean</id>
<phase>clean</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Clean Phase</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
- 每个插件可以有多个目标来执行不同的任务。
- 任何插件的启动阶段都可以定义。
- 任务可以被配置为与插件定义的每个目标相关联。
Maven 插件的优势
- 更详细更好的架构。
- 有管理的生命周期
- 多语言的实现
- 公共构建逻辑的可重用性。
- 完全用 java 编写 maven 插件的能力
在 Maven 中创建您的第一个项目
原文:https://www.studytonight.com/maven/project-creation-in-maven
在前面的课程中,我们已经了解了 maven 项目架构以及项目涉及的不同配置。现在,我们将了解如何使用 Maven 创建一个示例 Java 项目。Maven 还可以用来构建和管理使用 C#、Ruby、Scala 和少数其他语言开发的项目。但是,这主要用于 java 项目,所以我们将以 Java 为例。此外,我们将看到当使用 maven 创建时,项目是如何结构化的。
马文原型
Maven 使用原型来创建任何项目。原型只不过是 maven 提供的创建项目的工具。它也被定义为‘一种组织模式,所有其他同类事物都是由它构成的’。
使用原型为开发人员创建项目提供了一种简单而实用的方法,在这种方法中,按照组织级别定义的标准采用最佳实践。此外,原型使开发人员能够快速创建一个项目,并在几个命令内开始运行相同的项目。
为了创建一个新的简单的 maven java 项目,只需在命令行中使用 maven 原型插件。目前列出了 850 多个 maven 原型,以便在不同的框架下创建项目,如 struts、spring、hibernate、web 服务(RESTful/SOAP)和许多其他框架。
让我们用 maven 创建一个简单的项目。打开命令提示符,导航到本地机器中的工作区文件夹(例如 D:\Java\workspace) 。您可以在电脑上的任何位置创建工作区文件夹,或者使用您的工作区(如果已经创建)。然后键入下面的 maven 命令(这是一个单行命令)并按 enter 键。
mvn archetype:generate -DgroupId=com.java.samples -DartifactId=JavaSamples
-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
这个 maven 命令将创建一个 Java 项目,其细节如下:
- groupId 将是 com.java.samples,代表包。
- artifactId 将是 JavaSamples(在构建时,将创建 JavaSamples.jar)
- 原型 ArtifactId 只不过是用来创建这个 Java 项目的模板。
- 交互模式在开发人员知道工件 id 的实际拼写时使用。在上面的例子中,maven-prototype-quick start 是被使用的一个,也是合适的一个。如果开发人员不知道这一点,那么交互模式被设置为
TRUE
,这样它将扫描远程仓库中所有可用的原型。这可能需要更长时间。
上面的命令指示 maven 用maven-原型-快速启动模板创建一个项目。
如果您导航到文件夹 D:\Java\workspace ,将创建一个名为javassimples的新项目,包括 Java 项目的所有基本结构,如下所示:
要查看下面的目录结构,您需要在您的 Eclipse IDE 上创建一个新的 Java 项目,并在那里导入下面的项目。
下表将描述作为项目一部分创建的主要目录。
| 插件名称 | 描述 |
| javassimples | 包含源代码和 pom.xml 的项目的根文件夹 |
| src\main\java | 包含包 com.java.samples 下的所有 java 代码 |
| src \主\测试 | 包含包 com.java.samples 下的所有 java 测试代码 |
| 主资源 | 包含所有资源,如 xml \属性文件 |
在文件夹D:\ Java \ workspace \ JavaSimples \ src \ main \ Java \ com \ Java \ samples下,将默认创建一个名为App.java的示例 Java 文件,该文件将包含一个 print 语句。
package com.java.samples;
/**
* Hello world!
*
*/
public class App
{
public static void main (String[] args)
{
System.out.println("Hello World!");
}
}
并且在文件夹D:\ Java \ workspace \ javassimples \ src \ test \ Java \ com \ Java \ samples下将创建一个示例 Java 测试类(JUnit)AppTest.java
package com.java.samples;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest extends TestCase{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest(String testName)
{
super(testName);
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite(AppTest.class);
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue(true);
}
}
标记为严格测试的测试类代码是在使用 maven 创建示例 java 项目时自动生成的代码。该方法将返回真,测试将在运行后通过。这种方法只是作为一个样本测试。您可以修改此方法或添加自己的测试方法。
此外,测试用例类是一个抽象类,来自这里在示例项目中使用的 Junit API。默认情况下,当创建一个示例 maven java 项目时,也会自动包含这个项目(检查 pom.xml 中 junit 的依赖项)。TestCase 类定义了在一个类中运行多个测试的装置。
开发人员需要添加他们的文件,如上表所述。他们可以根据项目开发的需要自由添加任何新的包。上面说的文件夹结构是根据原型插件定义的。
Maven 中的版本
任何 maven 项目都有两个主要版本:
- SNAPSHOT :这只不过是开发版。新版本的可用性将在每次结账时进行验证,如果需要,还会下载。此版本不允许发布。
- 固定:只下载一次到本地仓库。每当软件发布的主要版本发生时,就会得到这个结果。
构建并测试你的第一个 Maven 项目
原文:https://www.studytonight.com/maven/build-and-test-maven-project
在前面的教程中,我们已经看到了如何使用 maven 原型创建示例 maven 项目,并了解了文件夹结构是如何组织的。现在,我们将看到如何构建一个项目并测试编写的代码。
构建一个 Maven 项目
一旦在项目中完成了编码,就需要编译、构建项目,并使其为部署做好准备。
为此,请打开命令提示符并导航到包含 pom.xml 文件的根项目文件夹。例如 D:\ Java \ workspace \ JavaSimples。现在,输入命令mvn package
并按回车键。该命令将调用 maven 包阶段。
正如这里所解释的,每当 maven 阶段被调用时,它都会按顺序执行直到被调用的阶段。因此,在这种情况下,将执行上述包–验证、编译和测试阶段。
当运行 mvn package 命令时,maven 将验证并编译源代码,执行 junit 测试用例,并根据 pom.xml 文件中标签<packaging>
中给出的指令对其进行打包/捆绑。如果包装被指定为罐子,那么将创建一个带有该包装的罐子。
- 打包的 jar 文件将在项目的目标目录下可用。即D:\ Java \ workspace \ JavaSamples \ target。
- 所有的测试报告(junit 测试细节)都可以在文件夹D:\ Java \ workspace \ JavaSamples \ target \ surefire-reports中找到
要运行 App.test java,请打开命令提示符并导航到文件夹 D:\ Java \ workspace \ JavaSamples \ target \ class,然后输入命令 java com.java.samples.App
要运行测试类(junits),打开命令提示符,从项目的根文件夹中,执行命令 mvn 测试
在 Maven 中管理外部依赖关系
原文:https://www.studytonight.com/maven/managing-external-dependency-in-maven
在上一个教程中,我们了解了如何构建和测试 maven 项目以及用于该项目的命令。在本章中,我们将学习在 maven 中管理项目的外部依赖关系。
如前所述,maven 中所有基本的依赖项列表都是由 maven 仓库处理的,项目在该仓库中下载所需的依赖项。但是,在某些情况下,某些特定的依赖关系可能在 maven 远程和中央仓库中不可用。Maven 仍然通过提供外部依赖管理的特性来解决这个问题。
外部依赖项可以是 sqljdbc.jar 或 log4j。在 maven 中,任何外部依赖项都可以像 pom.xml 文件中的其他依赖项一样轻松配置。因此,让我们看一个简单的例子,将 sqljdbc.jar 作为外部依赖项添加到 maven 项目中。
-
在 maven 项目中创建一个名为 lib 的文件夹。
-
下载 sqljdbc.jar 放入 lib 文件夹。
-
现在,打开项目的 pom.xml ,添加一个新的依赖项,如下图所示:
-
指定组号作为 jar 文件的名称
-
指定 artifactId 作为 jar 文件的名称
-
指定系统的范围
-
指定 jar 文件到项目位置的相对路径。
<dependency>
<groupId>sqljdbc</groupId>
<artifactId>sqljdbc</artifactId>
<scope>system</scope>
<version>1.0</version>
<systemPath>${basedir}\src\lib\sqljdbc.jar</systemPath>
</dependency>
依赖范围
maven 中的依赖范围分为 5 种不同的类型。这些范围中的每一个都控制类路径中可用的依赖项和应用中包含的依赖项。
| 依赖范围 | 描述 |
| 编制 | 这是 maven 中任何外部依赖的默认范围。这些依赖项在类路径中是可用的,并且打包得很好。 |
| 提供的 | 这些依赖项预计将由 JDK 或一个容器提供。最好的例子是 servlet api。这些依赖项在类路径上可用,但在运行时不可用。此外,它们没有包装。 |
| 运行时间 | 这些依赖项不是编译所必需的,而是执行和测试系统所必需的。例如 JDBC 空气污染指数 |
| 试验 | 这些依赖关系只在测试编译和执行阶段需要。 |
| 系统 | 这个范围类似于“提供”。唯一的问题是开发人员需要在本地文件系统上显式地提供 jar 文件的路径。 |
Maven 构建自动化
Maven 构建自动化
原文:https://www.studytonight.com/maven/maven-build-automation
构建自动化是这样一个过程,在这个过程中,每当在工作空间中进行更改时,项目都会随着构建过程一起启动,并且还会确保项目及其相关项目是稳定的(如果项目被任何其他项目使用的话)。
这在软件开发生命周期中非常重要,因为在开发阶段很难管理失败的构建。因此,需要一个过程来始终确保构建的健康状态并保持关注。
考虑这个场景中的项目javassimples。在这里,将编写和测试许多不同 oops 概念的程序。但是,由于编译问题,独立测试每个类总是很困难的,因为它们是在不同的包集合下模块化的。
为了实现这一点,maven 提供了一个功能来实现自动化。考虑一下,开发人员希望在每次签入项目后检查构建稳定性。此外,考虑这个 JavaSamples 项目是另一个名为 CoreJavaTutorials 的项目的依赖项目。因此,维护一个稳定的 JavaSamples 构建是强制性的。
下面提到的是两个相关项目的 pom.xml 文件。
CoreJavautorials 项目
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>CoreJavaTutorials</groupId>
<artifactId>CoreJavaTutorials </artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>JavaSamples</groupId>
<artifactId>JavaSamples</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
javascomples 项目:
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>**JavaSamples**</groupId>
<artifactId>JavaSamples</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
</project>
现在考虑一下对 JavaSamples 项目所做的一些更改。开发人员需要通过在相同的上添加一个后期构建目标来更新 JavaSamples 项目的 pom.xml。
后期构建目标只不过是一个目标,一旦构建成功,它就定义了一组特定的任务。例如,生成 javadocs 是一个后期构建目标。我们将在接下来的教程中研究如何生成 Javadocs。
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>JavaSamples</groupId>
<artifactId>JavaSamples</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-invoker-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>build</id>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
使用 Jenkins 服务器构建自动化
Jenkins Server(点击查看完整 Jenkins 教程 i >)是一款持续集成工具。使用 Jenkins 构建可以自动化,测试构建的健康状态,还可以管理多个构建。这是一个方便的工具,很容易下载,也很容易设置。
设置 Jenkins 服务器
-
从以下链接下载最新的 Jenkins . war:http://jenkins-ci.org/T3】
-
在我们机器的本地网络服务器上部署 Jenkins. war 文件。例如雄猫
-
启动服务器,打开浏览器,点击网址http://localhost:8080/Jenkins
创建新作业并部署构建
点击新建作业链接,如上图所示,为构建自动化配置项目。如下图输入项目详情,点击确定。您必须为 Maven 项目输入名称并选择单选按钮。
在下一页中,填写所有必需的详细信息,如- Description、项目的 pom.xml 路径和其他详细信息,然后单击 save。请查看下面的图片寻求帮助。填写所有信息,点击保存
现在在 Jenkins 创建了一个项目/工作。如下图所示:
如上图所示,点击立即构建选项。这将读取 pom.xml 并拉出最新的代码,执行构建过程并相应地生成 jar/war 文件。
单击内部版本号链接,它会打开内部版本详细信息。点击控制台输出查看构建日志。
检查日志,查看您的项目构建是否成功。
什么是 Maven 快照?
基本上,当开发一个大规模的应用时,这个过程需要在应用中进行一系列的更改,直到它被确认准备好作为最终版本。因为,可能有多个团队在不同的模块集上处理一个应用。
考虑两个团队,A & B 在 2 个不同的模块上工作,并说团队 B 将依赖于团队 A 提供的服务。说团队 A 参与了一些主要的关键修复工作,这些修复将每天进行检查。所以必须通知 B 队,A 队还有一些未完成的工作,A 队还没有发布最终版本,这就是小牛的快照出现的地方。
快照是一个特殊版本,表示正在进行的项目的当前开发副本。对于每个构建,maven 总是检查项目的快照。
因此,每当 maven 找到项目的较新快照时,它都会下载并替换本地仓库中项目的较旧.jar
文件。
快照版本总是会在项目上进行一些更新/更改。此外,快照应该只存在于开发阶段,不会有发布版本。这意味着项目的构建将随时改变,并且它仍在开发过程中。
快照与版本
在 SNAPSHOT 的情况下,Maven 会在每次corejavattorials项目构建时自动获取最新的 SNAPSHOT(数据服务:1.0-SNAPSHOT)。
在版本的情况下,maven 一旦下载了上面提到的版本,比如 javassimples:1.0,那么它就永远不会尝试下载仓库中可用的更新的 1.0。为了下载更新的代码,CoreJavaTutorials 版本将升级到 1.1。
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>CoreJavaTutorials</groupId>
<artifactId>CoreJavaTutorials</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<url>http://maven.apache.org</url>
</project>
在 Maven 中生成 Javadocs
原文:https://www.studytonight.com/maven/generating-javadocs-in-maven
Maven 提供了一个很酷的特性,为一个项目生成 javadocs。每个开发人员都知道,拥有我们项目的代码文档是至关重要的,maven 的这一特性有助于实现这一点。
Maven 使用 maven-javadoc 插件来生成项目的 javadoc。这个插件内部使用JDK \ bin \ javadocs . exe命令生成 javadoc。当使用mvn install
命令部署项目时,它会为项目生成 javadocs。
马文:配置 Javadocs 插件
javadoc 插件可以在 pom.xml 中为任何项目进行配置,如下所示:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
马文:生成 Javadocs
在项目的 pom.xml 中添加了上述插件后,您所要做的就是打开命令提示符,转到项目目录,例如:Java \ workspace \ javassimples,运行命令maven install
。
生成的 javadocs 可以在项目的位置找到:D:\ Java \ workspace \ JavaSimples \ target \ API docs。
使用 Maven 模板创建 Web 应用
在前面的教程中,我们学习了如何使用 maven 原型创建一个简单的 java 项目,也了解了 maven 如何基于所选原型组织项目结构。在本章中,我们将学习如何使用 maven 创建 web 应用项目。
用 maven 创建 web 项目最简单的方法是使用 maven 原型maven-原型-webapp 。只需打开命令提示符,导航到需要创建项目的文件夹。运行下面提到的命令,Maven 将开始执行该命令,并将为基于 web 的应用创建一个完整的项目结构。
mvn archetype:generate -DgroupId=com.sample.webproject -DartifactId=SampleWebApp -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
下面是 maven 使用maven-原型-webapp 插件生成的 web 应用的项目结构。
| 文件夹结构 | 描述 |
| SampleWebApp | 包含源文件夹和 pom.xml 文件。 |
| src/main/webapp | 包含默认 index.jsp |
| src/main/webapp/WEB-INF | 包含 web.xml 文件。 |
| src/main/resources | 包含使用的资源文件。(图像或属性文件) |
使用maven-archetype-webapp
插件生成的默认文件
在任何 Java/J2ee Web 应用中,总会有一个文件驻留在 WEB-INF 文件夹 web.xml 下,这被称为部署描述符文件。该文件主要用于为以下主要因素配置 servlets:
- 拦截来自客户端(浏览器端)的请求,并在请求到达后端资源之前验证它们。
- 用于在响应被定向到客户端之前操纵来自服务器端的响应。
下面是 maven 为 web 应用生成的 pom.xml 。
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample.webproject</groupId>
<artifactId>SampleWebApp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>SampleWebApp Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>SampleWebApp</finalName>
</build>
</project>
利用这个原型,maven 生成了一个名为index.jsp的示例 JSP 文件,其内容如下所示:
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>
构建和部署 Web 应用
只需打开命令提示符,导航到 web app 的根文件夹,发出命令mvn clean package
。该命令将编译、测试并生成项目的 war 文件。
生成警告文件后,将警告文件复制到网络服务器(您使用的任何网络服务器)的目标文件夹中,并启动服务器。您可以通过调用 web 项目的 URL 来测试应用:
http://localhost:8080/
Maven 部署自动化
原文:https://www.studytonight.com/maven/maven-deployment-automation
在上一个教程中,我们学习了如何使用 maven 原型创建一个简单的 web 项目,也了解了 maven 如何基于所选原型组织项目结构。为了测试 maven 创建的 web 应用,我们遵循将应用(war 文件)部署到 web 服务器的手动方式,并对其进行了测试。
在实时项目中,典型的部署过程包括以下活动列表:
- 将代码签入仓库。
- 从仓库中下载源代码。
- 编译和构建应用,并从中生成 jar/war。
- 将生成的 war/jar 放在公共共享网络位置。
- 下载 jar/war 文件并部署到目标服务器
- 此外,应用的文档和版本细节也需要更新。
因为,任何实时项目总是会有多个团队为上述活动工作,所以有时某个特定的步骤可能会被遗漏,这将导致构建和部署过程的失败。
此外,实际观察到,手动处理上述步骤在大多数情况下容易出错。为了克服这个问题,部署过程应该是自动化的,这样就不会有任何干预,并且部署也是成功的。
如何自动化部署过程?
基本上,为了自动化 maven 中的构建和发布过程,将使用 maven 的发布插件。打开项目的 pom.xml ,更新如下:
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample.webproject</groupId>
<artifactId>SampleWebApp</artifactId>
<packaging>war</packaging>
<version>1.0 </version>
<name>SampleWebApp Maven Webapp</name>
<url>http://maven.apache.org</url>
<scm>
<url>http://www.svn.com</url>
<connection>scm:svn:http://localhost:8080/svn/jrepo/trunk/Framework</connection>
<developerConnection>
scm:svn:test/test123@localhost:8080:common_core_api:1101:code
</developerConnection>
</scm>
<distributionManagement>
<repository>
<id>Sample-Web-App-Release</id>
<name>Release repository</name>
<url>
http://localhost:8082/nexus/content/repositories/Sample-Web-App-Release
</url>
</repository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>*maven-release-plugin*</artifactId>
<version>2.0-beta-9</version>
<configuration>
<useReleaseProfile>false</useReleaseProfile>
<goals>deploy</goals>
<scmCommentPrefix>[Sample-Web-App-checkin]</scmCommentPrefix>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
仔细查看 pom.xml ,并观察下面列出的重要标签:
| 标签元素 | 描述 |
| 单片机 | 配置项目的配置管理(在这种情况下,使用 SVN) |
| 仓库 | 成功构建后 WAR/EAR/JAR 文件的存储位置 |
| 插件 | maven-release-plugin
实现流程自动化 |
maven-release-plugin
是如何工作的?
随着 pom.xml 的更新,我们都开始在 maven 中自动化项目的部署过程。但是,在结束这一点之前,了解在后台实际发生了什么使部署过程自动化是至关重要的。
当 maven 调用插件 maven-release-plugin 时,将相应地执行以下任务:
-
mvn 发布:清理 -清理上一次构建的工作空间,并为新的构建进行设置。
-
mvn 释放:回滚 -如果最后一个进程不成功,则恢复/回滚工作空间。
-
mvn 发布:准备 -该任务执行以下操作列表:
- 签出本地工作区中任何未提交的文件。
- 检查并确保没有快照依赖关系。
- 准备发布版本。
- 将 pom 更新为 SCM (SVN/Git/Mercurial/CVS)
- 执行测试用例。
- 执行对配置管理的最终提交。
- 标记代码。
- 增加版本号,并将快照添加为未来版本的一部分。
-
mvn 发布:执行 -从仓库中签出代码,并运行 maven 目标来构建工件并将其部署到仓库中。
使用 Eclipse IDE 和 Maven
原文:https://www.studytonight.com/maven/maven-with-eclipse-ide
Maven 还提供了一个优秀的插件,帮助将 eclipse 和 maven 集成在一起。M2eclipse 是用来集成 maven 和 eclipse 的插件。下面是这个插件的一些主要好处:
- 从 eclipse 启动 maven 构建。
- 推出 maven 目标。
- 管理 eclipse 构建路径的依赖关系。
- 从仓库中自动下载 maven 依赖项。
- 基于图形用户界面(基于向导)创建 maven 项目。
- 所需依赖项的快速修复。
安装m2eclipse
插件
按照下面的链接在您的 eclipse IDE 中轻松安装 m2eclipse 插件。
http://books . sonatype . com/m2 eclipse-book/reference/ch02s 03 . html
在 Eclipse 中创建一个 Maven 项目
下面是在 eclipse 中创建 maven 项目的逐步说明。
-
打开月食。转到文件 - > 新建 - > 项目,通过关键字 maven 搜索,选择 Maven 项目
-
选中复选框创建一个简单的项目,点击下一步。
-
如下图提供组号、人工号、版本、包装的详细信息,点击完成。
-
将创建一个新的项目名称 SampleMavenProject ,如下所示:
马文教程到此结束,希望你有一个很好的学习体验。
Ruby
基础
Ruby 简介
Ruby 是松本由纪弘开发的面向对象编程语言。Ruby 是一种动态编程语言,具有复杂但同时表达语法。Ruby 还有一个核心类库,拥有丰富而强大的 API。
Ruby 的灵感来自其他低级和面向对象的编程语言,如 Lisp 、 Smalltalk 和 Perl ,并且使用 C 和 Java 程序员容易学习的语法。
Ruby 是一种动态的开源编程语言,注重简单性和生产力,它有一个优雅的语法,易于阅读和编写。
虽然用 Ruby 编程很容易,但它不是一种简单的语言。
Ruby 的特性
-
面向对象:Ruby 中的每一个值都是一个对象,甚至是最原始的东西,比如字符串、数字,甚至是真假。所以,Ruby 是一种纯面向对象的语言。每个对象都有一个类,每个类都有一个超类。
-
动态: Ruby 是一种非常动态的编程语言。Ruby 程序不像 C 或 Java 程序那样编译。程序中的所有东西都是由运行时的代码构建的。程序也可以在运行时修改自己的定义。
-
单例类:Ruby 中的每个对象都有两个类:一个
regular class
和一个singleton class
。一个对象的单例类是无名类,它唯一的实例就是那个对象。单例类是自动创建的,让 Ruby 变得简单而优雅。 -
元编程:Ruby 中的一切都是对象。您可以在程序运行时使用它们来了解它们,甚至修改它们。这种技术被称为元编程。
-
灵活性:可以将方法添加到现有的类中而不进行子类化,可以重载操作符,甚至可以在运行时重新定义标准库的行为。
-
变量和作用域:程序员不需要在 ruby 中声明变量或变量作用域。变量的名称自动确定其范围。
示例: var
是局部变量$var
是全局变量@var
是一个实例变量@@var
是类变量
Ruby:高级特性
- 处理错误的例外。
- 垃圾收集器。
- 与操作系统无关的线程化,即使在 DOS 等操作系统上也能编写多线程应用。
- 你可以用 c 语言编写 Ruby 的扩展。
为什么你应该选择鲁比?
- Ruby 是一种服务器端脚本语言。
- Ruby 可以嵌入到 HTML 中。
- Ruby 的语法类似于许多编程语言,如 C 和 Java。
- Ruby 几乎支持所有的平台,比如 Windows、Mac 和 Linux。
- Ruby 可以很容易地连接到 Oracle、MySQL、DB2。
如何安装 Ruby
在本教程中,我们将学习如何在本地系统上安装 Ruby。我们将介绍以下两种操作系统的安装步骤:
- 在 Windows 上安装
- 在苹果电脑上安装
Ruby:安装在视窗系统上
要下载 ruby,请前往http://rubyinstaller.org/downloads
下载最新版本的 Ruby。最靠前的那个是最新的。您可以下载安装程序或存档文件。但是下载安装程序还是不错的。
对于 64 位操作系统,下载以(x64)结尾的安装程序。下载 exe 文件后,双击打开文件。
选择语言。
点击“我接受许可”。
浏览并选择所需的安装路径。但是建议安装在默认目录下。并检查以下 3 个选项:
- 安装 Td/k 支架
- 将 Ruby 可执行文件添加到路径中
- 将
.rb
和.rbw
文件与 Ruby 安装相关联
点击安装。
您将看到安装进度条。完成后,单击“完成”。
鲁比:在苹果电脑上安装
Ruby 预装在 Macintosh 上。所以不需要经过安装程序。
使用 Ruby 交互式 Shell
它也被称为 irb。它允许我们键入 ruby 表达式或语句。打开命令提示符并键入 irb。(Windows 和麦金塔都有)。
如上图所示,我们可以编写 ruby 表达式和语句。引号内输入的文本称为字符串。我们可以对两个字符串执行连接操作。
我们可以简单地将值存储到变量中,
name = “Welcome to Ruby!”
Ruby 是一种区分大小写的编程语言。所以,名称不同于名称和名称。
我们还可以执行一些复杂的操作。请参见下面打印从 1 到 9 的数字的代码片段。
i = 1
while i < 10
print i
end
输出:
哇哦!!刚刚发生了什么?看到输出后,您可能会感到困惑。我们说它打印 1 到 9。但是它显示了所有的 1,而且也太多了。这是因为变量i
没有增加。按 Ctrl + C 终止执行。
下面的代码从 1 到 9 打印
i = 1
while i < 10
print i
i += 1
end
我们也可以在irb
中定义函数。函数是执行特定任务的一组语句。这是一个返回数字平方的函数。
*def* square(n)
return n * n
end
调用函数: square (4)
调用该函数并将 4 作为参数通过执行操作4 * 4
返回 16 。同样,求圆面积的函数。
*def* circle(radius)
return radius * radius * 3.14
end
调用函数: circle (5)
,传递 5 作为参数。此功能通过乘以5 * 5 * 3.14
返回 78.5
Ruby 脚本
我们将从文本编辑器而不是命令提示符运行 ruby。您可以使用任何文本编辑器,如记事本、记事本++ 、崇高、括号。Ruby 脚本有。rb 分机。所以,你必须保存扩展名为.rb
的文件。现在,在您的编辑器中输入以下代码,并以任何带有.rb
扩展名的名称保存它:
puts "Welcome to Ruby!"
我们先把这个保存为吧。要运行程序,进入命令提示符,输入ruby first.rb
。如果在安装期间选择了“将 Ruby 可执行文件添加到您的路径”选项,您也可以通过简单地键入first.rb
来运行。
同样,您可以在麦金塔中使用任何文本编辑器,并遵循与在 Windows 中相同的过程。
Ruby 中的注释
Comments
是Ruby
中不可执行的语句。Comments
隐藏在Ruby 解释器中,因此这些行被忽略。它们用于增加程序的可读性。我们可以在程序的任何地方写注释,除了在变量里面,因为 Ruby 解释器认为它是一个字符串。
Ruby:单行注释
使用 Ruby 中的#(Hash)
符号创建Single line comment
。
print “Hello World” #Used to Display the Text
每当,Ruby
在一行中找到#时,其后的所有内容都将被忽略。
Ruby:多行注释
使用代码块 =begin / =end 创建多行注释
=begin
This is used
to illustrate
multiple line comments
in Ruby language.
=end
The statements inside this block are ignored by the Ruby Interpreter.
有效的注释示例:
Puts “4 * 6 = #{4*6}” #Multiplies 4 with 6 and Displays result
进阶
使用print()
和puts()
显示数据
原文:https://www.studytonight.com/ruby/displaying-data-in-ruby
现在,我们将学习如何在屏幕上显示数据。为此,Ruby 提供了两个功能:
puts()
print()
Ruby:puts()
法
puts
在数据末尾自动添加新行。
puts ("hello, world")
puts "hello, world"
您可以使用这两种方式来显示数据。要在一个 puts 语句中打印多个字符串,请使用下面的方法。它将在每个字符串的末尾添加一个换行符。
puts "hello, world", "Goodbye, world"
也试试下面的例子:
puts "practice", "makes", "a", "man", "perfect"
Ruby:print()
法
print
结尾不加新行。
print "hello, world"
如果你想用打印方式在数据的末尾包含新行,那么你必须为新行包含特殊字符\n
。
print "hello, world\n"
print "practice\n", "makes\n", "a\n", "man\n", "perfect\n"
您也可以使用这些函数显示数字数据。
puts(1)
print(1)
您也可以评估表达式并显示结果。
puts (2+2)
print(2+2)
在 Ruby 中使用gets()
从用户获取数据
原文:https://www.studytonight.com/ruby/getting-user-input-ruby
为了使程序与用户交互,程序通常需要用户的输入。为此,我们可以使用gets
方法。gets
函数以字符串格式从键盘获取输入,并将值存储在变量中。
name = gets
该语句从用户处获取字符串输入,并将其存储在名为 name 的变量中。
它还在用户输入的输入结束时追加一个\n
新行字符。
因此,当您键入变量名时,它会显示存储在其中的内容。当您使用print
功能显示时,它会显示用户输入的文本以及新的一行。要删除换行符,可以使用名为chomp
的函数。以下语句从用户输入的内容中删除换行符。
print name.chomp
以下代码将两个整数与用户提供的数字相加:
number1 = gets
number2 = gets
(Integer)number1 + Integer(number2)
Integer()
部分代码现在对你来说看起来很棘手。
如前所述,gets
方法获取字符串格式的输入。因此,在对数据执行算术运算之前,需要转换为整数。这可以使用Integer()
功能来完成。
如果不将这些变量转换为整数,它将连接两个字符串,而不是执行算术加法。你还记得我们在第 1 章前面看到的连接两个字符串吗?同样,要添加两个十进制数,请查看以下代码:
num1 = gets
num2 = gets
float(num1) + float(num2)
注: float()
方法用于将数据转换为十进制格式。如果转换没有完成,它只是像前面所说的那样执行串联操作。
Ruby 中的变量和数据类型
在本课中,我们将看到不同类型的变量和常数。虽然有几种类型的变量,如类变量和全局变量,但我们将在本课中了解局部变量。要在 ruby 中创建一个变量,我们只需使用赋值语句提供一个名称和值。
number = 100
Ruby:命名变量的规则
-
Must begin with lowercase letters or underscore like :
number
,_name
. Underscore come in handy when we create a compound variable using Snake Case like,first_name = "Bharath"
Another way to write compound variable or multiword variable is Camel Case.
lastName = "Kumar"
Ruby 风格指南向 Ruby 开发人员推荐了一致的约定和最佳实践。
-
后跟下划线或小写字母变量的下一个字符可以是数字或其他字母,但不能是符号。
_123, rate1 *//valid* #abc, n*ame *//invalid variable names.*
-
名称应该与任何保留关键字相匹配。我们将在保留关键字一课中查看 ruby 中的保留关键字。
-
全局变量是通过在变量名前放一个美元符号
$
来创建的。《出埃及记》$salary = 10000
。工资是一个全局变量,可以在整个项目中看到。
Ruby:数字数据类型
在本节中,我们将使用数字数据类型。Ruby 支持主要的数字系统,如整数、浮点数。允许Binary
、Octal
、Hexadecimal
等不同的碱基。
要用二进制写,我们使用0b
和相应的数字。例如,5 在二进制中可以写成 101。同样,用十六进制0x
表示数字,八进制 0 单独使用。负数通过在数字前使用一元运算符- (负)来表示。
Ruby 支持加、减、乘、除、模、幂等不同的算术运算。
在上图中,您可以看到执行的算术运算。
9 % 3
语句提供 9 除以 3 的余数。在这种情况下,结果将为 0。2 ** 5
语句将 2 的幂提高到 5。所以,结果会是 2 * 2 * 2 * 2 * 2,等于 32。
我们将在后续课程中详细学习运算符。
Ruby:ABS 法
abs
是用来求一个数的绝对值的方法。例如, -26.abs 给出的值是 26。其他一些方法是 div 和模。
您也可以将数字转换为字符串。例如,要将 100 转换为字符串:
100.to_s
Ruby:布尔数据类型
布尔型变量可以保存两个值真或假。但是在 ruby 中,它也可以保存布尔变量中的第三种类型的值,称为 nil 。但是在大多数情况下,我们只使用真和假值。所以,让我们专注于这两个。
布尔数据类型用于比较、循环和决策语句。 100 > 1 返回真。因为 100 大于 1。同样, 1 > 100 返回假。
您也可以为变量指定布尔值。
flag = true
赋值后,变量标志包含布尔值真。
Not 运算符(!)
否定布尔值。例如,如果flag
变量包含值真。然后标志变量的否定给出了值假。
也可以对变量进行双反。但不止一次否定往往会令人困惑。因此,当你需要的时候,最好坚持使用单一否定。
Ruby:常数
Constants
是在整个程序中保持相同值的变量。Ruby 是一种典型的语言,您可以在其中重新分配常量。按照惯例,ruby 中的所有常量都是大写的字符,以便于区分。
注意,它确实改变了常量的值,但是它给出了一个警告,说“PI 已经是初始化常量了”。
所以,只要注意你可以在 ruby 中定义常数,你也可以改变它的值,这意味着你想知道它们不应该被称为constants
。正如我们已经说过的,Ruby 是一种典型的语言。
Ruby 中变量的类型
原文:https://www.studytonight.com/ruby/types-of-variables-in-ruby
在Ruby
中有 4 不同类型的变量。它们是:
- 局部变量
- 类变量
- 实例变量
- 全局变量
| | 当地的 | 全球的 | 情况 | 班级 |
| 范围 | 仅在块或函数内 | 在整个计划中 | 限于类的一个特定实例 | 限于定义它们的类 |
| 命名 | 局部变量以小写字母或下划线开头 | 全局变量以$开头 | 实例变量以@开头 | 类变量以@@开头 |
| 初始化 | 不需要初始化。使用未初始化的局部变量被解释为对没有参数的方法的调用。 | 不需要初始化。未初始化的全局变量没有值。 | 不需要初始化。未初始化的实例变量没有值。 | 必须在使用前进行初始化。使用未初始化的类变量会导致错误。 |
Ruby 中的保留字/关键字
原文:https://www.studytonight.com/ruby/reserved-keywords-in-ruby
有些词是专门用来做特定任务的。这些词被称为keywords
,它们在Ruby
中有标准、预定义的含义。
Ruby
中提供的一些keywords
如下所示:
| 开始 | 结束 | 别名 | 和 | 开始 | 破裂 | 情况 | 班级 | 极好的 |
| 组件 | 然后 | 无 | 不 | 或者 | 重做 | 营救 | 重试 | 返回 |
| 埃尔西夫 | 目标 | 错误的 | 确保 | 为 | 如果 | 真实的 | 未定义 | 除非 |
| 做 | 其他 | 极好的 | 然后 | 直到 | 当...的时候 | 正在… | 定义了吗? | 自己 |
这些keywords
不能用于Ruby
中的命名变量或常量。
Ruby 中的运算符和表达式
在本课中,我们将了解 ruby 包含的不同operators
以及如何在expressions
中使用它们。
鲁比:加法运算符
+
符号被使用。它既是二元运算符,也是一元运算符。顾名思义,Binary operator
需要运算符两侧的两个操作数/值来执行运算,一元运算符只需要一个操作数。一元加号没有任何作用,它的存在只是为了与一元减号对称。
For example : 1 + 2 *//binary addition*
value = +3 *//unary plus*
鲁比:减法运算符
-
符号被使用。您可以使用一元减号来反转变量的符号。
For Example : 23.2 - 2.2 *//binary subtraction*
value = -3 *//unary minus*
鲁比:乘法运算符
*
符号被使用。对两个数字操作数执行乘法运算。
For Example : 122 * 3.14
鲁比:除法运算符
/
符号被使用。返回第一个数字操作数除以第二个操作数的结果。
For Example : 18 / 3
鲁比:模运算符
除法后返回余数。
For Example : 13 % 2 *//returns 1*
鲁比:指数算子
如果你想提升x
到y
的力量(即)x ^ y
。
It is done by x ** y
2 的幂 4 返回 16。
Ruby:运算符优先级
Operators
有一些precedence
的顺序,它决定了表达式的求值顺序。
Consider this example, 1 + 2 * 3
我们可能会认为 1 + 2 执行,结果 3 将乘以 3 并给出 9 。但是乘法、除法和指数运算符的优先级高于加法和减法运算符。因此,首先执行 *2 3 ,并将结果添加到 1 中,并给出 7 作为答案。
但是,我们可以通过将子表达式放在括号中来修改优先顺序。在表达式 1 + 2 * 3 中,如果 1 + 2 需要先执行,将该表达式放在括号中。
(1 + 2) * 3 this expression produces 9
Ruby:关系运算符
Relational operators
用于比较。他们返回Boolean values
。我们比较两个值是否相等、不相等、小于、大于、小于或等于以及大于或等于。
==
符号被使用。用于检查两个数是否相等。
1 == 1 returns true because 1 is equal to 1.
<
-小于
>
-大于
<=
-小于或等于
>=
-大于或等于
小于运算符检查一个数字是否小于另一个数字,如果是则返回真否则返回假。小于或等于运算符检查一个数是否小于另一个数,还检查一个数是否等于另一个数,如果任一条件正确,则返回真,否则返回假。大于和大于等于也一样,检查是否大于。
**
比较两个值的另一种方法是使用通用比较运算符。它根据操作数返回 0(零)、 -1 或 +1 。如果两个值相等,则返回零,如果第一个操作数小于第二个操作数,则返回 -1 ,如果第一个操作数大于第二个操作数,则返回 +1 。
The General Comparison operator is <=>(< = >).
Relational operators
也可以搭配琴弦使用。
如果相同,则返回真。你可以看到它为操作【苹果】=【苹果】返回假,这是因为 Ruby 区分大小写,一个单词有Uppercase A
,而另一个单词有lowercase a
。我们也可以使用带字符串的通用比较运算符。
比较【车】和【车】时,返回 0 ,因为两者相等。将【驾驶室】与【汽车】进行对比时,由于【驾驶室】中【b】一词的第 3 个字母小于【汽车】中的【r】,因此返回 -1 。
鲁比:逻辑运算符
Logical operators
允许您组合两个或多个关系表达式并返回Boolean
值。
- 和运算符:
当所有表达式都为真时,它返回真;如果其中一个表达式的计算结果为假,它返回假。您可以使用and
或&&
使用该运算符。
表达式工资== 10 & &小时== 40 返回真,因为我们已经将工资和小时变量的值初始化为 10 和 40。对于所有其他情况,它将返回 false。
- 或运算符:
OR
当任意一个条件/表达式为真时,运算符返回真,只有当所有条件/表达式都为假时,运算符才返回假。您可以使用or
(或)||
来使用该运算符
可以看到,即使只有一个表达式为真或运算符也返回真。
- 非运算符:
NOT
运算符否定关系表达式。该操作员可以使用not
(或)!
。
在第一个表达式中,它返回 false,因为表达式 salary == 10 返回 true,not 运算符否定 true 并返回 false。同样,表达式工资< 10 返回假,非运算符否定并返回真。
Ruby 杂项表达式
原文:https://www.studytonight.com/ruby/miscellaneous-expressions-in-ruby
在本教程中,我们将学习链式赋值、定义运算符和并行赋值。
鲁比:链接作业
通常,在程序中,您希望用相同的值初始化一组变量,通常为 0。
不过,你可以这样做
a = 0
b = 0
c = 0
但是,程序员使用的还有一种叫做chaining assignments
的方式。
a = b = c= 0
现在这三个变量都有相同的值。
可以看到变量 a 、 b &、 c 具有相同的值 0。
Ruby::defined
运算符
这是 ruby 的一个有趣的特性。在表达式中使用它,我们可以确定它是什么类型的标识符。我们已经将变量定义为。我们现在可以使用定义的运算符来识别什么是 a ?
因为变量 a 是在本地声明的,所以它作为local-variable
返回。同样,它返回method
表示打印和assignment
表示表达式 a = 1 。
鲁比:并行分配
考虑变量 a 包含 5,b 包含 10,现在我们必须交换变量的值。
它是由,
a = 5
b = 10
temp = a
a = b
b = temp
但是有一种有效的方法叫做parallel assignment
。这可以通过 a,b = b,a 来完成。安静简单。正确
最初 a 和 b 的值为 5 和 10 ,并行赋值后 a 和 b 的值为swapped
。
Ruby 中的插值
Interpolation
是关于在字符串内部使用表达式和值。例如,考虑一个名为 a 的变量,它包含 4,而变量 b 包含 6。现在,我们要打印 4 * 6 = 24
a * b = a*b. Will this work?
没有。它返回了一个意外的结果。我们需要打印 a 、 b 和 a*b 的数值。现在,Interpolation
进入画面。使用Interpolation
,我们可以在字符串中包含表达式和值。
To Interpolate the value of a, do the following: puts " #{a} "
它返回一个的值,而不是作为字符串的“a”。同样,我们必须对变量 b 和表达式 a*b 做同样的操作。
Ruby 计算变量或花括号之间的表达式的值。
#{a*b}
Ruby,计算 a*b 的值并插值成字符串。
插入字符串:
考虑一个有值的变量。
person = "Sachin Tendulkar";
现在,我们要展示“我爱萨钦·坦杜尔卡”。
我们期待“我爱萨钦·坦杜尔卡尔”但是它显示了“我爱这个人”。现在,让我们插入变量person
。
Ruby 字符串数据类型
可以使用single quotes
或double quotes
在 Ruby 中形成弦。
引号内的任何字符如数字或字母或符号均为Strings
。
我们已经学习了在字符串中添加换行符。同样,其他字符也可以嵌入字符串中。
name = *"Bharath\tKumar"*
\t
添加制表符空间\s
增加空间
对于创建字符串,这是使用双引号而不是单引号的额外优势。如果使用双引号,可以在字符串中使用单引号作为apostrophe
。
str = "Bharath's"
- 但是不能在单引号中直接使用单引号。
- 但是有一种方法可以做到这一点,使用一个特殊的字符
\
作为转义字符,从而告诉编译器/解释器下一个字符有一些特殊的含义,就像\n
的情况一样。在其他情况下,像撇号一样,反斜杠\
告诉编译器/解释器下面的字符没有特殊含义,并且下面的字符是字符串的一部分。
str = 'Bharath\'s'
使用双引号内的\'
在字符串中包含撇号。
在下图中,当在字符串的单引号中使用单引号时,您可以看到我们无法退出交互模式。所以,不可取。
鲁比:这里的关键字
要创建多行字符串并将其存储在变量中,使用HERE
关键字。
这以两个小于符号<<
开始,关键字在这里表示,直到您再次看到关键字在这里,将所有值存储在变量中。
quote = << *HERE*
What you do
today can
improve
all your
tomorrows
*HERE*
因此,值What you do\ntoday can\nimprove\nall your\ntomorrows
存储在变量quote
中。这是在变量中存储大块文本的最简单方法。
Ruby:分裂法
分割是一个有用的方法,用于获取字符串并分割成多个部分。它的语法是:
*<String Value>*.split(<*DELIMITER*>)
其中,分隔符是指定的字符串将被一分为二的点。
first,last = "Bharath,Kumar".*split*(/,/)
这里comma (,)
是分隔符。我们使用slashes (/)
来定界(转义)分隔符。
执行此语句时,逗号前的文本首先分配给变量,逗号后的文本最后分配给变量。****
****因此在上图中,值Bharath
被分配给变量first
,值Kumar
被分配给变量last
。
Ruby:挤压法
Squeeze
用于从字符串中删除尾随空格。以下是它的语法:
*<String Value>*.squeeze
在上图中,您可以先记下变量中的空格数。当使用挤压方法打印第一个变量时,它会删除尾随空格。
Ruby 中的范围
范围是一系列数据。例如,数字 0 到 9 是一个范围。字母 a 至 z 为 a range
。我们也可以定义自己的范围。
The syntax for defining range is startvalue..endvalue
示例: 0..9 是包含从 0 到 9 的值的range
。同样‘一’..z' 也是一个range
里面有所有的字母。
您也可以创建自己的范围,如“aab”..aae' 包含值 aab 、 aac 、 aad 、 aae 。
Range
是 Ruby 中灵活的数据类型。一旦定义了范围,我们也可以在范围上调用方法。
Ruby:范围数据类型的方法
-
include()
方法用于检查特定元素是否存在于范围内。如果该元素存在于该范围内,则返回true
,否则返回false
。 -
min()
方法返回范围的最小元素。 -
max()
方法返回范围的最大元素。 -
each
method is used to loop around a range and print all the elements of a range on the shell output.我们可以这样显示
range
的每个元素/成员:letters.each { |letter| print(letter) }
在上面的代码中,范围‘a’的每个成员..存储在变量
letters
中的 z' 在每次迭代中被复制到变量letter
中。这是通过使用符号||
来完成的。然后,我们可以用这个值做任何我们想做的事情。这里,我们刚刚打印了变量letter
中的值。Ranges
通常用作循环中的条件。 -
There is also another useful operator called case equality operator
(===)
. Using this operator, we can determine that whether any particular element is present in the given range or not. If the element is present in the range it returns true, else returns false.这里元素‘c’出现在变量
letters
中,所以它返回真。同样的,digits
是一个包含 0 到 9 范围的变量,我们正在用case equality operator
检查 100 是否在范围内,它返回 false 表示 100 不属于这个范围。
Ruby 中的数组
数组存储相同数据类型的多个值。数组类似于范围,唯一不同的是范围必须代表连续的序列。另一方面,数组包含数据集合;它不需要是连续的序列。阵列的真实例子有:
- 装鸡蛋的鸡蛋纸盒
- 棋盘及其棋子等
数组的表示
数字 0 到 7 称为数组Index
。它们用于访问数组元素。
Ruby:定义数组
我们通过将放在数据周围的方括号来定义数组。例如,
numbers = [1,3,5,7,9]
这里numbers
是integers
类型的 5 号(数据)的集合。
数组的元素通过使用数组名后跟索引来访问。例如,numbers
数组的第一个元素被号【0】访问
为了总结等级数组的所有元素,使用以下语句。
Sum = grades[0] + grades[1] + grades[2] + grades[3]
然而,有更有效的方法来访问数组的所有元素。当我们进入关于循环的课程时,我们会看到这些。到目前为止,要访问数组元素,您需要指定它的索引。有时称为偏移。
Ruby:把序列变成数组
序列(范围)可以使用to_a
方法转换为数组。
鲁比:什么是哈希?
Hash
是存储数据集合的另一种数据结构。它通常被称为关联结构,因为我们以key-value
对存储数据。联想结构的一个经典例子是词典,其中单词是键,单词的定义是值。在 hash 中,为了找到值,我们必须查看键。
下面是一个演示如何在 ruby 中定义散列的例子:
pincode = {
'Abc' = '123',
'xyz' = '980',
'def' = '456',
}
Ruby:散列的表示
我们通过像数组下标一样将键呈现给散列名称来从hash
中检索值。
要检索 Praveen 的号码:numbers['Praveen']
如果我们试图用一个不存在的键来检索一个值,它会返回nil
。
这样可以保证键是否存在。如果返回nil
,则表示密钥不存在。
Ruby 中的push
和pop
方法
在这一课中,我们将学习更多关于数组的知识,更多的方法使add
和remove
元素往返于数组。打开交互式 ruby Shell 并键入:
sample = [ ]
这将创建一个空数组,其中没有元素。现在,我们将向这个名为样本的空数组中添加元素。您可以将元素推入数组。你可以用几种方法做到这一点。
sample << '*first item*'
该语句将字符串“第一项”推入数组。
鲁比:推送操作
将项目添加或推入数组的另一种方法是使用push()
方法。
sample.push("*second item*")
现在,你可以看到数组中有三个名为sample
的项目。
露比:流行操作
要从数组中移除元素,我们使用pop()
方法。
sample.pop
要移除元素,不需要指定参数。它会移除最近插入的项目,无论它是什么。
弹出操作
如您所见,pop
操作移除了最近插入的项目哈库纳马塔,然后是第二个项目。现在,数组只包含一项。这些操作允许数组用作 STACK 数据结构。
记住,
push
-将项目或元素插入数组。pop
-从数组中移除项目或元素。
Ruby 中的决策
决策语句用于根据某些条件运行一组语句或另一组语句。
Ruby: if
语句
让我们使用 ruby 脚本。键入notepad filename.rb
。这将提示您创建一个新文件,键入 yes。你也可以根据自己的喜好选择其他文本编辑器。
#if comparison (relational expression)
# statements
#end
grade = gets
grade = Integer(grade)
if grade >= 70
puts "pass"
end
这是程序的代码片段。任何以# sign
开头的语句都是注释。它们是不可执行的语句,用于更好地理解程序。
If
语句的语法:
if (condition)
statements
end
如果条件为真,则执行if
块内的语句。
运行程序时,提示用户输入等级,转换为Integer
。如果输入的等级大于 70 ,则显示pass
。
您可以看到,当输入大于 70 的值时,它会显示 pass。如果输入的值小于 70,则不显示任何内容。为了处理这个问题,我们需要另一种类型的语句If - else
。
Ruby: if...else
语句
如果条件为真,If else 语句执行一组语句,如果条件为假,则执行另一组语句。
If- else 语句的语法:
if (condition)
statements1
else
statements2
end
如果条件为真,则执行 If 块中的语句,如果条件失败,则执行 else 块中的语句。
如果输入的值小于 70,则显示fail
。
If else 语句用于双向决策。如果要有两个以上的决策,可以使用If - Else If
语句。
If - Else If 语句:
它用于制作更复杂的分支语句。
If - Else If 语句的语法为
if (condition1)
statements1
elsif (condition2)
statements2
elsif (condition n)
statements3
else
statements4
end
它计算条件 1,如果为真,它执行语句 1,如果为假,它计算条件 2,如果为真,它执行语句 2,依此类推。如果这些条件都不成立,它就执行语句 4。
执行此程序时,会提示输入标记。根据输入的值,它检查程序中给出的条件,并显示您的Grade
。
鲁比:案例陈述
If - else if 语句的替代语句是Case statement
。它也用于做出多个决策。我们可以使用 Case 语句以结构化的方式做出多个决策。
Case 语句的语法:
case (expression)
when expression1
statements1
when expression2
statements2
else
statements3
end
如果变量等级的值在 90 到 100 之间,它会将A
分配给变量letterGrade
。同样,当满足相应的表达式时,基于输入执行以下语句。
Ruby unless
条件
在我们开始unless
之前,让我们来看看一些我们之前已经看过的基本东西。我们这样做是因为,它解释了你的问题为什么除非?所以,我们看到关于or
运算符、if
关键字和unless
关键字。OR
运算符返回 true,即使其中一个条件为 true。
在上面的代码中,变量权重被赋予一个值 32 。然后使用OR
操作符检查条件。
体重小于 35 或大于 70 显示“需要看医生”。
现在,检查第一个条件重量< 35 ,这个条件变为真,因为重量的值是 32,如果第一个条件为真,则OR
操作员不检查第二个条件。它只是返回真。
当条件为真时,显示“需要看医生”信息。现在,将重量的值视为 87 。
第一个条件检查重量< 35 ,条件失败,检查第二个条件重量> 70 ,条件为真,显示信息。现在,如果权重包含 35 到 70 之间的值会怎么样?
像往常一样,检查第一个条件,它失败,检查第二个条件,它也失败。因此不执行puts
语句。
当我们谈到if keyword
的时候,它是用来做决定的,是不是执行那组代码。但是,如果想要测试 if 的反义词呢?也就是说,您只想在条件为 false 时执行代码。这就是unless
出现的地方。
当年龄大于 18 岁时,该程序显示消息“你有资格投票”。存储在变量年龄中的值是 23 。
当检查条件时,它返回 false 并执行 puts 语句。这可能会令人困惑。
Remember that unless is opposite of if.
你,可以把这个代码声明理解为如果你的年龄不低于 18 岁,你就有资格投票。也就是类似puts "You're eligible to Vote" if age > 18
如果你在阅读unless
语句时感到困惑,只需以与if
语句相反的方式阅读即可。
Ruby 中的循环
循环用于根据条件重复执行一组语句。有时需要一次又一次地执行一组语句。例如,检查数组中的数字是否是质数。
鲁比:当循环
While 循环用于重复执行一个代码块或代码段,直到条件变为假。
While 循环的语法:
while (condition)
statements
end
首先检查条件,如果是真的,重复while block
中的语句。在每次迭代结束时,再次检查条件。当条件被发现为假时,while
循环终止。
考虑下面打印“你好,世界” 5 次的例子。
现在让我们检查它的输出
哦,等等!这是什么?应该只印了“你好,世界”5 次。但是发生了什么?
变量计数用值 1 初始化,当计数变为 5 时,循环将终止。但是在 while 循环中,没有递增 count 值的语句。因为条件永远不会变假,所以不会终止。这叫Infinite loop
。
现在,在这段代码中,您可以看到计数的值增加了 1 。因此,每次执行循环时,计数的值递增,如果计数的值变为 6 ,则条件失败并退出循环。现在,让我们看看输出。
这就是我们的预期产量。条件失败后,从while block
出来,执行while block
后面的下一条语句。
下一个程序打印前十个数字的总和。
鲁比:直到循环
Until loop
与while loop
非常相似。
while loop 和while loop的唯一区别在于 while loop 重复执行语句集,直到条件变为 false 和直到循环重复执行语句集,直到条件变为 true 。Until
与while
相反。
While 循环的语法:
until (condition)
statements
end
检查条件,如果是假它执行until block
里面的语句,当条件变成真时,它退出循环。
循环执行,直到计数变为 6 。当计数变为 6 时,条件将为真,并且退出循环。程序的输出是:
打印前 10 个数字总和的程序
上述程序的输出是:
Ruby:每个迭代器
Each Iterator is used to iterate over an array
它取出容器或数组的每个元素,并分配给变量 x 。使用变量 x 的值,我们可以进行我们想要的操作。
鲁比:用于循环中
就像while
和unless
循环重复执行一组语句。利用这一点,我们还可以遍历容器。
在这段代码中,它取出数组 nums 的每个元素,并将其存储在单个元素(变量) num 中。然后使用该值,我们可以执行所需的操作。上面代码的输出是:
要使用 for 循环对 10 个数字求和:
它的输出是:
高级
Ruby 中的迭代器
Iterators
允许我们遍历一个范围,并在一个范围内做一定次数的事情。演示Iterator
比描述更容易。
Ruby:时代迭代器
这段代码执行 do 块中的语句的次数在times
关键字之前。times
关键字知道从 1 开始,到times
关键字之前指定的数字为止。
Here, 5 is given. So, it prints "Hello, World" for 5 times.
鲁比:向上迭代器
它从upto
关键字之前指定的数字开始,直到upto
关键字中指定的数字,遍历整个范围。在我们的例子中,从 1 到 10。对于每次迭代,它将值存储到变量 x 中。使用变量 x 中的值,我们可以通过在 do 块中指定它来执行我们想要的操作。
上面代码的输出是:
同样,我们可以将前十个数字的值相加,
Ruby:步骤迭代器
有点类似upto
迭代器。
它在用户指定的范围内迭代。对于每次迭代,它增加由步数计数器指定的变量x
的值。
上述程序的输出是:
打印最多 10 个奇数的总和
上述程序的输出是:
请记住,迭代器与传统编程语言中的while
和do while
循环相比,提供了更大的灵活性。
Ruby 方法
方法也称为功能。方法用于执行特定的一组指令
例如,
- Word 中文件菜单有保存、打开等不同操作。,
- 保存专门保存单据,并包含相应的编码。
- 打开命令用于打开文档。
函数取参数,有返回类型。
参数就像给函数的输入,而返回类型就是函数的输出。
返回类型在 ruby 中可以是两种类型:
- 通过使用表达式
- 通过使用
return
关键字。
方法的语法:
def *methodname*(arguments)
statements
return
end
在上面的代码中,有一个名为square
的方法,只有一个参数。名为number
的变量被赋予了 3 的值。另一个名为numbersqr
的变量被赋予了该函数返回的值。这里,我们通过指定名称和传递参数来调用函数。
square(number). It is called function calling statement.
变量number
被传递给函数,该函数被分配给函数中的局部变量num
,该数字被相乘,并且函数返回被分配给变量numbersqr
的值。
这是上述程序的输出:
值 9 从函数返回,分配给变量numbersqr
,并使用print
方法显示。在本例中,函数的返回类型是使用表达式。
具有多个参数的 Ruby 方法
在这个程序中,有两种方法square
和power
。幂法取两个参数。此方法将基础变量中的值提升至exp
变量中的值后返回该值。此方法显式返回该值。即使用return
关键字返回该值。
def *power* (base, exp)
product = 1
while exp > 0
product *= *base*
exp -= 1
end
return product
end
当通过传递以下参数调用该函数时:power (3, 3)
。它将 3 的值乘以 3 的幂。
在这个程序中,函数调用语句是在 print 方法内部编写的。这指定被调用的函数在程序中的任何地方。
首先调用 square 方法,它返回值并存储在变量numbersqr
中。现在,当调用幂方法时,我们传递变量numbersqr
和number
。因此,返回numbersqr ^ number
的值。
在我们的例子中,9^3
或9*9*9
即 729 是从函数中返回的。
不返回任何东西的 Ruby 方法
方法可以返回值,也可以不返回值。没有规定它们必须返回值。这些方法可以用来显示某种类型的消息。
这里有一个名为prompt
的方法,它显示传递给它的消息。我们可以用这个方法显示短消息,从主程序中抽象出代码。我们通过传递“你好,世界\ n”来调用这个方法,它会显示消息。
我们从用户那里获得输入,并将其存储在变量value
中,我们通过传递变量值来调用函数提示,以显示用户输入的消息。这个方法不返回任何东西。
Ruby 方法:使用数据结构
使用不返回值的方法的另一个原因是,当您想要创建一个可能必须返回多个值的方法时,或者当您必须对该方法中较大的数据结构进行操作时。
在这个方法中,我们已经声明并初始化了名为grade
的数组。我们定义了一个名为points
的方法,它将用户指定的值添加到数组的每个元素中。此法取
arr.map! { |grade| grade+= grace }
这个语句使用了一个叫做map
的方法。地图法属于类阵。Map 方法从数组中取出每个元素,并将其存储在某个变量中,使用该变量我们可以执行所需的操作。
这里,对于每个实例,它将数组的元素存储在变量grade
中,并将值grace
添加到其中。第一次迭代时, 60 存储在grade
中,grace
的值为 5 (调用函数时传递)被添加到数组grades
的元素中。因此,当我们使用each
迭代器打印等级时,显示等级数组元素的值。
Ruby 类
Ruby
是一种纯面向对象的编程语言。面向对象程序由Classes
和Objects
组成。object
是一个实体,它充当数据的容器并控制对数据的访问。
A class
就像一个蓝图,允许你创建对象,并创建与这些对象相关的方法。例如,您可以使用形状类来制作不同的形状,如矩形、正方形、圆形等。一个object
就是一个class
的例子。
等级体系
Ruby
有很多班。并非所有的类都包含在这个层次结构中。类基本对象是所有类中的超类。
我们已经将局部变量值设置为一个字符串。当我们通过调用来检查值的等级时。类方法,它告诉我们 val 的类是 String。然后,当我们检查字符串的超类时,通过调用。超类方法它告诉我们Object
等等。
The reason the last value is nil is because the class BasicObject has no superclass.
在 Ruby 中定义类
Ruby
中的一个类以关键字class
开头,后面跟着类的名称。
在 Ruby 中创建对象
使用方法new
创建 Ruby 中的Objects
。new
法属类类。
obj1 = Shape.new
这是创建对象的语法。这里 obj1 是对象名, Shape 是类名。
类的另一个例子:
在上面的程序中,我们创建了一个名为名为的类。
方法initialize
是一种特殊类型的方法,由对象创建中的new
方法调用。initialize
方法接受存储在实例变量@第一个、@中间和@最后一个中的三个参数,而变量第一个、中间和最后一个是局部变量。inspect
方法给出关于类名和实例变量及其值的列表的信息。
这是程序的输出:
使用到 _s 方法的另一个例子:
to_s (to string) method allows us to display the state of the object. State refers to all the data that is being stored in the class objects.
程序的输出是:
当我们将程序的最后一行改为时,打印 obj1 。这里我们是字面上的打印对象,让我们看看这个变化后的输出:
所以,当打印对象时,自动调用to_s method
。此方法可用于通过在任何特定时间显示对象的状态来调试或测试代码。
Ruby:访问类和对象属性
我们还可以编写方法来检查对象的单个字段或属性。
您必须使用属性/字段的名称来定义方法。这里我们已经为领域首先创建了一个方法。使用object name
调用该方法。
程序的输出是:
同样,我们可以检查对象的每个属性。我们可以用另一种简单的方法做到这一点。
属性可以通过以下语句来检查 attr_Reader:第一个,:中间,:最后一个。该方法返回使用print
方法打印的对象的属性值。
程序的输出是:
使属性可写
通过以下语句可以使属性可写/可修改:
attr_writer :first, :middle, :last
这里,我们修改了对象 obj1 的实例变量。程序的输出是:
这里可以看到第一个、中间、最后一个值被修改打印。
Ruby 中的正则表达式
原文:https://www.studytonight.com/ruby/regular-expressions-in-ruby
正则表达式基本上是用来处理 ruby 中的字符/文本模式的。
sub()
方法不是正则表达式。但是它解释了何时使用正则表达式。它用用户指定的其他字符串替换字符串的一部分。它包含两个参数,第一个参数是要被取代的substring
,第二个参数是要被取代的substring
。
例如,要将 badjohnny 中的子字符串 bad 替换为bad我们可以使用:
puts "badjohnny".sub('bad','good')
它用good
代替bad
。但是它不会替换子字符串的所有实例。
您可以看到它只替换了子字符串坏的的第一个实例。使用gsub()
方法替换子串的所有实例。
像这样的事情可以在正则表达式中完成。
鲁比:正则表达式
变量a
有值“嘿,你想要什么?”。如果你想把“嘿”换成“打扰一下”,那你可以用正则表达式。如前所述,sub()
方法有两个参数。我们必须用我们想要的字符串替换前三个字符。
第一个参数包含/^.../
正则表达式以正斜杠/
开始和结束。^
符号用于匹配从字符串开头开始的子字符串。它没有用替换中间的字符,而是从头开始替换字符。圆点 .
代表任何字符,它可以是数字、字母、符号任何东西
现在,它所做的是,从开始匹配 3 个字符,在我们的例子中是“嘿”,并用用户指定的字符串替换它。
Ruby:扫描方法
变量一个包含一些值。使用scan()
方法,我们将扫描变量 a ,并使用正则表达式,我们读取字符并以我们想要的方式显示它。
正则表达式(/.../)
读取三个字符,并将其临时存储在变量 x 中,使用该值我们可以进行所需的操作。如前所述,点代表任何字符,因此它可以读取任何三个字符(包括空格)。我们刚刚打印了 x 的数值。
在正则表达式中,我们使用了'\S'
。\S
为非空白字符。可以是号或任何字母。我们给出了三个 \S\S\S ,它遍历变量,找到三个非空白字符,存储在变量 x 中。
首先读取 x 的"Rub"
店铺并打印出来。然后它读取"y"
即 y 和一个空格,它忽略它,因为它包含空格字符。同样,典型中的"a"
和"l"
被忽略。
Ruby 异常处理
原文:https://www.studytonight.com/ruby/exception-handling-in-ruby
Ruby 中的异常处理涉及到我们如何处理程序中出现的错误。通过错误,我们不是在谈论语法错误,例如拼写错误 Ruby 关键字。我们指的是程序无法恢复的错误,程序员不会预料到但它可能会发生。好的程序员预见到它们并采取行动来处理它们。
异常由于程序运行时系统无法处理的事情而发生。
Ruby:例外的例子
在上面的程序中,我们试图用零除一个数。运行程序时,它会给出以下结果:
出现一个ZeroDivisionError
是因为我们试图用一个数字除以零,而这个操作在 Ruby 中没有定义。
让我们看另一个例子:
以下是上述程序的结果:
当我们执行这个程序时,我们会得到一个错误(没有这样的文件或目录),因为程序试图打开磁盘中不存在的文件。同样,当我们键入程序时,编译器无法知道该文件是否存在。
在这两个例子中,程序完全终止,这不是我们所期望的。所以,我们必须处理exceptions
,防止程序崩溃并退出操作系统。
鲁比:处理异常
当我们为分母输入 0 时,我们得到除以零的结果。
我们必须隔离导致exception
的代码。因此,如果出现异常,我们可以将控制转移到处理该异常的程序的另一部分。
我们是这样做的:
导致异常的代码写在begin
块中,rescue
块包含处理异常的代码。当begin
块中的代码引发异常时,控制自动转移到rescue
块,然后救援块中的代码执行,程序终止。
异常存储在全局变量!(exclamation mark)
中。语句print $!
打印异常。
上述程序的输出是:
当输入分母值 0 时,exception
升高,控制转移到rescue
块,并执行语句。它打印异常并提示为分母输入另一个值,然后执行操作,程序终止。这里程序不崩溃也不完全停止。但是这并不是这个问题的完美解决方案,因为当用户再次输入数值 0 时,会导致exception
再次被处理。我们必须使用循环以完美的方式处理exception
。
Ruby:处理多个异常
当一段代码引发multiple exception
时,我们必须以不同的方式处理它。例如,考虑下面的代码
begin
块包含引发“被零除”异常以及“文件未找到异常”的语句。我们只处理了“除零”异常。
现在,考虑一下这段代码:
这里处理“除零”异常,没有用。因此,在多个异常的情况下,我们必须特别注意异常的处理。
这里处理所有类型的异常。我们可以通过使用异常的名称来处理特定的异常。
我们通过指定名称处理了ZeroDivisonError
异常。
我们也可以有多个救援区块来处理每个异常。
我们有两个rescue
区块,一个用来处理ZeroDivisionError
,另一个用来处理未知的exception
。像ZeroDivisionError
这样的未发现异常的文件没有特定的异常名称。但是我们可以用SystemCallError
例外来处理一般的例外情况。
当发生一般异常情况时,控制转移到第二rescue
块处理exception
。我们还可以将异常消息存储在变量中。像这样,
输出结果是:
异常ZeroDivisionError
的实际错误信息存储在变量零中,我们打印该变量。
Ruby:引发异常
我们可以在 Ruby 中创建自己的异常来处理 Ruby 无法识别的错误。使用raise
关键字创建用户定义的异常。
程序的输出是:
这里,执行第一条语句,我们已经提出了我们的异常。但是最后一条语句没有打印出来,因为当异常出现时,程序完全终止。
Ruby 文件处理
在本教程中,我们将学习 Ruby 编程语言中的文件处理。我们将通过简单的代码示例学习如何从文件中读取数据、将数据写入文件、将数据追加到现有文件中。让我们开始吧。
鲁比:阅读文件
读文件在 Ruby 中比其他语言非常简单。
这是名为sample.txt
的文件的内容。现在,我们将阅读这个文件的内容。
这段小代码可以读取任何文件的内容。你可能会困惑于文件名没有声明。我们可以在运行程序时在Command Prompt
中指定文件名。
We run by: ruby files.rb sample.txt
输出如下:
这是读取文件的一种方法。我们也可以通过在程序中指定文件名来读取文件。像这样:
这里,我们使用open
方法打开文件。变量文件在这里充当文件处理程序。因此,对于每一行,我们使用variable
文件调用gets
方法,并将其存储在变量行中,使用puts
方法打印。
程序的输出是:
鲁比:在文件中写作
我们必须使用new
方法创建一个File object
来从文件中读取数据或将数据写入文件。
这里 fil 是使用new
方法创建的文件对象。新方法有两个参数,第一个参数是文件的name
,第二个参数是mode
。w
代表文件的写入模式。我们使用带有print
和puts
方法的文件对象fil
来直接写入文件。
当我们完成时,我们应该总是close
文件。完成后总是close
文件是一个很好的做法。如果我们不关闭文件,有时当我们稍后尝试打开它时,文件可能会损坏。使用print
和puts
方法打印的数据存储在缓冲区中,缓冲区在我们关闭文件时被刷新。
程序的输出是:
实际上,当我们执行程序时,什么也不会发生。但是当我们查看文件时,内容是写在文件中的。这是另一个例子,
Unity3D
游戏开发概念
游戏工程导论
原文:https://www.studytonight.com/3d-game-engineering-with-unity/introduction
这门课程需要很大的耐心和奉献精神,在本教程中,你将学习到许多有趣的元素和组件,这些元素和组件你一直想知道,关于游戏是如何开发和设计的。
这是一个教程,它将为你提供游戏开发所需的所有内部架构和组件的详细概述。
什么是游戏?
嗯,你们都听说过游戏这个术语。游戏可以被定义为一种为了娱乐而注册的活动,作为一种准备好的游戏形式,基本上是为了娱乐和/或作为一种教育工具。
根据数学模型研究博弈论,在玩游戏时,参与游戏的候选人之间要么是赢,要么是输,要么是平局,这是基于游戏过程中所做的动作或决定。
几乎每款游戏的关键组成部分都是它的目标、规则和惯例、挑战和互动。当一个玩家玩任何游戏时,它通常涉及精神或身体刺激,并且经常两者都有。这最终也提升了人类的感官、反应和思考能力(我们将在游戏工程和玩部分的优势中讨论)。许多游戏有助于发展实用技能(如模拟游戏),而其他游戏则是一种锻炼形式(虚拟现实和面向 X 盒的游戏),而其他一些游戏有助于发展教育或心理潜力。
什么是电子游戏?
视频游戏可以定义为在电子设备上运行的游戏,该游戏涉及人类与用户界面(UI)进行交互,以在任何视频设备(如电视屏幕或计算机监视器)上生成视觉响应。这种电子游戏由用户玩时,会处理一组图形、图像甚至音频,使游戏更具互动性。
简单来说,视频游戏就是人类通过电脑、电视、智能手机、平板电脑或其他游戏机“玩”的数字娱乐平台(它是一种软件形式)。视频游戏中的视频一词是人们使用光栅显示设备(在某些地方仍在使用)时出现的传统附加词,但在 20 世纪后,该术语被用于任何类型的能够产生二维或三维图像/视频的显示设备。
游戏开发
游戏开发是创建视频游戏的过程,包括在一些平台/软件上开发游戏。开发由游戏开发者承担,可以是游戏工程师(用于构建整体结构和游戏玩法)设计师(用于设计对象和动画)编码师(用于编码并赋予游戏生命,包括逻辑、分数和其他计算)项目经理(用于管理和推广游戏)游戏测试员(游戏开发完成后将对游戏进行测试,以发现游戏中的 bug,如有)。所有这些人力资源都归属于游戏开发者,开发完整游戏的过程被称为游戏工程。
第一个电子游戏是在 1960 年开发和发行的。但是为了运行这些游戏,需要大型计算机,而普通大众(在当时)无法使用。后来,商业游戏在 20 世纪 70 年代随着第一代电子游戏以及游戏机和家用电脑(台式机)的出现而诞生。
谁是游戏开发者?
游戏开发人员是从零开始创建游戏的人,他们像专门从事视频游戏开发的软件开发人员一样工作——开发人员的重点在于创建视频游戏。一个游戏开发者的团队可能从一个承担所有任务的人(开发一个完整的游戏)到一个开发游戏的大型商业公司——责任在各个学科之间分配,如编程、设计、艺术和游戏策划、测试等。
需要注意的是,一个小游戏可以由一两个人开发(比如马里奥、拼图、迷宫),但涉及到 GTA、IGI、NFS、COD 等大型游戏时,则需要一整个开发团队的努力才能完成游戏并取得成功。
有开发人员专门从事不同的游戏开发软件(如统一 3D、虚幻等)或动画软件(如自动索引玛雅、搅拌机等)。此外,开发人员可能专门从事某个游戏平台或游戏控制台(如任天堂的 Wii U、索尼的 PlayStation 4、微软的 X-box 等),而其他开发人员可能为个人电脑或智能手机等特定设备开发游戏。
游戏开发工具
游戏开发工具是专门的软件解决方案,允许和促进视频游戏更容易的开发。在开发游戏时,开发团队可能需要动画软件来设计玩家、树木或游戏中使用的任何其他对象;或者一个程序员可能需要 Visual Studio 或者 MonoDevelop 编辑器来注入特定的代码来移动一个游戏对象,所有这些工具都在 Game development tools 下。换句话说,我们可以说开发完整游戏所需的工具属于游戏开发工具的范畴。所有这些工具都有助于设计游戏。
游戏开发概念
原文:https://www.studytonight.com/3d-game-engineering-with-unity/game-development-concepts
游戏开发是计算机科学最令人兴奋的领域之一,也是软件开发行业的重要组成部分。电脑游戏在全球范围内构成了一个庞大且不断扩大的市场。
交互式数字媒体和游戏以及娱乐应用在个人电脑的日常用户中掀起了巨大的热潮,并在提供经济实力方面发挥了重要作用(因为游戏不是免费的),这是一个不容忽视的因素。
因此,游戏开发也将不断产生新的想法和互动设备,使游戏玩得更有吸引力和刺激。对于这款游戏,开发者需要接受良好的培训,并配备他们的开发技能。
游戏开发的一个重要特点是,学习者和开发者应该想出新的想法和一个朗朗上口的情节,把剩下的留在这门课上,因为到本教程结束时,你将拥有游戏开发所需的特定技能。据观察,德国通过在德国各地建立游戏学院,为愿意开发游戏的学习者提供设施,这些学院侧重于与游戏开发相关的特定培训。
在这里,study now为读者提供了一个免费的机会来建立自己的学院,按照自己的节奏学习,并根据自己的想法和技能开发游戏。
如何开发一款好游戏?
成为一名优秀的游戏开发人员需要大量的实践,根据你的想法和一步一步的方法来工作。
第一步,就是拿出一个游戏的计划/蓝图。不遵循适当开发方法的游戏会遇到以下问题:
- 开发所需的时间更多。
- 超出预算。
- 倾向于不合理的错误。
所以,给新游戏开发者的建议是,在继续设计和编写游戏之前,修正一个明确的目标,弄清楚你的游戏需要什么。游戏开发的这一阶段称为需求捕获或规划阶段。您也可以使用形式化语言,如统一建模语言(UML) (我们将在后面的章节中详细讨论)。在“需求捕获”或“规划阶段”,游戏开发人员可以使用案例图,快速收集关于需求的见解(例如,需要多少设计师、程序员、测试人员或开发工具——游戏引擎、动画工具和其他建模工具以及游戏玩法或故事情节或游戏的目标和级别),以有效管理和成功完成您的游戏开发。
游戏工程团队管理
你的开发团队将不得不面对某些挑战(如果你不是单独开发游戏的话)。您或团队成员可能面临的一些问题包括:
- 每天都有新的功能和工具在网上发布,您的团队成员必须管理和升级他们的技能。
- 可能会有内部纠纷或个人问题,你的团队经理应该巧妙地处理。
- 好的测试人员应该被雇佣来使你的游戏没有错误,否则你的游戏可能无法达到相当高的人气,甚至无法达到你设定的目标。
因此,项目经理应该选择合适的、熟练的设计师、开发人员和测试人员,让团队协同工作。
游戏开发就是软件开发
游戏开发所需的步骤和阶段遵循类似于软件开发的阶段,以及一些成功完成游戏的额外阶段。由于游戏开发是软件开发行业的主要部分,因此游戏开发也经历了 SDLC(软件开发生命周期)的各个阶段以及一些额外的阶段。让我们详细解释一下这些阶段。
软件开发生命周期是软件工程中用于开发预期软件产品的结构良好且安排有序的阶段序列。同样的结构也需要游戏开发者遵循。这些阶段是:
-
Communication:
这里,用户发起开发期望游戏的请求。然后他/她联系开发商或项目管理公司,并试图讨论条款。然后在成功达成协议后,第二阶段将开始。如果用户自己是 hame 开发者,那么它直接从阶段 2 开始。
-
Requirement Gathering:
在这一阶段,游戏开发团队讨论进行项目的要求,项目经理将决定项目所需的人力资源数量。该团队将与不同的利益相关方进行讨论,以讨论不同领域的问题,目的是根据他们的要求提供尽可能多的信息。
-
System Analysis:
在这个阶段,开发者将决定一个成功的游戏开发计划的路线图,直到发布,并尝试提出适合项目的最佳软件模型(我们将在下一章详细讨论软件工程模型)。该阶段还包括事先正确理解产品的局限性或现有系统中所需的变更。
-
Systems Design:
在开发的这个阶段,期望的特性和详细的工作,包括游戏,目标和水平的设置,屏幕布局,玩家和游戏对象模型;在游戏、商业规则、流程图(UML、DFD)、伪代码和其他文档(GDDs)中创建动画。
-
Development Phase:
游戏的真正代码将在这个阶段编写。这可以来自一个伪代码或一组写在 GDD(游戏设计文件)的算法。
-
Integration and Testing Phase:
在这一阶段,游戏的演示版本发布,试用期为 15 天或 1 个月。这是由团队自己正式完成的,以检查错误和受欢迎程度。随着这款游戏的部分发行,推广也在 YouTube 等网站和其他游戏网站开始。同时,测试人员被雇来检查游戏中的错误。
-
Final Release Phase:
测试和推广完成后,游戏的最终发布就完成了。
-
Maintenance Phase:
在这个开发阶段,游戏的适当维护是有保证的。检查游戏是否运行平稳或变得过时,同时收集、分析并使用来自游戏用户的反馈来改进游戏本身。
-
Patches and Cheat-Codes:
团队自己发布补丁(bug 的热修复)和作弊代码,这样新手玩家也有动力玩完整个游戏,并找到轻松进行关卡的兴趣。还有 mods (修改器)也是在游戏发布 6-10 个月后发布的,也是更新游戏增加额外特性和功能的补丁(增加新自行车或插入新型号的枪)。
因此,所有这些阶段都必须遵循,才能让游戏成功。
游戏开发生命周期模型
原文:https://www.studytonight.com/3d-game-engineering-with-unity/game-development-models
因为在最后一章,有很多话题/术语没有解释清楚,所以让我们试着帮助你理解整个画面。首先,让我们讨论一下软件/游戏开发生命周期模型,这通常是在公司或个人公司遵循的。
如果你是一个初级游戏开发人员,我们理解你很难遵循这些生命周期模型,但是了解它们并没有坏处。
生命周期模型
有很多提议的软件/游戏开发生命周期模型,它们在开发过程中遵循特定的生命周期。这些模型也被称为流程&开发模型。所有这些模型都遵循一系列循环形成的步骤,这是其类型所独有的,以确保其开发阶段的成功。
所有公司和游戏开发商都遵循的一些著名开发模式如下:
瀑布模型
它是最古老和最常用的模型,遵循简单和直接的方法——根据这种方法,首先完成一个阶段,然后进入下一个阶段(不后退)。瀑布模型的每个阶段都依赖于前一阶段传递的信息。更容易理解和有效管理。
这种模式在游戏开发的早期(1980 年代到 1990 年代中期)非常流行,因为在整个开发过程中需求是不变的。但是现在,需求每天都在变化,因此遵循这种模式不是一个好的选择。它可以用于小游戏项目。
螺旋模型
这是一个灵活的模型。螺旋模型有一个重复的方法,以循环的方式前进,项目以螺旋的形式一遍又一遍地经历四个阶段,直到完成,因此允许几轮细化。
在游戏开发中,螺旋生命周期模型的典型步骤是:
- 设计和规划
- 实施计划,或者换句话说,编写游戏代码。
- 玩测试:这包括玩游戏和分析游戏的改进,寻找 bugs 问题等。
- 对当前进展的评估。理解我们做对了什么,做错了什么,用新的观察点,回到第一步。
螺旋模型的优势
- 风险很低。
- 应该总是从核心特性的开发开始。
- 一个工作原型在更短的时间内就准备好了。
- 这种模式允许更快的变化。
- 该模型与 SCRUM 配合良好。
迭代模型
这里不是从完全已知的需求开始,您还可以在迭代之后开始实现一组软件需求、测试、评估和插入进一步的需求。在每一次迭代中,都会产生新的游戏版本。这种冲洗和重复一直持续到整个项目准备就绪。
v 形模型
这个模型也被称为验证和验证模型,这个模型诞生于瀑布模型,并且在其每个开发阶段具有并行运行测试活动的特征。和瀑布模型一样,V 型模型的每个阶段都依赖于它的前一个阶段。当所有的需求在手之前都很清楚的时候,这个模型就完美地发挥了它的作用,因为很难有一个向后的动作来做出任何改变。
大爆炸模型
它并不完全遵循 SDLC 方法论,或者换句话说,这个模型并不遵循任何特定的过程,在游戏开发时,只有非常少的时间花在规划和设计这个模型上。大量资源集中用于发展。这是一种不常见的方法,通常用于只有两到三个开发人员在开发游戏的小项目。
敏捷模型
在这个模型中,产品被分解成一组特性,因此它被用于快速交付工作产品,因此被认为是非常合理的开发方法。该模型生成项目的持续版本,每个版本都有小的和增量的变更,这些变更是从以前发布的版本更新而来的。在每个周期,项目都经过测试,然后发布。
关于敏捷的详细信息:敏捷原则
理解游戏架构
原文:https://www.studytonight.com/3d-game-engineering-with-unity/game-development-architecture
富有创造力和艺术感的人,在分享他们的梦想、想法和愿景中找到奉献。画家通过绘画做到这一点,而音乐家创作音乐。同样,程序员希望自动化,让你的生活变得轻松,游戏设计师希望通过他们的游戏让他们的想法和想法变得生动起来。
每一个标准游戏都由一些系列的关卡组成:嵌入并与游戏的故事情节紧密相关,要直播的动作和冒险序列,要体验的壮观视觉效果,它们通过探索和展现我们的战术和战略制定技巧来挑战我们的心智能力。游戏是所有娱乐媒介中最独特的,因为它能与观众互动。
大多数游戏都赋予玩家故事中最重要的角色:英雄。这是让玩家融入游戏的好方法。
游戏的架构
游戏的架构和结构类似于软件。但是它确实有一些额外的组件,这使得它不同于软件。每个游戏都有以下组件:
- 图形引擎
- 声音/音频引擎
- 渲染和视觉输入引擎
- 输入/输出设备(如鼠标、键盘、扬声器、显示器等)
- 动态链接库文件和驱动程序/设备接口
所有这些上面提到的组件结合在一起,使一个游戏可以充分发挥它的作用。在讨论它们之前,让我们先搞清楚什么是引擎。引擎是一个完整过程的自处理组件,它在原始过程之后自动运行。
图形引擎
图形引擎是一种软件,它与应用一起帮助在计算机的显示设备上绘制图形。
计算机领域中的引擎一词指的是帮助对程序执行某种确定类型的处理的软件,例如文本到语音引擎、数据库引擎、布局引擎和图形引擎。图形引擎有助于通过提高分辨率和单位面积像素数量来改善游戏图形。这个引擎也让你的游戏场景清晰流畅。
声音/音频引擎
音频/声音引擎是由处理声音的算法组成的组件,内置程序被写入其中以处理游戏中嵌入的声音效果。它能够使用中央处理器或任何专用的专用集成电路进行计算。抽象 API,如 Open-AL、SDL 音频、X-Audio 2、网络音频等。可以在这个引擎中使用。
渲染和视觉输入引擎
渲染引擎和视觉输入系统使用不同的技术,如光栅化和光线跟踪,生成三维动画图形。由于被编程和编译为直接在任何中央处理器或图形处理器上执行,大多数渲染引擎都是基于一个或多个渲染应用编程接口开发的,如为图形处理单元(GPU)提供软件抽象层的 Direct3D 和/或 OpenGL。
像 DirectX 或 OpenGL 这样的低级库被广泛地集成到游戏中,因为它们提供了对不同计算机硬件的独立硬件访问。这些硬件设备可以是输入设备,如鼠标、键盘和操纵杆;网络设备,如网卡和声卡。
输入输出设备
用于在计算机中输入数据和程序的设备称为输入设备。输入设备可以读取数据,并将其转换成计算机可以使用的形式。输出设备可以将机器加工的成品生成人类可用/可读的形式。对于游戏来说,用户和他/她玩的游戏之间应该有很强的互动。因此,像鼠标、键盘、操纵杆和显示器这样的外围设备在游戏互动中扮演着重要角色。
动态链接库文件和驱动程序/设备接口
一个 DLL(动态链接库)文件,是一种包含以程序形式编写的指令的文件,其他程序可以调用或使用这些指令来执行某些任务。以这种方式,不同的程序可以共享已经被编程到单个文件中的能力和特征。
这些系统级文件对构建游戏的架构起到了支持作用,并有助于使其表现良好。你可能已经注意到,如果你已经安装了一个你想玩的游戏,你点击了可执行文件(。exe 文件)来运行游戏,而就在游戏开始前,一条错误消息弹出,并带有一条消息-
同样,设备应用编程接口可以定义为应用编程接口,它允许开发人员创建任何最终可以与插入或安装在您系统中的硬件设备交互的应用。设备应用编程接口通常为最终用户提供使用其插入的或关联的硬件与系统交互的机会。大多数游戏(流行的)都需要这些设备驱动程序和应用编程接口来使游戏在所有组件成功运行的情况下工作。
这五个组件构成了游戏的内部和外部架构。
游戏引擎与游戏发展历史
原文:https://www.studytonight.com/3d-game-engineering-with-unity/game-engine
对于每一款游戏,游戏引擎都扮演着重要的角色,因为游戏引擎通过在场景、人物和图形生成、声音、人工智能、脚本动画、网络等方面提供帮助,帮助游戏设计者将游戏中的人物栩栩如生。游戏引擎就像一个集成的开发环境,有一套现成的可视化开发工具和可重用的软件组件。它通过提供抽象层,将复杂的游戏开发任务变得简单,这使得许多大任务看起来非常容易,而游戏引擎则在后台完成所有的硬件工作。换句话说,它是一个专门为电子游戏的构建和开发而设计的框架。开发人员使用这些游戏引擎为游戏机、移动设备和个人电脑创建游戏。
因此,那些对深入游戏开发、探索新技术和以游戏形式展示你的想象力感兴趣的开发人员或游戏爱好者,或者如果有人只是好奇想知道游戏引擎技术背后发生了什么,这里有一个构成游戏引擎的组件的详细解释。
游戏引擎的组件
游戏引擎是为了开发游戏而创建的,就像任何特定语言编程的其他 IDE 一样。游戏引擎中的所有组件都被构建和集成,以支持游戏开发的动机。
-
Input:
如果一个游戏不能玩,它就什么都不是,游戏引擎支持一系列输入设备,如鼠标、游戏手柄、触摸等,同时也支持游戏手柄、操纵杆等设备。处理输入有许多不同的方式,最常用的两种是通过:
events
和polling
。输入events
被计算机捕获(如鼠标右键点击,或按向上箭头键等),你的自定义代码根据收到的输入被触发。Polling
用于获取位置值,例如鼠标指针在哪个坐标(x,y)上,或者你玩游戏时使用的游戏杆或智能手机的倾斜角度。 -
Graphics:
游戏中的图形决定了它的命运。3D 图形是使用 3D 资产设计的,这些资产在外部 3D 渲染程序(如 Maya、Blender 等)中开发和设计,然后导入游戏引擎。因此,一个好的游戏引擎必须支持多种导入格式。
游戏引擎提供了许多功能,如灯光效果,阴影,凹凸贴图,混合动画等,使导入的资产看起来真实。
-
Physics:
游戏引擎有一个子组件,叫做物理引擎。物理引擎是一种软件,它允许对大多数现实物理系统进行相当精确的模拟,如刚体的运动(我们将在后面的章节中使用统一 3D 进行实际模拟)、软体质量和速度的改变以及流体动力学、弹性等。这些是集成在最新游戏引擎中的复杂引擎,主要用于视频游戏(通常作为中间件),其中必须描绘实时和真实生活的模拟。重力、碰撞检测、旋转&旋转、物体速度和其他此类应用由游戏内的物理引擎处理。
-
Artificial Intelligence:
如今,人工智能在游戏开发中扮演着重要的角色。根据情况或玩家的行为知道玩家将使用哪种武器会被记录下来并相应地执行动作,这可以使用嵌入游戏中的专门软件来完成。在游戏中实现人工智能通常是使用现成的脚本来完成的,这些脚本是由专门从事人工智能的软件工程师设计和编写的。例如:我们的角色如何对撞墙、看到动物等做出反应可以通过构建一系列行为节点来轻松完成,而不是编写复杂的代码。
-
Sound:
音频和渲染引擎是游戏引擎的一个子部分,用于控制声音效果和在 2D 屏幕上生成三维动画图形。它们使用多渲染应用编程接口(如用于视频渲染的 Direct3D 或 OpenGL)和应用编程接口(如用于音频的 Open-AL、SDL 音频、X-Audio 2、网络音频)来提供图形处理器的软件抽象。
-
Networking:
从十年前开始,游戏就支持在线多人游戏和社交游戏,这将你的游戏冒险与你的朋友联系起来。大多数游戏引擎都为这些需求提供了完整的支持和脚本,因此您不必担心 TCP/UDP 流量、社交 API 集成等。
游戏发展历史
如何制作游戏?这是游戏行业最难以捉摸的问题。事实上,整个软件行业对于软件工程过程作为一个整体是多么的不成熟是相对开放和前沿的。看看史蒂夫·麦康奈尔的《淘金热之后》,了解软件行业急需的成熟度的精彩讨论。软件工程界的许多开发工作都在致力于改进我们制作软件的过程。
在 60 年代和 70 年代,从 Fortran 和 COBOL 到 C,编程语言的实力有了很大的提高。在 80 年代,微型计算机在编程领域带来了巨大的进步。每个开发人员都可以有自己的工作站,在那里编辑、运行和调试代码。
在 80 年代末和 90 年代初,软件开发社区的前沿被面向对象编程的功效和 C++的大项目优势所吸引。集成的编辑器、调试器和分析器继续改进。
优化编译器几乎使汇编编程过时,可视化界面布局工具使编程对业务应用来说相当愉快。随着软件开发过程中所有这些奇妙的改进,软件项目预算只会变得更大,只会随着时间的推移和数量的增加而减少。
不同类型的游戏
原文:https://www.studytonight.com/3d-game-engineering-with-unity/genres-of-game
我们开发的所有游戏都属于不同的预定义类别之一,这些类别也被称为游戏类型。在开发游戏之前,游戏工程师或项目负责人必须决定他想为他的观众开发什么类型的游戏。所以在这一章中,你将学习游戏的类型以及它们的特点。
游戏的类型定义了游戏的确切类别,并可以通过类似的游戏特性来传递,比如——目标和故事情节的类型、关卡和摄像头点(即 FPS、TPS)、游戏展示的功能和故事情节。游戏的类型不是由内容或游戏模式来定义的,而是由游戏所具有的共同挑战和特点来定义的。例如, FIFA 和PES-Pro Evolution football具有相似的属性和目标,因为两者都是足球比赛,当球队通过进球赢得比赛时,球员的得分或难度水平会提高,就像现实生活中的足球比赛一样。一个游戏的类型是由发现的相似性决定的,并被列在一个共同的标题下,在这里,国际足联和 PES 将归入体育-类型游戏。
所有游戏类型的列表
这里我们列出了游戏分类的主要类型。
游戏类型:动作
操作类别有一些子类别,如下所示:
- 潜行游戏:这些游戏倾向于强调技巧和精确打击更明显和毫不掩饰的射手。例如:金属齿轮系列、IGI 系列等。
- 生存游戏:这些游戏在敌对状态下以玩家最少的资源开始,伴随着开放的世界局势,目标是收集资源、工艺工具、炮兵和武器&保护,以便在游戏进行过程中玩家的生存。
- 射击游戏:在这些游戏中,玩家会抽取一系列武器,为远处发生的动作做出贡献。
- 平台游戏:这些游戏设置在三维(3D)环境中,玩家引导角色穿过障碍物,在游戏中前进。
游戏类型:冒险
就像冒险电影一样,以冒险为故事情节的游戏充满了虚构的风景、人物等。这些游戏描绘了一种不同的游戏方式,没有过度的反射、硬核挑战或动作。重点在于玩家通过与环境互动来解决谜题或谜团。马里奥、铁皮都是冒险游戏的例子。冒险游戏的一些类别有:
- 图形冒险
- 视觉小说(基于小说和故事) -哈利波特(使用 PlayStations、X Box 和其他游戏机播放)
- 互动冒险(基于电影) - Tin-Tin,蝙蝠侠等
- 实时 3D 冒险 -记忆的阴影
游戏类型:角色扮演游戏
在这样的游戏中,玩家被选中在充满无数冒险者的故事情节中扮演主要角色,并且擅长特定的技能组合,并且玩家在故事情节中的进步增加了他的技能和力量。这一类别是最著名的类型之一,由世界各地的游戏玩家玩。以下是角色扮演游戏的一些子类别列表:
- Rogue like Game:它是一个子流派,名字来源于 1980 年电脑游戏 Rogue 的游戏性元素。Nethack 是 roguelike 游戏的另一个例子。
- 奇幻游戏:暗黑破坏神、最终幻想、波斯王子等游戏有一个充满不寻常的角色和反派的世界,玩家必须完成充满挑战和神秘的关卡,还有一些隐藏的路线需要解锁才能继续游戏。
- 沙盒 RPG(开放世界 RPG): 这些都是现代游戏,玩家被赋予了完全的自由,可以自由漫游,做任何事情(即玩家不会被岩石&栅栏、单一目标等限制在单一路径上)。这类游戏的例子有著名的侠盗猎车手(GTA) 系列、看门狗系列等。这些游戏提供了一个大的地理区域来探索游戏的主要目标和任务。
- 大型多人在线角色扮演游戏(MMORPG): 这一术语于 20 世纪 90 年代商业化出现,自 1978 年以来一直存在。这包括数百名玩家在同一平台上实时互动和合作。
游戏类型:模拟游戏
这些主要是设计和开发来紧密模拟(复制)我们现实生活或虚构环境的所有方面。模拟游戏的不同子类别如下
- 养殖模拟
- 车辆模拟
- 生活模拟
- 管理模拟
游戏类型:策略游戏
这里的主要焦点在于游戏性,这需要一个谨慎和熟练的心态和一个好的计划来取得胜利。著名游戏工程师安德鲁·罗林斯(Andrew Rollings)说,在大多数策略游戏中,“玩家被赋予了一个游戏的神一样的愿景,世界相对于它而存在,并以某种方式控制着他指挥下的单位。”
- 4X 游戏: 4X 游戏是指具有四个主要目标的特定形式的策略视频游戏的类型,这四个主要目标是-
- 探索
- 展开
- 开拓
- 消灭
- 实时策略(RTT)和战争游戏:实时策略游戏的特点是在游戏内获取资源、建造基地等资产,玩家为了应对不断变化的游戏状态,不得不不断做出具体的决策和执行某些动作。例如:《帝国时代》等。
- 塔防:塔防游戏的格式和玩法都非常简单。通过部署合适的防御系统来摧毁敌军,让你的塔变得坚固。
- 多人在线战斗竞技场(MOBA): MOBA 游戏也被称为动作实时战略(ARTS) 游戏,这是战略游戏的一个分支,起源于一个实时战略游戏,玩家控制两个团队中的一个角色。
游戏类型:体育游戏
这些游戏模仿了在设备上进行的任何传统体育运动的游戏性。像棒球、篮球、足球等现实世界的运动都是以电脑游戏的形式出现的。随着你技能水平的提高,你的游戏也会模仿真正的职业运动员以及他们的移动和比赛方式。其子类型有:
- 赛车
- 室内运动
- 户外运动
- 战斗
- 竞争和杂项
科教游戏
有几个案例,许多家长和老师抱怨孩子玩电子游戏,但有几个伟大的教育游戏,实际上可以帮助孩子和孩子,甚至成年人学习新事物和收集知识。
其他杂项游戏类型
其他各类游戏有:
- 休闲游戏
- 编程游戏
- 逻辑游戏
- 音乐游戏
- 派对游戏
- 琐事游戏
- 棋盘游戏/卡牌游戏
理解游戏类型的好处
在开始游戏开发之前,了解游戏的类型是非常关键的。如果你在为某个游戏开发项目的客户工作,试着去理解你的客户心目中的游戏类型,它会帮助你完成以下工作:
- 设计游戏的主题。一个冒险游戏在有森林背景的情况下看起来不错,而一个为学生设计的游戏在有彩色背景的情况下看起来不错。
- 游戏声音也取决于游戏的类型。
- 游戏中使用血腥和暴力只建议 18 岁以上年龄组的玩家玩动作游戏。
因此,一旦游戏的类型被定义,你就会有很多想法。
为游戏创建动画的基础知识
原文:https://www.studytonight.com/3d-game-engineering-with-unity/basics-of-animation
您可以将动画视为通过快速显示一系列彼此差异最小的图像来制造运动错觉和变形错觉的技术或过程。只要放一本翻书。
创作动画的技术人员被称为动画师,他们是有创造力的人,拥有开发动画的专门技能。这些动画可以是模拟媒体或翻书、动画电影、视频和 GIF、数字媒体(包括动画 GIF、Flash 动画文件、视频等)的形式。
用于创建动画的方法包括两种传统的动画开发方法,包括停止运动动画,可以是二维或三维对象、剪纸、泥塑等。图像以快速的速度呈现,基本上每秒 24、25、30 或 60 帧。
而计算机动画用计算机生成的图像生成动画图像。三维动画需要计算机图形,而 2D 动画侧重于风格,低带宽和更快的实时渲染能力。
在游戏世界中,图形软件被实现用于创建动画效果。基本动画可以是通常在网页中使用的动画 gif 图像。当你不得不在电脑软件游戏或太空战动画中描绘一个人或外星人脸的动画复制品时,动画就变得复杂了。
一些动画软件的列表
下面是一些流行和广泛使用的动画和 3D 动画程序的列表。
- 搅拌机(免费版提供):T2】http://www.blender.org/
- 光波 3D:http://www.newtek.com/
- 弹性现实与狂热 3D:http://www.avid.com
- 玛雅:T2】http://www.alias.com/
- Macromedia Flash(提供免费版本):http://www.macromedia.com/flash
- 3d studio max:http://www . Autodesk . com/
- 3DPlus(免费):http://www.freeserifsoftware.com/
- 动画大师:http://www.hash.com/
- 动作捕捉:http://www.metamotion.com/
动画的类型
动画有三大类:
-
Traditional Animation:
传统动画也称为手绘动画,是一种每一帧都需要手工绘制的动画。这种动画制作方法成为电影院中最主要的动画类型,直到计算机动画的新时代到来
-
Stop Motion:
这个术语基本上描述了动画的轮廓,它可以通过物理控制现实世界的对象并一帧一帧地拍摄它们来生成,以创建运动的错觉,其中帧作为连续的图像链按顺序播放。
各种类型的定格动画有:
- 木偶动画
- 剪切动画
- 黏土动画
- 物体动画
- 像素化
-
Computer Generated Animation:
计算机辅助或计算机生成的动画据说是由一个或多个二维平面组成的系统,该系统将传统的即手绘动画技术计算机化。
所有这些类别都可以用来制作 2D 和三维图像。此外,还有一些额外的、不太常见的形式,将它们的主要焦点投射在创建图像上,同时融合了实时动作和绘图或计算机生成的图像。其他一些动画形式有:
- 传统动画
- 基于 2D 矢量的动画
- 3D 电脑动画
- 运动图形
- 停止运动
在游戏开发中,对能够开发模型、对象和各种场景或游戏视图的动画师有着巨大的需求。所以,既然你已经有了动画的基础知识,我们希望你能够判断出你游戏中对动画发展的要求。
游戏项目管理和商业环境
原文:https://www.studytonight.com/3d-game-engineering-with-unity/business-context-of-game
每一个游戏项目,从预算超过 600 万美元的大型多人游戏开发到小而有趣的游戏(比如糖果粉碎),都需要有一个合适的商业计划。
在这种情况下,如果你没有一个从游戏中获利的计划,或者如果你的游戏项目没有与任何商业风险挂钩,仍然有一条很好的路线来识别——你为什么开发游戏,以及为游戏的未来设定了什么目标,你的计划。所以可以说,无论如何,业务端也很重要。
项目管理三角
项目管理三角形是分析任何游戏项目的目标和计划的有用工具,其中三角形的 3 个顶点代表:
- 预算
- 时间
- 范围
为了形成一个好的商业计划,你将不得不遵循一些项目管理程序来定义项目的需求以及各种其他方面。
项目管理三角就是这样一个模型,它允许项目经理根据预算、时间和范围因素,预测项目开发步骤在质量方面的公平性。
它有助于项目经理在计划阶段提前了解游戏项目开发过程中可能出现的困难,从而使项目管理更好。
软件开发和/或游戏开发行业有一条商业法则,规定你的项目可以实现一个项目的三个目标中的任意两个,但是没有办法同时实现这三个目标。
有一些项目开发人员没有理解这样一个事实,即三个项目三角形属性中一次只能有两个是可能的,这导致项目错过了所有这三个目标!因此,我们必须记住这样一个事实,我们必须努力使我们的游戏在任何两个指定的三角形属性中变得更好,并将第三个属性提升到一个适度好的水平。
三大制约因素
-
Budget:
每个项目都有一个附加成本,在设定的预算内完成项目很重要。有些时候,由于最初开发阶段的项目管理不善,按时完成项目变得困难。在这种情况下,额外的资源(更多的开发人员)被雇佣来处理项目,这增加了项目成本/预算。
-
Time:
当我们在一个项目上工作时,时间起着非常关键的作用,因为最后期限必须遵守。如果项目延迟完成,直接影响(增加)项目预算。
-
Scope:
任何项目的范围都是在需求和规划阶段预先决定的。项目团队在开发阶段开始之前就知道项目的可交付成果,并且必须在设定的期限内完成它们。另一方面,项目经理必须有能力处理需求/范围中影响时间和成本的任何变化。
质量
质量不是项目管理三角的三个约束之一,但它是最终目标。毕竟,每个团队都希望生产出最优质的产品。有些人混淆了质量和成本,认为只有高成本才能产生高质量的产品。这在某种程度上是正确的,因为没有好的资源,整个项目永远不会成功。
使用项目三角形
项目三角形的三条边由三个约束之一表示。通过对实际项目的研究和实验发现,一个项目遵守所有 3 个约束是非常罕见的,这意味着项目在设定的预算内按时完成,并且项目的所有可交付成果都已完成。
在现实生活中,如果一个项目开发计划在时间和成本方面保证了完成期限,那么它将错过项目的范围。同样,如果一个项目必须在设定的预算内完成,并且完成范围,那么它将花费比决定更多的时间。最后,如果你相信“时间就是金钱”这句话,并希望在时间截止日期之前完成开发,完成范围,那么你将不得不投入更多的资源,这将影响成本。
开发人员可以遵循市场上许多不同的应用开发策略之一,如瀑布、螺旋模型、迭代等。但是没有一个列出的开发技术和模型会神奇地解决所有的问题。在项目开发阶段,你迟早会面临这样一个问题:如何根据业务模型和三个约束有效地管理你的项目。遵循项目三角的可能结果可以是:
- 在预算和时间上:意味着你必须接受质量的牺牲
- 高质量和预算:意味着你必须接受一场迟到的比赛
- 高质量准时:表示你必须接受额外支出
评估您的游戏项目
原文:https://www.studytonight.com/3d-game-engineering-with-unity/game-project-survival
在投入时间、金钱和其他资源之前,明确你的项目愿景是非常重要的。
在你开始游戏开发之前,你应该不断问自己一些具体的问题来评估游戏开发的计划和行动方案。提前评估你未来的努力,作为你项目的生存测试。史蒂夫·麦康奈尔在他的论文《软件项目生存指南》中提到了自我评估项目的优势以及如何相应地行动。
这个测试的主要用例是快速大致了解你的整体准备情况,然后和你的团队一起为游戏项目计划你未来的步骤。建议在项目的开始或中间进行测试,并做出相应的反应或改变。
自我(基于项目)评估的问题
正如你所知道的,游戏开发遵循与软件项目开发相同的开发阶段。因此,对于每个阶段,您可以决定一组特定的问题,基于这些问题,我们可以评估我们的项目开发工作。以下问题根据不同阶段进行划分:
对于游戏需求阶段
- 你的游戏是否有清晰、明确的愿景陈述?
- 你的团队成员相信你提出的愿景并认为它是现实的吗?
- 该项目是否对出版商或公司以及开发者都有任何盈利的现实期望?
- 游戏的内部玩法和 UI(用户界面)有没有用描述的方式展示出来,让每个人都能毫无疑问地理解游戏的主要目的?
- 你的团队成员认为游戏项目会有趣和令人兴奋吗?
对于规划阶段
- 你的游戏有详细的书面设计和开发文档吗?
- 您的游戏是否必须提供清晰的书面技术文档,说明项目中需要使用的技术内容?
- 你的游戏有详细的、书面的美术制作准备吗?
- 议程中有没有列出所有需要执行的任务的综合项目?
项目开发阶段
- 你的游戏有没有一个管理人员:一个项目负责人或者首席设计师来处理整个项目?
- 你的项目的里程碑是否有清晰的、可测量的可交付成果?
- 所有团队成员以及项目负责人都有合适的工作量吗?他们有足够的时间处理大型项目吗?
- 您的开发人员是否可以访问匿名交流平台或渠道,在那里他们可以毫不犹豫或恐惧地就游戏开发过程中的问题给出反馈或报告?
- 您的项目是否有一个明确的方法来定义团队领导如何评审变更?
- 是否所有的源代码都在 Perforce、Git 等版本控制软件下?
技术设计文件和游戏设计文件
原文:https://www.studytonight.com/3d-game-engineering-with-unity/tdd-and-gdd
本教程将讨论技术设计文档和游戏设计文档,教你如何讲述你将在游戏中使用的技术特性和元素。本课将向您介绍一份技术设计文档和一份整体游戏设计文档,以及在创建游戏时整合技术计划所涉及的工作。
面向对象设计
现代数字游戏可以被认为是大型软件项目,由数千行代码到数百万行代码组成。面向对象设计(OOD) 应运而生,处理大型软件项目。GDD 或 TDD 是牢记 OOPs 的所有要求以及其中的实施细节(技术细节的 TDD 和整个游戏细节的 GDD)。
技术设计文件
技术设计文档为您团队中的软件工程师提供了一个蓝图,以实现和编码您游戏的功能。技术设计文档将让您的开发人员指定需求是什么,它们应该如何实现,以及实现所需的工具和技术。软件的结构设计和技术设计文档之间的联系是技术设计文档比软件架构图范围更广,细节更少。
TDD 通常包含以下信息:
- 所有功能的列表。
- 游戏引擎的选择
- 高级图表
- 关于 3D 对象、地形、场景的详细信息。
- 物理引擎的使用
- 游戏逻辑与人工智能
- 视听细节和规格
- 建立关系网
- 交付平台&在系统上运行游戏的硬件/软件要求。
这里我们有一个非常好的 TDD 示例(由一些学生为他们的大学项目设计): TDD 示例
游戏设计文档(GDD)
任何人说 【签入设计文档】 的时候,基本都是指游戏设计文档(GDD)。本文档详细解释了游戏中的所有角色、阶段或关卡、游戏机制、视图和场景、故事情节、各种菜单和选项等。
游戏设计文档是一组文档的一部分,这些文档指定了您正在创建的游戏的完整细节。所有这些文件,统称为生产计划:
- 概念或愿景文件(提案)
- 艺术设计文件
- 技术设计文件
- 项目进度表
- 软件测试计划
- 风险缓解计划
游戏设计文档可以内部分为三个子部分,其中文档的每个部分描述了游戏项目的一个特殊阶段。描述了从概念到设计到生产的三个发展阶段。这些是:
概念文件
概念文件是一份建议书,其中规划了整个目标以及工具和人力资源需求。这有助于清晰地设定我们(或整个团队)的目标,以便每个目标都在同一页上。
它也是合作伙伴的销售工具,他们会将产品带到市场上进行销售和宣传。在这个阶段,你也可以开始使用一个微型原型,这将会给你一个实验和修改你的想法的机会。
在这份文件中,诸如:故事情节叙述,类型,目标受众,最引人注目的特点,成本,开发时间等信息被指定。
设计文件
在这个游戏设计文档中,艺术家、动画师、声音工程师和开发者之间有一个活跃的讨论。这些文档经常被用来通过添加注释、分享想法等来消除混乱。游戏设计和开发所需的工具和软件也是用适当的预算编写的。
设计文档是为了确保最终产品与您预期的一样。
生产文件
这是游戏设计文档的最后阶段,在这里,生产管理人员和开发人员的团队共同创建最终产品。大部分的游戏设计者只是为了一些特定的游戏设计目的而被外包。而游戏制作团队和游戏开发者纯粹是该公司的内部人力资源。这个阶段还保留了关于开发人员数量以及分配给他们的工作的细节。
该文档充满了时间管理图表、任务数据库、预算电子表格、技术规范等。
这里我们有一个非常好的 GDD 例子(由一些学生为他们的大学项目设计): GDD 例子
Unity
使用 Unity 引擎的游戏设计
原文:https://www.studytonight.com/game-development-in-2D/introduction
所以你想成为一名游戏设计师。这是一个非常有趣的职业选择;我们必须提到,这是一条漫长的道路,有超过你的份额的路障和挑战,你必须克服。但这也同样值得。毕竟,没有什么比看着一个你在你的头脑中创造的世界,在你面前复活,准备好被玩,准备好讲述你的故事更好的了。****
**更不用说还有一些硬通货要赚。美国游戏设计师的平均年薪约为 8.4 万美元。
游戏设计师,是所有事情背后的人。是一个设计师想出了马里奥越坑越管的主意,他们是决定机枪中一个夹子能装 34 发子弹的人,他们是决定游戏是否是多人游戏的人。他/她是集团创意总监。他们还负责与艺术家、作曲家、配音演员、程序员、测试人员等合作,以确保团队拥有所需的所有专业知识。
兴奋吗?你应该是。然而,作为一个初学者,从游戏制作开始(注意游戏制作和游戏设计的区别),你很可能会自己做很多团队成员的工作,或者在一个小组里。这就是为什么本教程系列旨在让你在职业生涯中不断进步的同时,自己或与自己的团队一起制作游戏。我们将使用什么来制作这些游戏?我们要怎么做?
你所有的问题很快就会得到回答。
为什么你不应该忽视 2D 奥运会?
在这样一个游戏盛行的时代:
为什么要做 2D 游戏?人们还在玩那些游戏吗?尤其是自从你把你的老 NES(任天堂娱乐系统)连上电视,整天玩 T2 魂斗罗(T3)以来,已经很久没见了?
这是因为 2D 奥运会还没有失去魅力,而且很可能永远不会。如果他们这样做了,你今天知道的大多数安卓游戏都不会存在,许多最初作为 2D 概念的 3D 游戏也不会存在。2D 游戏开发对你的资源来说也没那么费力,因为你的项目中少了一个需要处理的维度。这意味着它非常适合初学者和资源较少的小团队。
如果你仍然不相信,看看这些美丽的 2D 奥运会:
这些都是 2D 游戏。是的,就连上图的忍者游戏。
Unity 简介
Unity 最初发布于 2005 年,是一个游戏开发环境和超过 20 个不同平台的引擎。它在MAC OS X****Linux和 Windows 上运行。
Unity 以其简单易懂的界面很快成为了人们开始游戏制作的首选。频繁的更新、良好的文档和更好的社区使它成为最好的工作引擎之一。2013 年,随着 4.3 的更新,Unity 发布了各种工具,供团队和开发人员在上面制作 2D 游戏,使任务比以前简单多了。Unity 也是我个人的最爱,因为它是我最早学会使用的游戏开发程序之一,它确实激发了我进入游戏制作行业的热情。
所以,受够了历史和看似明目张胆的广告,让我们咬紧牙关。要获取最新版本的 Unity,只需前往位于unity3d.com的 Unity 网站
打开网页后,点击按钮获得 Unity。
向下滚动,您会发现:
点击尝试个人按钮,获取安装程序。您看到的安装过程几乎是您安装的任何程序的标准过程,尽管我将特别注意以下屏幕:
看到那个突出显示的东西了吗?那是你应该在继续之前停下来思考的地方。雄心勃勃的新开发人员会检查列表中的每个框。别这样。你应该做的,是思考你的目标。如果你对制作安卓游戏或手机游戏感兴趣,请在安卓和 iOS 框中打勾。基本上,抓住你需要的,不要,你不会的。
你的硬盘会感谢你的:)
安装 Unity3D 游戏引擎
原文:https://www.studytonight.com/3d-game-engineering-with-unity/installing-game-engine
游戏开发需要使用一个 IDE 和一两种编程语言。这个 IDE 将是你开发游戏项目的游戏引擎。在本教程中,我们将学习如何安装/设置并使用 Unity 游戏引擎将其用作您的游戏开发环境。
为窗口设置 Unity3D 环境
要使用 Unity3D,您必须从 Unity 的官方网站下载安装程序。为此,只需遵循给定的步骤。
-
从链接下载并安装 Unity 编辑器:unity3d.com/get-unity/download/archive
-
点击下载(适用于 Windows)按钮,将显示如下选项的下拉列表:
选择您需要的选项并开始下载。
-
安装程序使用下载助手,并有您需要遵循的详细说明。 Unity 下载助手是一个重量轻、体积小的可执行文件(。exe)程序,该程序将允许您选择要下载和安装的 Unity 编辑器的组件。
-
选择要安装的编辑器组件,然后点击下一步按钮。
-
下一步,如果不确定要安装哪些组件,可以保留默认选择,点击下一步继续,按照安装者的说明进行。
在下面显示的截图中,一些复选框是:
- 用于 Unity 的 Microsoft Visual Studio 工具(是必需的)。
- Windows 构建支持(如果你也计划制作基于 Windows 手机的游戏)。
- 安卓构建支持(如果您计划使用 Unity3D 制作基于安卓的游戏)。
- 休息,保留默认选中的复选框。
-
现在,让该安装程序下载并在您的电脑上安装 Unity,然后在安装完成后启动 Unity 游戏引擎。
在 macOS X 上安装 Unity
我们可以使用命令行在 Mac OS X 上安装 Unity3D,也可以使用 Unity 下载助手。
使用下载助手安装
-
从链接下载苹果电脑的Unity 安装程序文件:unity3d.com/get-unity/download/archive
-
将下载一个
.dmg
文件名unitydownloadstant。双击它开始安装过程。双击 Unity 下载助手图标开始安装。
-
同意条款和条件,点击继续。然后你会被要求选择要安装的软件包,坚持默认的,如果你是初学者。
使用命令行安装 Unity
-
从链接下载苹果电脑的Unity 编辑器文件:unity3d.com/get-unity/download/archive
-
单独的 Unity 编辑器作为
.pkg
文件提供,您可以使用命令行安装。 -
这将被安装到指定目标卷上的文件夹/应用/Unity中。首先键入以下命令-
sudo installer [-dumplog] -package *Unity.pkg* -target /
这里 Unity.pkg 是我们在第一步下载的文件名。
-
现在,要安装标准素材,将其安装到指定卷上的文件夹/应用/Unity/标准素材中,请使用以下命令-
sudo installer [-dumplog] -package *StandardAssets.pkg* -target /
文件 StandardAssets.pkg 可以从我们在步骤 1 中下载 Unity Editor 文件的同一个下拉列表中下载。点击选项标准素材。
-
要在指定卷上安装位于文件夹/用户/共享/Unity/标准-素材中的示例项目,命令将是-
sudo installer [-dumplog] -package *Examples.pkg* -target /
文件 Examples.pkg 可以从我们在步骤 1 中下载 Unity Editor 文件的同一个下拉列表中下载。点击选项示例项目。
素材商店
基于 Unity 的游戏开发者也可以从素材商店获得素材。只需遵循下面给出的链接:
参观:Unity 素材店
Unity3D 简介
原文:https://www.studytonight.com/3d-game-engineering-with-unity/introduction-to-unity
在本教程中,您将了解Unity3D 游戏引擎和Unity3D 的基本元素。
Unity 是目前全世界开发者使用的最流行的游戏引擎,这是有充分理由的。它有一个强大的可视化界面,用于制作游戏、跨平台开发和活跃的贡献社区。Unity 是一个跨平台游戏引擎,主要用于为 PC、控制台、移动设备和网站开发视频游戏和模拟。它是由 Unity Technologies 开发的,并在 2005 年的苹果全球开发者大会上首次仅针对 OS X 发布,此后它几乎扩展到了所有可用的平台。
Unity3D 的特点
这里从技术角度列出了 Unity 的众多特性。这些是:
- 创建和销毁游戏对象
- 访问组件
- 游戏对象的事件
- 处理矢量变量和定时变量
- 面向物理的事件
- 协同和返回类型
Unity3D:界面/窗口
如您所见,Unity 的主编辑器窗口,您会注意到 Unity3D 的窗口是由小的独立窗口组成的,这些窗口可以重新排列、分组、从一个位置分离并再次停靠回主窗口。这表明编辑器的外观可能因项目和开发者而异。
Unity3D:项目窗口
它将显示可供使用的资源库以及您将在项目中实现的图像、音乐文件和其他附加文件。当您在项目中导入素材时,它们会出现在此处。
在“项目”视图中,就在“素材”上方,有一个收藏夹部分,您可以在其中选择并保存经常使用的项目。
左上角的创建选项可用于向项目添加新的素材。
Unity3D:场景视图
它允许开发人员为您正在创建的场景提供可视化导航和编辑功能。该视图能够根据您正在处理的项目类型显示 2D 视图和三维视图。您可以在此视图中移动 obejcts 以正确定位它们。
Unity3D:层次窗口
它显示了场景中每个可用对象的分层表示。它揭示了物体如何相互附着的形成过程。整个场景为父对象,添加到其中的对象成为子对象,这个概念在 Unity 世界中也被称为育儿。
Unity3D:检查器窗口
它允许开发人员检查和分析所选对象的所有可编辑属性。因为不同的对象类型具有不同的属性集,具有不同的布局和内容。例如,当您从项目窗口中选择一个资源时,检查器窗口将显示关于该资源的所有可用信息,并且可编辑属性可供编辑。
Unity3D:工具栏窗口
这是 Unity 编辑器中最重要的窗口。在左侧,它将包含操纵场景视图的主要工具以及其中包含的对象。
播放、暂停和步进控制也将在该窗口中可用。您还可以使用右侧的按钮和 Unity 帐户访问 Unity 云服务,以及可见性菜单&编辑器布局菜单,该菜单将为编辑器窗口提供一些交替布局。
基本上工具栏不属于窗口类别。
Unity3D:游戏视角
在这个窗口中,实际的游戏视图是由游戏中的摄像机呈现的。这允许您检查实际游戏视图的外观。
Unity3D 的游戏项目元素
原文:https://www.studytonight.com/3d-game-engineering-with-unity/elements-of-unity3d
有一组元素(或组件)共同组成了一个游戏,使用 Unity 引擎开发。这些元素在使游戏具有互动性以及增加能够生动表达游戏目标的功能方面发挥着重要作用。让我们讨论一下这些元素及其功能。
素材
素材是可以在游戏或项目中实现的项目项的表示。素材可以是从 Unity 外部导入的文件,如 3D 模型、音频和声音文件、图像(jpeg、gif、png 等)、纹理或 Unity 支持的任何其他文件类型。还有一个可以在 Unity 中生成的素材类型集合。
这类素材的例子有:
- 动画师控制器
- 音频混频器
- 渲染纹理
- 图片
- 动画文件
项目
Unity 中的项目是一个文件夹或位置,它保存着你完整的游戏项目以及它的所有相关资源,可能还包含库和资源子文件夹。
包装
这是一个预编译的游戏素材集群。Unity 附带各种包装。
游戏对象
游戏中的每一个物体都是一个游戏物体。从技术上来说,它们不会给你的游戏项目添加任何功能,而只是充当像变形、光、脚本和刚体等组件的持有者。您将在接下来的章节中了解它们,并以小项目的形式实际实现。
成分
组件是基本的构建模块,即游戏中对象及其活动的具体细节。它们充当每个游戏对象的功能块。默认情况下,每个游戏对象都有一个自动设置的变换组件,因为它规定了游戏对象在 Unity 环境中的位置,以及如何旋转和缩放。
景色
场景可以被定义为基础或父对象,在那里你可以放置你的游戏对象来制作一个游戏级别。一个或多个场景(又名关卡)通常被放入一个游戏中,它们被链接在一起,你的观众会通过清除一些特定的目标来穿越或通过。所有这些目标和游戏的逻辑都将被放入在场景中与玩家一起运行的方法中。
预制的
预设是放置在项目视图窗口中的可重用游戏对象组件。预设可以被引入到任何数量的场景中,你想引入多少次就引入多少次,每个场景。你可以创建这些预置的实例,链接到主预置。项目中有多少实例并不重要;当您对 Prefab 进行任何更改时,您可以可视化应用于所有其他实例的更改。您将在后面的章节中使用预设,同时开发小游戏项目。
建设
这是一个导出的改编你的游戏,将包含所有必要的场景播放在特定的平台。
使用 Unity3D 创建第一个项目
原文:https://www.studytonight.com/game-development-in-2D/hello-unity
开始做游戏你一定很兴奋吧!让我们不要再等了,点燃团结。闪屏后,您应该看到的第一件事是:
如果您看到此屏幕,只需点击左上角的项目选项卡。
点击新建项目,应该会看到如下画面。
您可以通过在标有 1 的字段中输入名称来为您的项目命名一个,您也可以通过单击标有 2 的三个点来选择项目在您的计算机上的存储位置。
现在,由于我们将在本系列中处理 2D 游戏设计,我们将继续点击单选按钮,在标有 3 的字段中显示 2D 。这告诉 Unity 我们想在 2D 奥运会上工作,因此它相应地建立了我们的基础项目。点击按钮创建项目**,开始滚动!我们在做第一场比赛。
探索你所看到的
我们标记了的字段称为层级。这是您将在场景中添加对象、相机、光源等类似的东西的地方。稍后我们将在场景和项目中进行更多解释。
接下来我们有场号 2 。这是你游戏的素材**存放的地方。素材是游戏使用的所有外部资源。这包括图像、字体、脚本、场景、文本文件、XML 文件、音乐、声音、视频等。
场号 3 为景景。在那里你会看到场景本身实际发生了什么。您还将在这里添加您的素材,拖动它们,进行更改,所有这些都在场景视图中。
在【4】我们有检查员。这是您将修改、添加和移除组件以及您在场景中添加的对象的属性的地方。它现在看起来是空的,但是我们很快就会到达那里。
编号 5 是一套播放按钮。这些按钮用于在编辑器中启动您的游戏,因此您可以测试您的工作。你甚至不用担心游戏在出错的情况下崩溃,Unity 一遇到它无法处理的错误就会停止游戏。
并且,在编号处,我们有控制台选项卡。如果您熟悉编程,您会知道所有的输出消息、错误、警告和调试消息都显示在这里。这对 Unity 来说是完全一样的,只是输出消息的处理方式与您想象的有些不同。
在 Unity3D 中添加和管理素材
原文:https://www.studytonight.com/game-development-in-2D/adding-and-managing-assets
我们看到我们的游戏现在看起来很空。让我们解决这个问题。抓住一个你想让你的球员的形象。例如,我们将使用这个快乐的小星星。
我们的桌面上有石凡星,因此我们可以轻松访问他。要将他添加到 Unity 中,我们只需将图像拖放到我们的素材中。
到目前为止,我们所做的只是将星图像添加到我们的项目中,但没有添加到当前场景中。要将其添加到场景中,只需将图像从素材视图拖放到场景视图或层次结构(在场景视图中添加的对象会自动添加到层次结构中)。
当你在 2D 工作时,你添加为图像的对象被存储为精灵。精灵是 Unity 记住你用这些图像在 2 维空间而不是 3 维空间工作的方式。
您只添加了一个图像,并且您一定已经注意到 Unity 窗口中不同视图的一些变化。首先,似乎最值得注意的是检查器视图不再是空的,下面列出了雪碧渲染器和变换等选项。这些被称为组件,它们很重要。
你看,变换是 Unity 中任何存储一些最基本数据的对象的属性。基础数据下有什么?
- 每个对象都有一个位置。
- 它有一个旋转角度。
- 它有一个比例因子。
这些值告诉 Unity 一个对象在游戏世界中的确切位置和方式。尝试将这些属性的X
、Y
和Z
元素更改为不同的值,看看会发生什么。
精灵渲染器是一个处理屏幕上精灵(即图像)的组件。它有一些属性,如渲染的图像、图像的颜色(白色表示图像未修改)、翻转和排序图层。目前,我们不想改变雪碧渲染器中的任何东西,所以让我们保持原样。
如果你现在点击播放按钮,你会看到你添加的图像现在在游戏中可见!哇哦!但是,有一个你不太记得添加的蓝色背景。这是因为背景是由场景中的摄像机添加的。如果您想更改背景颜色,只需点击层级中的主摄像头,然后点击检查器中摄像头组件的背景属性更改背景颜色。
到目前为止,我们只添加了一项素材。但是随着您的项目越来越大,并且您添加了越来越多的素材,管理您所有的素材可能会变得困难。这就是为什么确保你的素材从一开始就被合理地组织起来可以减少很多未来的麻烦(相信我,我一直是受害者)。
您可以将您的素材组织到文件夹中,右键单击素材部分的任意位置,然后选择,创建→文件夹。
Unity 是如何工作的?
让我们脱离在 Unity 上的工作,深入了解 Unity 实际上是如何与兜帽下的游戏一起工作的。
想象你是一个完全正常的人。你不是一个游戏设计师或任何东西,你只是去你的日常业务。
想象有一天你去看一场戏。你买票,你在座位上坐下,也许在路上买些零食,心情享受夜晚。
真正的乐趣从这里开始。如果是一部剧,你对它有什么样的期待?肯定有一个舞台,在那里一切都会发生。还有,一部剧不是没有装饰好的舞台,人们在舞台上移动的剧,对吗?谁会愿意盯着一个空荡荡的舞台看一个小时,更不用说付钱了?你可以说舞台上有很多东西,很多物件。
大多数戏剧通常是分场景的。可能会有这样一个场景:一片黑暗的森林,有巨大的树木,一个湖,周围有仙女。城堡内部可能还有另一个场景,到处都是黄金铺成的,天花板上挂着吊灯。我接下来要说的是,在一部剧中有不同的场景,舞台上的物体可能不同,甚至可能相同(人们可以使用山中或矿井附近的岩石的相同切口)
Unity 只是一个巨大的舞台剧。Unity 中的一切都发生在场景中。你的游戏的标题屏幕将是一个场景,结束信用将是一个场景,你的游戏将发生在一个屏幕(或其中几个),见鬼,甚至你的选项菜单将是一个场景。Unity 中的每一个场景都是用物体制作的,很像常规舞台剧中的一切。你在舞台表演场景中安排硬纸板剪贴,而你在 Unity 场景中安排音频源、光源、播放器、相机和地图。
戏剧中的演员通常有剧本,告诉他们在戏剧中的任何给定时间应该做什么、表演什么和说什么。我们也可以称演员为对象,对吗?毕竟人类也是物体。类似地,Unity 场景中的一些或所有对象可能都有脚本,告诉他们做什么,什么时候做。制作这些脚本,包括编写代码(通常是C#
或JavaScript
)并将它们附加到您希望代码影响的对象上。例如,如果我们的场景中有一艘宇宙飞船,我们会写一段代码,用箭头键移动它。我们会将这段代码保存为一个脚本,然后将该脚本附加到作为您的宇宙飞船的对象上(请记住,Unity 场景中的所有东西在某种程度上都是一个对象)。
这就是团结的全部,真的。你只是在做一个巨大的互动舞台剧。就像你通过学习 Unity 成为一名游戏设计师一样,你也成为了一名舞台剧协调员!(嗯,不完全是)
Unity 引擎物理组件
原文:https://www.studytonight.com/game-development-in-2D/2D-physics-components
大多数游戏的核心基础之一,无论是 2D 还是 3D,都是其中涉及的物理。物理学不需要像波动方程和流体动力学那样复杂。甚至你在制作游戏时所做的最基本的事情都涉及到物理。
例如,移动玩家通常包括在玩家的物体上增加一个力,或者将其移动一定的量。让它漂浮或淹没在水中,或者只是滑下斜坡,也与物理学的工作原理有关。
Unity 中的物理,以及一般的游戏设计,真的很重要。很多时候,是游戏的物理特性导致了"bugs"
或者"glitches"
。其中的一些例子是 OOB(越界)和裁剪错误。
在这一节中,我们将研究如何在游戏中为对象添加物理属性,以及如何让它们按照我们想要的方式工作。我们还将了解更多关于引用对象和公共的魔力。
Unity:从 2D 物理学开始
顾名思义,2D 意味着二维工作。因此,我们并不真正关心第三维(或 Z 轴)发生了什么。)就我们而言,我们只需要关心 X 轴(水平方向发生了什么)和 Y 轴(垂直方向发生了什么)。
事实上,在我们开始之前,这里有一个小东西你可以试试。在 Unity 中,尝试单击场景视图左上角的 2D 按钮。
你会看到这样的东西:
你会注意到 Unity 实际上只是让我们认为我们在 2D 工作,而实际上我们只是在制作一个平面的 3D 游戏!我们实际上可以利用 Unity 为我们自己所用的这个技巧,我们将在稍后发现灯光效果时看到。
好了,该开始了。以下是我们将合作的内容:
- 向量
- 刚体和力
- 对撞机和碰撞
- 你的第一场比赛
我们将在这里解释什么是单位矢量和力,从下一课开始,我们将从刚体和碰撞开始。
在 Unity 中,我们有两个脚本类,名为 Vector2 和 Vector3 (实际上,也有一个 Vector4,但我们暂时不太关心这个)。 Vector2 和 Vector3 就是你可以称之为containers
的若干数值,最常见的是浮点值,用末尾的数字表示。所以, Vector2 是两个单个值的容器, Vector3 是 3 个值的容器。当我们在 Unity2D 工作时, Vector2 类变得突出,虽然 Vector3 还有一些用处。
由于这可能对一些读者来说有点混乱,让我们用一个例子来理解。假设我们有一个物体的位置,比如石凡星。他在 2D 游戏世界中的位置由一个 X 值(即水平方向)和一个 Y 值(垂直方向)来定义。
在为 Unity 编写代码时,我们使用一个保存两个变量的向量 2 来代替石凡星位置的两个单独的值。这些变量既可以定义,也可以设置为其他用户定义的变量。
注意:不用担心你的 C# 代码写在哪里,我们很快会给你演示如何添加自己的脚本。
当然,一个向量 2 并不真正局限于定义一个位置。每当您处理修改(或定义)某个对象的位置、旋转或方向的值时,向量就有了最佳用途。
注意:如果你在安装 Unity 的时候没有安装 Visual Studio,你的脚本很可能会在 Unity 的默认界面 MonoDevelop 中打开。不要担心代码在颜色或类似的东西上看起来与你的不同;只要你跟上形势,你就会没事的。
向 Unity 游戏项目添加 C# 脚本
原文:https://www.studytonight.com/game-development-in-2D/basics-of-unity-script
当然,在我们的游戏中有不动的物体并不能真正让我们的游戏变得有趣。那么,让我们来了解如何使用 Unity C# Script 来移动游戏对象,从这里开始,我们将转向刚体。
首先,让我们创建一个脚本。为此,在素材区域右键,转到创建→ C# 脚本。
这将创建一个新文件,默认名称为新行为脚本。将脚本重命名为运动,然后按回车键。这将在素材部分创建一个名为运动的新脚本。双击打开它,让我们看看会发生什么。暂时不要在这个脚本中键入任何内容。
既然我们现在进入脚本,让我花一些时间来提及 Unity 将场景中的对象称为游戏对象。所以,从现在开始,我们将场景中使用的对象称为游戏对象。石凡星现在将被称为游戏对象,而不是对象。
您会注意到,我们刚刚创建的脚本带有两个预定义的方法,并且您的脚本自动继承自一个名为MonoBehaviour
的基类。让我们一个一个地看完这些,试着理解它们的意思。
整体行为
这是 Unity 中所有脚本继承基本属性的基类。这个类定义并提供了许多有用的值、方法和属性,您可以在脚本中使用它们,为您省去许多麻烦。例如,MonoBehaviour 包含游戏对象(gameObject.transform.position.x/y/z
)位置的定义,这意味着您可以直接使用这些值,而不必定义它们。
您通常不应该去掉继承声明,因为大多数时候您需要这个父类提供的东西来完成您的工作。MonoBehaviour 还包含Start()
和Update()
方法的定义,我们将在前面解释。
Start()
方法
这个方法由脚本运行一次,在游戏对象初始化和启用的最开始。这意味着对象一激活,该方法就运行。如果场景打开时某个对象已经处于活动状态,则初始化和启用过程将被视为同时进行。当您需要声明组件或设置值时,此方法非常有用。例如,您可以使用 Start 方法来设置枪的子弹数量的初始值。您也可以使用它来访问附加到任何游戏对象的其他组件,我们将在后面看到。
查看下面的代码示例,并仔细阅读注释以理解它。
Update()
方法
Unity 每秒调用该方法 60 次(或者,每秒 60 帧)。这是代码的主要动作通常发生的地方。例如,检测输入,增加力量,增加分数,繁殖敌人或子弹等。
MonoBehaviour 类给了我们很多其他预定义的方法。您实际上可以在 Unity 文档中找到这些方法的列表。它们有各种各样的用途,但目前,为了简单起见,我们将只坚持这两种方法以及我们自己定义的方法。
理解 Unity3D 刚体
原文:https://www.studytonight.com/game-development-in-2D/rigid-bodies
刚体是一种属性,当它被添加到任何物体上时,允许它与许多基本的物理行为相互作用,比如力和加速度。你可以在任何你想在游戏中拥有质量的物体上使用刚体。
换句话说,向游戏对象添加刚体是告诉 Unity 的方式,
好的,看到这个物体了吗?我希望它表现得像有一些质量和重量,它应该以现实的方式对力和碰撞做出反应。
当我们使用 2D 游戏设计时,我们使用刚体 2D ,而不是刚体。它们的不同之处在于,刚体 2D 仅在XY
轴上相互作用,并且总体上是二维的。刚体 2D 组件覆盖变换,并将其更新为刚体 2D 定义的位置/旋转。这有助于在需要时增加物体的速度和加速度。
为了进一步理解刚体,这里有一个例子。假设你有一个普通的纸箱,形状像一个立方体。考虑到盒子本身目前没有一个确定的重量,它只是一个存在的盒子。如果你想在盒子里移动,你可以用各种不同的方法。想象一下,你想让硬纸板盒表现得像一个真实的、有质量的物体。假设我们用沙子填满了它。然后,我们有一个有实际质量的纸箱,感觉很重。如果你拉或推它,你可以期望在它移动之前必须施加一些力。在这个例子中,刚体的行为类似于沙。它们给游戏物体(也就是你的硬纸板盒)增加了一种质量感,这样它就可以与力和其他物理基础如重力和摩擦力相互作用。
关于什么是刚体的描述已经够多了,让我们深入研究一下这个游戏。在检查器中,对于游戏对象,像石凡星一样,点击底部的添加组件。如果你没有修改游戏对象,按钮应该在精灵渲染器组件的正下方。
从那里,转到物理 2D →刚体 2D 。这将为你的游戏对象添加一个刚体 2D 组件。
在交互视图中,在精灵渲染器的正下方添加了一行新的刚体 2D 特征。
让我们运行我们的游戏,看看会发生什么。“呃...什么?”很可能是此时从你嘴里说出来的。你会注意到你的游戏物体像石头一样掉落!那真的不好玩,是吗?
要解决这个问题,只需将刚体属性的重力标度值设置为0
。
虽然没有什么不同,是吗?你之前在游戏中有一个精灵,添加了一个刚体,并将其重力设置为零,这似乎让我们回到了完全相同的点。
不完全是。你看,通过改变刚体的重力比例,你基本上定义了物体受重力影响的程度。事实上,试着将质量和重力标度改变到不同的值,看看会发生什么。物体仍然有质量,它只是不关心作用在它上面的重力,因此保持不变。
通过改变其他属性的值并查看其对游戏对象的影响,可以自由探索刚体的更多选项。
Unity:使用 C# 脚本移动游戏对象
原文:https://www.studytonight.com/game-development-in-2D/making-player-move
现在你已经知道了什么是刚体以及如何连接它们,让我们继续把它们投入实际使用。我们能想到的解释刚体工作的最好方法之一是让玩家使用箭头键移动。
为此,打开我们之前制作的运动脚本。如果你删除了它,或者你正在做一个干净的新项目,只需创建一个新的脚本并命名为运动。在你的 IDE 中打开它,你会看到我们之前解释过的熟悉的Start()
和Update()
方法。
现在,让我们详细看看每一行代码,并尝试理解这里发生了什么。不要担心,如果你不能一下子掌握全部,你会随着我们的进步而学习。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour {
public RigidBody2D starBody,
public float speed;
void start()
{
// use this function to initialize
// anything
}
// Update is called once per frame
void update()
{
starBody.velocity() = new Vector2(Input.GetAxisRaw("Horizontal")*speed, Input.GetAxisRaw("Vertical")*2);
}
}
线→ 公共刚体 2D 星体 :简单声明Rigidbody2D
的一个实例,命名为starBody
。记下public
访问修饰符,我们很快就会谈到这一点。
线→ 公共浮点速度 :简单声明一个名为speed
的浮点值。再次,记下这里使用的public
访问修饰符。
线→ 虚空开始()T5】:注意这个方法是完全空的。我们甚至没有给speed
和starBody
赋值。如果我们不给这些变量一些东西,你会期望得到到处都是的 NullReferenceExceptions 或unassigned referenceexceptions和普遍的混乱,对吗?然而,这种方法仍然神秘地空着。
线→ (【内部更新方法】 星体.速度=新矢量 2(输入。GetAxisRaw...) : 这就是主动作围绕你的游戏角色进行的地方。让我们深入研究这一行,好吗?前几个字是starBody.velocity =
的意思,我们给starBody
当前引用的刚体指定一个速度。而new Vector2(...)
意味着刚体的速度被定义为Vector2
,其中输入参数分别是沿 X 轴和 Y 轴的速度。
现在,对于这个代码中的实际魔法:Input.GetAxisRaw("Horizontal")
和Input.GetAxisRaw("Vertical")
这是什么东西?好的,输入类提供了 MonoDevelop 来处理输入。它有你所谓的输入轴的定义,定义为水平和垂直。
基本上是游戏在检测水平和垂直输入轴对应的输入,根据你按的按钮设置为-1
、0
或1
。因此,当您按下右箭头键时,这意味着您正在将横轴的值设置为1
。一旦放开箭头键,该轴上的值就会跳回 0。现在,在游戏语言中,它只是意味着,
按下右箭头键时,每帧水平移动字符 1 个单位。
将它保持在 1 意味着该物体将行进得相当慢。因此,我们将该值乘以速度浮动,这样说,
以 1 倍的速度移动角色,因为我们知道任何东西乘以 1 都是相同的值,所以我们实际上是说当按下轴按钮时,以这个速度水平移动角色。
注意:默认情况下,标准键盘上的轴按钮是向上和向下箭头,纵轴是 W 和 S ,横轴是左和右箭头,横轴是 A 和 D 。
继续,这一行的内容基本上是下面的句子:
给这个刚体一个游戏世界的速度,其中水平速度为(横轴速度),垂直速度为(纵轴速度)
现在,为了完成,保存这个脚本并返回到 Unity。要将脚本附加到对象上,只需将其拖放到该对象上,或者转到添加组件→脚本。
现在,还记得我们写脚本的时候是如何要求你记下public
访问修饰符的吗?看看脚本的组成部分。
您会注意到,随着脚本的执行,Unity 自动生成了两个字段,用于输入刚体 2D 和速度浮动。这就是团结的魔力。在编辑器中可以看到公开声明的Values
和class
实例,您可以在其中进行调整,而不必一直查看代码。
要为第一个字段设置刚体 2D,请单击字段旁边带有点的小圆。这将打开场景中可用刚体的列表,您可以使用。目前,由于我们在整个场景中只有一个刚体,请单击列表中出现的刚体。
你这么做是为了什么?还记得我们写脚本的时候是怎么不给starBody
变量赋值的吗?这是我们指定的地方。我们可以用一个简单的用户界面来完成组件和值的赋值,而不必在代码中编写它。
接下来,在下一个字段中设置速度值。不要把它定得太高,否则你的角色可能会在你看到他去了哪里之前就飞走了。这是一个问题,因为我们的相机是固定的,所以把它放回视野将成为一项说起来容易做起来难的任务。我们建议将速度设定在5
左右。
完成后,您的脚本组件应该是这样的:
现在点击播放按钮,让我们看看会发生什么。如果一切顺利,你会注意到你现在可以用箭头键移动你的角色。太棒了。
Unity3D——使用碰撞器 r2D 处理游戏对象的碰撞
原文:https://www.studytonight.com/game-development-in-2D/colliders-and-collisions
碰撞是 Unity 理解两个刚体之间,实际上是两个游戏物体之间的物理相互作用的方式。在现实生活中,当我们说两个物体相撞时,我们的意思是它们在物理上相互接触。
在 Unity 中,碰撞不是由刚体本身定义的,而是由一个名为碰撞 r2D 的新组件定义的。碰撞器 2 是定义一个区域的组件,在该区域中游戏对象之间发生碰撞交互。简单来说,碰撞器就是游戏物体相对于其他游戏物体的固定区域。我们强调它们是区域的事实,因为不是所有碰撞器的形状都完全像定义它们的游戏对象。事实上,对于高度详细的模型和精灵,大多数开发人员使用基本形状,使近似形状。
**
在上图中,请注意绿色边界。这些边界定义了各自游戏对象中的碰撞区域。在三角形中,边界非常适合游戏对象的形状,因为我们使用了一个简单的三角形。在正方形中,我们将碰撞区域做得比游戏对象的实际形状大,以再次表明碰撞器是独立于游戏对象的区域。
最有意思的案例是档位对象。请注意,碰撞器没有完美地缠绕齿轮的齿,而是 Unity 对形状的碰撞区域进行了近似,导致了更简单的碰撞区域。(我们没有制作那个碰撞区域,Unity 自动生成的。我们将很快向您展示如何自己完成)。
所以,让我们利用对撞机的知识。我们甚至不需要使用脚本,耶!在你的项目中,打开你的主角,通过转到添加组件→物理 2D →盒子对撞机来添加一个Box Collider 2D
。你现在会注意到一个新的组件,盒子碰撞器,出现在检查器面板中。
当然,大小值可能会根据您的图像的形状而有所不同。
你可以看到上面图片中我们高亮显示的编辑碰撞器选项。如果你点击那个按钮,你会注意到你的图像现在有几个手柄,你可以用来调整碰撞区域的大小。
如果你现在运行游戏,你不会真的注意到任何不同。你的角色仍然会像正常人一样使用箭头键移动。所以,让我们通过给我们的主角一些可以碰撞的东西来测试碰撞器的真正魔力。为此,右键单击素材区域,并转到创建→精灵。
该菜单为您提供了许多基本形状,您可以将其用作占位符精灵或测试交互。点击方块,会生成一个新的方块形状供你使用。
按回车键,然后将方块拖放到层次结构中,就像我们添加了石凡星一样。
使用蓝色手柄将正方形调整到合适的大小,这样您就可以测试碰撞。像下面这样的图片就足够了。
如果你现在运行这个游戏,你会发现石凡星并不真的在乎他前进道路上的障碍,他只是在白色的障碍物下平稳地滑行。
我们如何解决这个问题?方法如下:在不改变其他任何东西的情况下,也给新的方块精灵添加一个Box Collider 2D
。因为它是一个基本的矩形物体,Unity 会自动添加一个碰撞器区域,就像精灵形状一样。现在,再次尝试运行游戏。
我们的角色现在像我们希望的那样与白色块碰撞!但是一旦你试图在推着角色的同时让他转过街角,事情就开始变得不稳定了。
好吧,让我们从 Unity 的角度来看一下整个场景。玩游戏时,只需点击场景选项卡,即可看到场景背后发生的事情。如果你点击你的主角,你可能会看到这样的东西:
有问题!你试图把方形对撞机推到一个角落,从而旋转它。事实上,这里有一个方法,你可以在现实生活中测试这一点,甚至不用从你的电脑座位上站起来。试着推一下显示器(轻轻地!)中间。会向后移一点,对吗?但是试着把它推到一个角落。会发生什么?你的显示器旋转。如果你学过一点高级物理,你会知道你正在做的是给你的显示器施加一个扭矩,让它转动。
回到游戏中,我们如何让我们的角色不在角落里摇摆不定?很简单。只需打开你的主角,在刚体 2D 属性中,打开约束部分。
如果您打开该菜单(通过单击三角形),您将看到禁用(或冻结,Unity 称之为)对象移动和旋转的选项。勾选冻结旋转 Z 框,就可以开始了。但还是不太令人满意。两个对撞机之间有一个很大的空间间隙,由于对撞区域的盒子形状,你无法移动。
我们如何让对撞机的形状更逼真一点?就像我们的明星一样。好吧,我们不要用盒子对撞机,让我们继续看稍微复杂一点的版本,也就是Polygon Collider
。要添加一个多边形碰撞器 2D ,让我们首先去掉已经附着在我们角色身上的方块碰撞器。只需点击组件右上角的齿轮(打开设置)(我们已经在图片中突出显示了它),并选择选项,移除组件。
现在,按照我们在添加箱式对撞机时遵循的相同步骤进行操作,但这次,请选择多边形对撞机来代替。如果你的角色有一个相当简单的形状,Unity 应该不会在为你自动定义一个类似形状的碰撞区域上有太多问题。然而,如果不是这样,就像石凡星的情况一样,我们将不得不自己做这件事。
只需点击编辑碰撞器按钮,即可编辑碰撞器的边界区域。
在石凡星对撞机上稍作编辑后,这是我们最终得出的产品:
尝试在游戏中测试你的新对撞机。
现在,你可能想保存你的工作。只需按下Ctrl + S
,保存为场景即可。我们在前面的课程中已经解释了场景是如何工作的,接下来,我们还将教您如何使用多个场景。
练习练习
-
试着让玩家在游戏内部绑定,这样他就不会在屏幕外徘徊了。通过制造新的精灵来使用碰撞器。
提示:主摄像头静止不动,所以通过对摄像头边缘的判断,你对对撞机放在哪里有一个相当好的想法。
-
一旦你掌握了窍门,让你的第一个游戏真正可以玩!用对撞机和精灵做一个迷宫,试着让一个主角找到出路!你甚至可以尝试用开始和结束文本导入图像,并将其放入游戏中来帮助玩家。
Unity:使用 Prefab 在运行时创建游戏对象
原文:https://www.studytonight.com/game-development-in-2D/basic-fundamentals-of-game-objects
既然您已经了解了使用 Unity 的一些基本知识,并且已经自己制作了一两个游戏,那么让我们试着深入挖掘一下,好吗?毕竟我们刚刚刮到了冰山的表面,那就是 Unity!
首先,是时候和石凡星说再见了。到目前为止,他一直是我们旅途中的好朋友,但对于我们前方的道路,我们需要更复杂一点的东西,而一颗仅仅在 13 秒钟内在 Paint.NET 匆忙画出的星星并不真正符合这个描述。
那么什么符合这个描述呢?我猜是这个...
现在,我们将理解与 Unity 相关的更基本的概念,更专注于游戏对象和预设。
理解预设和实例化
好吧,所以Prefab
这个词看起来有点吓人,不是吗?别担心,不是,事实上,它是游戏设计师实时创建游戏对象时最好的朋友之一。那么到底什么是预制构件呢?嗯,一个 Prefab 实际上是一个特定游戏对象的蓝图或模板。我们知道一开始理解起来有点混乱,所以让我们举一个非常基本的例子。
想象一下,我们正在制作一个基本的太空射击游戏,小家伙,这是一个敌方角色。
现在,如果我们想在 Unity 中用我们的主角和一个敌人构建一个游戏场景,它看起来会像这样:
当然,当你有一个敌人时,这是非常好的,但是如果你想要很多敌人呢?不是 2 或 3,假设是 15 或 20。作为一个学习 Unity 的初学者,你可能会沿着这些思路思考一些事情:通过创建副本多次使用同一个素材。
好吧,我们认为这也是一个可行的解决方案,但是如果每个精灵都有自己的人工智能和自定义属性呢?你真的愿意为每一个精灵增加一个刚体和对撞机吗?如果你想在游戏中产生更多的敌人,而不是在场景制作过程中呢?我们真的不建议把每个敌人都放在自己身上,否则你的游戏可能会变得非常可预测和无聊。
如果我们可以定义一个敌人,并让某个东西生成这个敌人的副本,因为他们都是一样的呢?嗯,正是预制解决了这个问题。
一个预设是我们想要生成的游戏对象的定义,它会在你需要的时候,在你需要的地方生成一个定义好的游戏对象的精确副本。事实证明,当你需要动态生成游戏对象,比如子弹、外星人、硬币等时,这非常有用,因为 Unity 完成了这里的大部分工作,使游戏对象立即可供我们使用。
运行时使用 Prefab 生成游戏对象
让我们利用这个。我们将从一个非常简单的练习开始,每次按空格键时生成一个框。首先,让我们创建一个spaowner。现在我们真的不需要一个空间所有者来拥有图形,只需要一个空的游戏对象就可以了。所以,你要做的就是在层次中右键点击,点击创建空。
您应该会看到一个新的游戏对象出现在层次结构中。但是屏幕上什么也没有出现。因为这是一个空游戏对象,它没有任何组件,除了一个变换。请记住,精灵渲染器也是一个组件。因为这个游戏对象没有这样的组件,所以它根本不渲染任何东西。很简单,就在那里。空游戏对象对于像空间所有者和参考点这样的东西非常有用,因为它们在游戏中是不可见的。
你可以通过点击层次结构中的游戏对象来检查空的游戏对象在哪里。然后它会用一个半透明的圆圈显示游戏对象的位置。不管怎样,让我们把我们的空游戏对象重新命名为生成器,这样我们就知道它到底是什么了。我们将留给你去找出如何重命名游戏对象,这很简单。
现在,让我们创建实际的盒子来生成。使用默认的精灵菜单创建一个精灵,我们在前面的教程中使用它来生成封锁。(其实不一定非得是盒子,可以用任何雪碧。为了简单起见,我们使用默认的方形精灵)。
现在,让我们给盒子添加一个Rigidbody2D
,只是为了给它一个权重,这样它在生成时就会掉下来。这意味着我们不会修改我们的重力尺度。(或者,如果您是持久类型,请将其设置为零以外的任何值)。点击播放按钮测试你的盒子。如果它掉下来,你就在正确的轨道上。
现在,还记得你刚开始的时候是怎么把石凡星加入场景的吗?您将精灵从素材拖到了层级。
创建一个预制是这个过程的逆过程。您将现有游戏对象从层级拖动到素材。然后,Unity 会在您拖到的文件夹中生成该游戏对象的预设。因此,既然我们想制作一个盒子的模板,我们就把盒子精灵从层次结构拖到我们的 Prefab 文件夹中。
你应该看到一些新的东西出现在你的预设文件夹中。它与盒子的图像完全相同,但它出现在一个灰色的容器中。那是你的预制屋!很简单,不是吗?现在,只要按下空格键,我们就需要为生成器编写一个小脚本来生成这个预制的实例。为了在您按空格键时生成一个框,下面的代码是完美的。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Generator : MonoBehaviour
{
public GameObject boxToGenerate;
void update()
{
// When spacebar is hit
if(Input.GetKeyDown(KeyCode.Space))
{
// instantiate the box object
Instantiate(boxToGenerate);
}
}
}
你记得如何创建一个新的脚本并重命名它,对吗?如果没有,请查看上一个教程。我们也将我们的脚本命名为Generator
。
注意这里怎么少了Start()
方法。去掉空的Start()
和Update()
方法是你应该做的事情,在 Unity 开发的时候非常推荐。
- 7 号线:你现在应该熟悉这条线了。这是对 Unity 的一个声明,要求它生成一个 gameObject,通过在我们前面看到的编辑器中创建那个槽。
-
Line 11: This has some interesting stuff going on. The
Input
class, as we know, contains definitions for various methods of providing input to the game. This includes mouse buttons, gamepad keys and keyboard keys.在我们的例子中,我们使用
GetKeyDown
方法。这将检测某个键何时被按下。键盘的其他方法有GetKey
(检测一个按键,然后按住)和GetKeyUp
(检测刚刚释放的按键)。在GetKeyDown
方法中,我们有一个枚举作为参数,KeyCode
枚举。它基本上是键盘上所有键的枚举列表。 -
12 号线:如你所猜,这是我们一直称之为魔法主线。
Instantiate
方法是GameObject
类中的一个方法(注意大写的 G),它有一些重载的变体。然而,所有这些重载的主要参数是要实例化或生成的实际游戏对象。由于我们想要生成我们在编辑器中插入的盒子,我们将提供boxToGenerate
作为参数。只需保存这个脚本,并将其附加到编辑器中的生成器游戏对象中。
现在,要填充出现在脚本属性中的框以生成槽,我们只需点击圆点,并选择我们的框的预设。或者,你可以直接将预制好的盒子拖放到插槽中。这是在告诉 Unity 要生成什么。 boxToGenerate 只是 gameObject 变量的名字,那个变量还是要有东西的。
在新场景中保存您的作品,然后点按“播放”。如果一切顺利,只要您按空格键,就会生成一个新的框。
如果您注意层次结构,您会注意到您每次都会生成一个新的盒子(克隆)。即使他们从屏幕上掉下来,他们仍然在等级中。
这里我们应该警告你不要生成太多,因为它们会无限期地下降,太多的可能会开始滞后于计划。稍后我将解释如何摧毁物体。
Unity:Prefab 实例化,使其移动并设置速度
原文:https://www.studytonight.com/game-development-in-2D/more-complicated-instantiation
当然,我们可以将实例化用于更好的用途。让我们试着从一个会移动的玩家身上发射一颗子弹。首先,让我们让我们的小伙伴进入游戏。
接下来,我们会给他点东西拍。一个小火球怎么样?
太好了。现在,让我们用箭头键让他移动。我们已经知道如何做到这一点,所以我们将跳过这一部分。现在,让我们用那个火球创造一个预制。再次将火球拖放到层级中,使其成为活动的游戏对象,然后将其拖回素材中,从中生成一个预设。
注:如果存在预制体,一个很好的测试方法是简单地查看层级中游戏对象的名称。有预设的游戏对象会有蓝色的名字。
现在,我们将继续创建一个名为Shooter
的新脚本。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooter : MonoBehaviour
{
public GameObject fireball;
public RigidBody2D body;
public float speed;
void Update()
{
body.velocity = new Vector2(Input.GetAxisRaw("Horizontal")*speed, Input.GetAxisRaw("Vertical")*speed);
// When spacebar is hit
if(Input.GetKeyDown(KeyCode.Space))
{
// instantiate the fireball object
Instantiate(fireball);
}
}
}
到目前为止,这只是我们为移动和实例化编写的代码的组合。没什么太复杂的。如果你保存这个脚本并把它附加到你的主角身上,你现在可以移动他,如果你按下空格键,火球就会出现并落下。
设置新预制构件的位置
子弹并不是真的在做什么,只是下落(你可以通过将gravity
属性的值设置为0
来让它们停止下落,就像我们之前做的那样),它们总是在屏幕中间产卵,而不是从我们主角的手(手掌)中产卵。你能猜到为什么会这样吗?
那是因为我们只是告诉游戏,只要你按空格键,就会生成一个火球克隆体,就是这样。它不知道在哪里生成,所以游戏只是在坐标(0, 0)
处生成,也就是游戏世界的死点。
我们如何解决这个问题?好吧,让我们探索Instantiate
方法的重载(一个方法的其他变体),我们可能会得到一些帮助。
以上是我们到目前为止一直使用的Instantiate
方法的默认重载(变体)。让我们滚动重载,看看哪一个可能有用。
上面的重载(变异)方法取Object
(gameObject)的一个实例作为参数生成,取Vector3
的一个实例作为参数定义在哪里生成!太好了。不要担心Quaternion
参数值,我们将简单地将其设置为 0。
现在让我们稍微偏离一下我们的游戏,大致说说gameObject
。任何普通游戏对象都有一个位置属性,该属性存储为 2D 元素的Vector2
(或 3D 元素的Vector3
)。该位置属性可通过以下方式访问:
// For X
gameObject.transform.position.x
// For Y
gameObject.transform.position.y
这两个值都存储为float
。如果我们可以为我们的主角(射击萨维)读取这些值,我们就可以计算出当按下空格键时我们角色的确切位置,以发射火球,然后我们在那里产生一个新的火球。我们每次都需要捕捉主角的x, y
坐标,因为我们的角色可以用箭头键移动。
所以,让我们用重载方法代替默认的Instantiate()
方法。用角色脚本中的这个替换旧的Instantiate()
方法并保存:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooter : MonoBehaviour
{
public GameObject fireball;
public RigidBody2D body;
public float speed;
void Update()
{
body.velocity = new Vector2(Input.GetAxisRaw("Horizontal")*speed, Input.GetAxisRaw("Vertical")*speed);
// When spacebar is hit
if(Input.GetKeyDown(KeyCode.Space))
{
// instantiate the fireball object
Instantiate(fireball,
new Vector3(gameObject.transform.position.x, gameObject.transform.position.y, 0),
new Quaternion(0, 0, 0, 0));
}
}
}
这里到底发生了什么?我们新的重载方法接受三个参数:
- 游戏对象:要生成的游戏对象。
- 矢量 3: 在 3D 空间中的何处生成游戏对象。
- 四元数:与游戏对象在三维空间中的旋转相关的数据。
现在,由于我们在 2D 环境中工作,我们简单地考虑任何三维值,即Z
值为0
。你会注意到我们在代码中使用了gameObject.transform.position
。术语gameObject
只是指脚本当前附加到的任何游戏对象。这意味着在我们的例子中,游戏对象指的是我们的主角射击萨维。
- 20 号线:我们新建一个
Vector3
,由三个元素组成。这三个元素是火球产生位置的X
、Y
和Z
坐标。
我们在这里做的基本上是告诉游戏在玩家按空格键时的确切位置生成一个新的火球精灵。我们将四元数值(取 4 个参数,一个x
、y
、z
和一个附加的w
值)设置为零,因为它们非常复杂。事实上,即使是官方的 Unity 手册也说,除非你知道自己在做什么,否则你不应该真正与他们打交道。
为什么我们首先要创建一个四分之一(四元数)?你一定在想。好吧,看看我们再次使用的重载方法的输入参数。如果你现在运行游戏,你现在会看到火球在角色所在的地方产生,就在你按空格键的时候。
创建新的预设时移动它们
嗯,我们已经走得更远了,但是火球还是静止的。好像我们在到处制造萤火虫。那么我们如何让火球自己移动呢?为此,让我们通过创建一个名为Fireball
或FireballBehaviour
的新脚本(记住,名称中不要有空格)来重新开始编写脚本。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FireballBehaviour : MonoBehaviour
{
private float fireballXValue;
public float fireballSpeed;
void Start()
{
// getting the initial position where prefab is created
fireballXValue = gameObject.transform.position.x;
}
// Update is called once per frame
void Update()
{
// adding speed value to the X axis position
// value
fireballXValue += fireballSpeed;
// setting new X value to position
gameObject.transform.position = new Vector2(fireballXValue, gameObject.transform.position.y);
}
}
}
看到我们在这里做什么吗?我们使用了一个名为fireballXvalue
的私有浮动变量(我们并不想让其他脚本看到这个x
值)来存储火球位置的X
值。
当我们初始化一个新的火球时,这个新的火球运行它的start()
功能(记住,当gameObject
激活并启用时,start()
功能在最开始运行一次)。我们正在做的是在初始化时将fireballXvalue
的值设置为对象位置的X
值。这将确保火球从我们发射它的点开始移动,而不是从死点开始。
接下来,看一下update()
法。第一行只是将速度变量添加到每一帧的fireballXvalue
中。下一行很重要。如果你仔细阅读,你可能会奇怪为什么我们不能直接修改position.x
和position.y
的值,而是使用变量。如果我们试图直接修改 x 和 y 位置的值,我们会得到一个编译错误。
注:我们尝试直接更改第 22 行位置的x
值。
取而代之的是,我们在每一帧的空间中将位置设置为一个新的Vector2
位置。每一帧的数值都会改变,使得子弹在游戏时间内移动。以下是脚本对每个实例化的子弹(火球)所做的工作:
- 将名为
fireballXvalue
的全新变量的值设置为项目符号的初始位置。 - 每帧将
speed
的值加到fireballXvalue
上。 - 将每帧子弹的位置设置为
fireballXvalue
和原来相同的Y
值(我们不希望火球垂直移动,只希望水平移动)。
保存这个脚本,让我们返回 Unity。现在,既然我们希望每个新的火球都有那个脚本,为什么不简单地将其添加到模板中呢?为此,只需点击火球的预制T5。您会注意到,您可以像普通的活动游戏对象一样更改组件和属性。然后,您在这里所做的更改将应用于从该预设生成的每个新游戏对象,这意味着如果您将脚本附加到火球预设,每个生成的火球都将拥有该脚本,就像它在预设中一样。
所以,在不浪费任何时间的情况下,将FireballBehaviour
脚本附加到火球预制体上,并设置速度值(如果你想看到子弹实际移动而不是飞出屏幕,我们建议在0.4
周围做一些事情)。耶!如果我们用空格键射击,我们的火球会不断向右移动。
看看我们如何利用实例化来获得优势?它非常适合创建场景制作过程中不需要的游戏对象,而是在实际游戏中需要的对象。有些人相当疯狂,可以使用一系列 for 循环和对Instantiate()
方法的调用来生成整个级别。当然,如果你好奇的话,这是你应该自己尝试的。
Unity 的父子游戏对象
原文:https://www.studytonight.com/game-development-in-2D/parenting-game-objects
是时候放下你的婴儿玩具和奶瓶了,我们不再照顾小小的 gameObject 宝宝了。相反,我们将学习如何在层次结构中创建主游戏对象的子游戏对象,这种技术在与我们刚刚学习的Instantiate()
方法一起使用时非常有用。
如果您已经直接开始学习本教程,我们建议您查看我们的上一个教程,了解正在进行的示例。
如果你密切关注我们在上一个教程中创建的角色,你会注意到火球只是从我们的主游戏角色中间产生的,而不是从你预期的地方(就像在这个例子中,伸出的手)。
现在,如果不是角色,而是一个看不见的游戏物体射出火球呢?毕竟,用户(游戏玩家)不会真正看到到底是谁发射了火球。那就这么办吧。首先,创建一个新的空游戏对象。
你看,游戏物体一般都有它们相对于游戏世界的位置。
但是对于某些对象,比如枪或汽车喇叭,你可能需要它相对于另一个游戏对象。我们可以让游戏对象说这个游戏对象离另一个游戏对象有 2 个单位,不管它在哪里,而不是说这个游戏对象离游戏的死点有 2 个单位。**
让我们在游戏中尝试一下,看看它到底是如何工作的。要使游戏对象成为子对象,只需将目标子对象拖放到目标父游戏对象上。在我们的例子中,我们将把我们的空游戏对象拖到我们的角色对象上。
您会注意到,新的游戏对象现在出现在我们的主要角色下的下拉列表中,并在层次结构中为其名称添加了一个小缩进。这意味着游戏对象现在是我们角色的孩子。如果你现在试图移动角色,你会注意到空的游戏对象也跟着移动,但是保持在相同的相对距离。
但是空的游戏物体漂浮在我们角色的头附近,而不是他的手附近!要解决这个问题,只需使用变换视图中的position
值调整空游戏对象的位置,直到空游戏对象到达您需要的位置。
同样,子游戏对象相对于其父对象将有其位置,而不是游戏世界。也就是说,如果你将位置设置为(0, 0, 0)
,子游戏对象将被定位在父游戏对象的死点,而不是屏幕。
在我们的例子中,如果你还记得上一个的话,我们在射击萨维游戏对象附带的脚本中添加了每次按空格键时实例化一个新火球的代码。同样的脚本还保存了使射击萨维游戏物体移动的代码。
因此,我们将不得不从Shooter
类的update()
方法中移除火球预设创建代码。
让我们创建一个新的类ShootingBehaviour
并将代码添加到这个类的update()
方法中,并将这个脚本附加到射击 Savi 游戏对象的新的隐形子游戏对象中。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShootingBehaviour : MonoBehaviour
{
public GameObject fireball;
void update()
{
// When spacebar is hit
if(Input.GetKeyDown(KeyCode.Space))
{
// instantiate the fireball object
Instantiate(fireball,
new Vector3(gameObject.transform.position.x, gameObject.transform.position.y, 0),
new Quaternion(0, 0, 0, 0));
}
}
}
正在进行射击萨维动作的Shooter
类看起来像,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooter : MonoBehaviour
{
public RigidBody2D body;
public float speed;
void update()
{
body.velocity = new Vector2(Input.GetAxisRaw("Horizontal")*speed, Input.GetAxisRaw("Vertical")*speed);
}
}
现在,我们已经将拍摄脚本附加到空的游戏对象上,并使其成为我们角色的游戏对象的子对象,让我们现在测试我们的游戏。
有效!那么这一课我们学到了什么呢?我们已经了解了 gameObject 育儿是如何工作的,以及我们可以如何利用它来为自己谋利,我们不需要换一个脏尿布(我们不需要做太多工作)。
Unity:用 CollisionEnter 检测碰撞
原文:https://www.studytonight.com/game-development-in-2D/detecting-collisions
在本教程中,我们将学习如何使用简单的 C# 脚本检测两个游戏对象之间的冲突,以及如何在对象冲突时执行一些代码。
我们还将学习如何使用游戏标签以及它们为什么重要,我们还将学习如何使用 Unity 的控制台来输出定制的消息,这些消息对我们作为开发人员和测试人员来说非常方便。
首先,让我们打开目前正在进行的项目:
一切似乎都井井有条。现在,让我们给我们的子弹(火球)添加一个新的 2D 盒子对撞机,这样它就可以探测碰撞(记住,对撞机实际上是定义碰撞的东西,而不是刚体)。
想看看如何给游戏对象添加对撞机?你会在这里找到它。
这里有一个快速的问题: 如果我们想要所有生成的子弹(火球)都有一个盒子对撞机,我们要修改什么?预制当然。在预制构件上安装一个 2D 箱式对撞机,这就是子弹。
现在,让我们给我们的主角一些可以拍摄的东西。目标怎么样?我们这附近有一个。
开始了。让我们将这个目标导入到我们的游戏项目和场景中(到目前为止,你应该对添加新的精灵到场景中感到相当舒服)。
现在,让我们给我们的目标添加一个 2D 圆对撞机(毕竟是圆)以及一个Rigidbody2D
。
现在,让我们继续写一些脚本来检测子弹(火球)和目标之间的碰撞。再一次,复制下面的代码,我们将详细解释发生了什么。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TargetBehaviour : MonoBehaviour
{
void onCollisionEnter2D(Collision2D col)
{
// When target is hit
if(col.gameObject.tag == "Bullet")
{
Debug.Log("Target was Hit!");
}
}
}
记得吗,我们说过MonoBehaviour
类除了start()
和update()
之外还提供了很多其他的默认方法?嗯,OnCollisionEnter2D()
(带参数Collision2D
)就是这样一种方法。这是一个由 Unity 触发(调用)的方法,每当它检测到这个脚本附加到的对象和任何其他游戏对象之间的冲突时。
注意我们提供的Collision2D col
参数。(当使用这种方法时,将变量名用作col
或coll
在开发人员中非常流行)。我们还没有设置甚至实例化任何Collision2D
对象/变量,我们如何使用它?
Collision2D
是 Unity 在碰撞过程中生成的一组关于碰撞的数据。它包括像击中的游戏对象,击中的点(存储为一个点变量,实际上是一个Vector3
)等等。col
只是我们给这组碰撞数据起的名字。
因此,每当检测到冲突时都会调用该方法,Unity 将确保参数col
(实例Collision2D
)中存储了所有需要的值。我们只需要使用它们并对它们进行操作。
接下来看看if
语句中的条件。
(col.gameObject.tag == "Bullet")
这句台词是什么意思?简单的说就是包含在col
数据变量中的 gameObject,也就是发生碰撞的 gameObject,应该有一个名为 Bullet 的标签,这样if
语句才会触发。标签?什么事?暂时不要担心标签,我们很快就会谈到这一点。
Debug.Log
是干什么的?
下一条线很重要,因为它是我们的魔法线。Debug
类是一个包含在你开发游戏时非常有用的工具的类,在你测试代码或任何其他组件时更是如此。
Debug
类中包含的方法之一是Log(string parameter)
方法,我们在上面的代码中使用了该方法。只要您调用该方法,它就会将参数定义的新消息打印到控制台。保存该脚本,并将其附加到目标。记得在编辑器中将重力比例设置为0
,另外,你应该在约束菜单中冻结X
和Y
坐标,以防止你的目标飞出。
什么是游戏标签?
在运行游戏之前,让我们先研究一下标签。标签对于你和 Unity 来说,基本上是一种识别和分组游戏对象的方式。默认情况下,游戏对象没有标签,也就是说,它们没有标签。我们可以通过点击游戏对象(或预设)检查器顶部的标签选项来设置标签并创建自己的标签:
Unity 默认给了我们一堆标签使用,我们甚至可以通过点击添加标签来添加自己的标签。点按“添加标签”会将我们带到检查器中的此菜单:
点击+
按钮,您将获得一个新标签名称的输入字段。由于我们编写了碰撞脚本来检测与带有标签项目符号的物体的碰撞,我们将给这个新标签命名为项目符号。一旦你这样做了,只需打开你的预设,给它子弹标签,现在将出现在你的列表中。
如果您现在运行游戏,尝试向目标射击,您应该会看到如下内容:
看看 Unity 窗口的左下角。当你的子弹击中目标时,你应该看到你的信息。当然,我们编程让子弹移动的方式是,它只会碰到目标,然后一直移动下去。我们会提前解决这个问题,所以现在,我们将关注这里到底发生了什么。
- 我们的主角发射一颗带有标签子弹的子弹
- 一旦 Unity 检测到与标签名为子弹的子弹发生碰撞,则
if
语句将关闭true
并执行其代码。 - 代码要求 Unity 将
Target was hit!
打印到控制台。
注意:每次射击目标时都会重复这个动作。
如果您想查看完整的控制台窗口,如果 Unity 检测到脚本错误和警告,您也可以在其中看到它们,您可以通过单击素材部分正上方的控制台选项卡轻松找到它们。
练习练习
- 尝试将多个目标(命中时会打印不同的消息)发送到控制台。比如目标 1 被击中!、目标 2 被击中!等等。请随意探索更多的功能和组件,尽管尝试在一个单独的、新鲜的项目中做这些,这样当您探索时,您就知道游戏中发生了什么变化。
如何在 Unity3D 中破坏游戏对象
原文:https://www.studytonight.com/game-development-in-2D/destroying-game-objects
在游戏中实例化和修改游戏对象很重要,同样重要的是在不需要的时候销毁它们。
破坏游戏对象的主要原因包括管理内存、处理掉不需要的游戏对象(像那些超出摄像头不返回的),甚至游戏相关事件(被子弹击中)。
Destroy(gameObject):
这是用来摧毁游戏对象的代码。相当简单,不是吗?让我们倒回去,更深入地看看发生了什么。如果您尝试在您的 IDE 中探索Destroy
方法,您将看到销毁方法有 2 个变体(重载形式)。
第一种重载形式只是破坏作为参数输入的游戏对象,而不是其他。
而第二种重载形式涉及另一个参数time, t
作为float
变量。这将使在破坏游戏对象之前等待以秒为单位指定的时间。当你想让游戏对象在摧毁自己之前完成一些其他的东西/任务/计算时,Destroy
方法的这种变体非常方便。例如,播放垂死的动画或添加乐谱。
直到我们的最后一个教程,我们已经成功地添加了一个目标,当被子弹击中时,它会向控制台输出一条消息。一旦击中目标,我们就让它消失,好吗?我们该怎么做?我们只需将以下几行添加到我们已经存在的目标脚本中:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TargetBehaviour : MonoBehaviour
{
void onCollisionEnter2D(Collision2D col)
{
// When target is hit
if(col.gameObject.tag == "Bullet")
{
Debug.Log("Target was Hit!");
}
// object which collided
Destroy(col.gameObject());
// object with which it collided
Destroy(gameObject);
}
}
这是怎么回事?我们告诉脚本销毁 col 数据中包含的游戏对象。简单来说,这意味着我们告诉脚本摧毁子弹(火球),因为我们不希望我们的子弹在摧毁目标后继续前进。
在第二条Destroy
语句(我们的魔法线)中,游戏物体会自我毁灭。请记住,简单地使用术语gameObject
指的是脚本附加到的游戏对象,在我们的例子中是目标。保存脚本,启动游戏!
信息:处于编辑模式。
信息:在播放模式下,目标被击中后
一旦我们击中目标,子弹和目标就消失了!看看层次结构,你会注意到目标和子弹的克隆游戏对象都不见了。一旦在游戏中被摧毁,它们就消失了。由于我们在构建目标时将其放置在场景中,因此每当我们重新进入场景时,也就是说,每当我们进入播放模式时,它总是会回来。
原来你有!销毁游戏对象本身是一个非常简单的概念,因为它只涉及一行代码,但是当您调用方法和其他语句来使对象的销毁看起来和感觉起来真实和正确时,真正的魔力就出现了。
这次我们做了很多。我们给了我们的角色发射子弹的能力,我们也学会了预设和实例化的概念。接下来,我们给我们的角色一个要射击的目标,从而理解碰撞检测,最后,我们让目标一旦被击中就摧毁自己,用物体摧毁来完成事情。
练习练习
-
试着给你的目标一个生命值,也就是说你要多次射击才能将其击破。这不仅会测试你制作游戏的逻辑,还会测试你基本编程逻辑的推理能力。
提示:一个简单的
integer
变量和一个if
语句可以大有作为。 -
尝试在摄像机覆盖区域之外为子弹创建一个末端区域。如果一颗子弹从相机区域射出,并触及这个末端区域,它就会被摧毁,而不是漫无目的地进入死亡空间。当你进入更大、更复杂的游戏时,这是管理内存的有效方法。
在 Unity 中使用导航网格导航
原文:https://www.studytonight.com/game-development-in-2D/navigation-using-navmash
在本教程中,我们将了解 Unity 中的 Navmesh,以及如何创建它并将其作为导航的一部分在游戏中使用。
Unity 中的导航和寻路
你有没有想过游戏中各种各样的 NPC(不可玩的角色)是如何在游戏世界中移动的,避开物体,甚至有时会避开你,结果只是从你身后弹出来吓你一跳。这是如何如此现实地做到的?这些所谓的机器人如何决定他们应该走哪条路,避免哪条路?
在 Unity 中,这个奇迹(一旦你知道它是如何工作的,就不会这么多了)是使用导航网格实现的。
导航网格或导航网格是 Unity 的导航和路径寻找系统的一部分。导航系统允许你使用从你的场景几何图形中自动创建的导航网格来创建可以在游戏世界中智能移动的角色。动态障碍允许你在运行时改变角色的导航,而离网链接允许你建立特定的动作,比如开门或从壁架上跳下来。
导航网格的不同组件
Unity导航网系统由以下部分组成:
- 导航网格(导航网格的缩写)是一种数据结构,它描述了游戏世界的可行走表面,并允许在游戏世界中找到从一个可行走位置到另一个可行走位置的路径。数据结构是根据您的标高几何图形自动构建或烘焙的。
- 导航网格代理组件帮助您创建在朝着目标前进时相互避开的角色。特工们用导航网推理游戏世界,他们知道如何避开对方,也知道如何移动障碍物。
- 离网链接组件允许您合并导航快捷方式,这些快捷方式不能用可行走的表面来表示。例如,跳过沟渠或栅栏,或者在穿过之前打开门,都可以被描述为离网链接。
- 导航网格障碍组件允许您描述代理在世界导航时应该避免的移动障碍。由物理系统控制的桶或板条箱是障碍物的一个很好的例子。当障碍物移动时,代理尽最大努力避开它,但是一旦障碍物变得静止,它将在 navmesh 上雕刻一个洞,以便代理可以改变路径来绕过它,或者如果静止的障碍物挡住了路径,代理可以找到不同的路线。
礼遇:直到导航网文档T3】
这一切都很好,但这只是理论。这只是告诉我们所有工具都存在什么。要知道如何使用它们,那完全是另一回事。学习这些工具的实现有什么比一个例子更好的呢?
是时候举个例子了!
我们在这里的目标是,我们希望创建一个迷宫式的场景,我们将在其中放置我们的玩家。我们将实现 NavMesh ,通过点击迷宫中的某个点,玩家对象将自动开始移动并到达迷宫中选定(点击)的点。容易吗?差不多吧。
设置和下载
我们将使用的组件不包括在标准安装中。
通过单击绿色的克隆或下载按钮,从 Unity Technologies GitHub 上的以下下载链接克隆或下载仓库。之后,使用 Unity 打开导航网格组件项目,或者复制
现有项目的资源/导航组件文件夹。(下载前检查 unity 版本)
场景
我们将要使用的场景看起来像这样。绿色胶囊是我们的球员,我们将尝试和移动他。橙色的物体是我们要避开的墙,黑色的物体是我们要走过的地板。你可以尝试自己创造这个场景(一定要尝试)。如果没有,点击链接下载场景。
下载场景//放置正确链接。
烘烤导航网
烘焙?导航网是一种蛋糕吗?良好的....在某种程度上,是的。请参阅,导航网格由 Unity 引擎计算和生成。这个计算和生成导航网格的过程被称为烘焙。
所以我们现在需要做的是烘烤我们的 NavMesh 。
-
为此,在层次选项卡中创建一个空对象,将其命名为“导航网格”,并重置其转换(自己做)。
-
Select this “NavMesh” object in the Hierarchy and click on Components > Navigation > NavMeshSurface.
-
Now just to see the beauty of NavMesh, hit Bake.
-
On hitting bake, we get the above image. The blue region shows the surface that is walkable. The current bake of the NavMesh is not what we want. What we want is that only the flat part of the floor is marked blue. To make this happen, we will change the properties of the agent to match our Player. So, select the Agent Type drop down and click on Open Agent Settings.
-
Now in the Navigation tab, click on the + icon to create a new Agent Type and input the parameters as shown in the image.
-
现在点击烘焙会有想要的效果。这是我们需要的道路。
-
现在你会注意到路径把我们的玩家当作障碍,因此玩家下面没有路径。为了解决这个问题,我们需要将我们的播放器放入另一个图层,并从包含图层设置中取消该图层的标记。为此,单击图层下拉列表并选择添加图层...选项。
-
现在在图层视图中,在自由图层空间中输入“玩家图层”,然后点击回车。
-
之后,从层次结构中选择导航网格对象,并在检查器中,单击包含图层下拉菜单,取消选中播放器图层。
现在选择层次结构中的播放器对象,选择层下拉菜单,然后点击“播放器层”。我们已经改变了玩家对象所在的层。
-
现在再次点击烘焙以获得导航可行走表面。
-
现在,即使看起来这些墙是禁区,我们也没有保证。为了确保这一点,我们必须特别使墙壁“不适合行走”。为此,首先选择层次结构中从墙(0)到墙(9)的所有墙对象,然后选择“添加构件”下拉列表。从该下拉列表中选择导航>导航网格修改器。现在所有的墙对象都有这个组件。
-
在所有墙对象仍处于选中状态的情况下,在检查器中检查导航网格修改器上的“覆盖区域”属性。现在选择区域类型下拉菜单,并选择“不可步行”。
-
现在终于再次点击烘焙,晒晒你创建的 NavMesh 的美丽。
设置播放器
设置播放器非常容易。我们只需要将“导航代理”组件添加到播放器对象中。
为此:
- 在层级中选择玩家对象。
- 在检查器中,点击添加组件下拉菜单。
- 从下拉列表中,选择导航>导航代理。
我们把这个组件连接到播放器上。现在我们的玩家可以访问导航界面。您可以尝试使用转向和避障设置,因为它们处理我们的玩家的实际移动。
让我们的玩家动起来
为了让我们的玩家移动,我们将在上面附加一个脚本,这将使导航网格将我们的玩家移动到我们点击的地板上的点。
为此,将名为“控制器”的新 C# 脚本附加到玩家对象。
using UnityEngine;
using UnityEngine.AI;
public class Controller : MonoBehaviour
{
public NavMeshAgent playerAgent;
void Update ()
{
if (Input.GetMouseButtonDown (0))
{
Ray camRay = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast (camRay, out hit))
{
playerAgent.SetDestination (hit.point);
}
}
}
}
现在让我们理解代码背后的逻辑。在这里,我们希望做的是获得鼠标左键被点击的位置,并从相机投射出一条光线到该点。相机有一个名为 ScreemPointToRay(位置)的功能,它从相机向给定的输入点发射光线。使用光线,我们可以计算出属性、组件、属性等。光线末端的物体。
一旦光线到达地面,我们将在 if 语句中得到一个真值,我们将让玩家向目标点移动。这是使用导航代理类的 SetDestination (Vector3)函数来完成的。该函数将代理移动到作为参数给定的点。
现在写完这段代码后,在 Unity 中,从层次结构中选择 Player 对象,并在检查器中将 Player 对象拖放到控制器脚本中的 playerAgent 变量中。
现在我们可以走了!继续按播放!看到魔法发生了!
这只是一个简单的迷宫。你可以玩这个。创建您自己的关卡,烘焙导航网格,并观看我们的玩家在迷宫中导航。最后,也是最重要的一点,玩得开心!
导航网格的力量
我们看到的只是使用 NavMeshes 的绝对基础。在运行时也可以使用 NavMeshes。
例如,拿一个有活动墙的地板来说。这种环境的导航曲面不断变化。因此,NavMeshes 的运行时计算已经完成(尽管这在资源上非常昂贵;避免)。
NavMeshes 也可以用于程序生成的关卡。我们要做的就是在 Start 上烘焙 NavMesh。为此,我们使用导航网格表面类的 BuildNavMesh() 函数。
因此,我们现在有了一个工具,它既强大又易于使用。但请记住,烘焙是处理器繁重的过程,所以要明智地使用它。
Unity 中的场景处理
原文:https://www.studytonight.com/game-development-in-2D/scene-handling
要理解这一点,我们首先要意识到什么是场景。场景是指包含特定游戏场景的物体。
假设你有一个游戏,它的世界由两部分组成:一个城市和一个森林。这里我们可以说这个世界可以定义为两个场景(虽然对于大型游戏来说可能不是这样),一个是城市场景,一个是森林场景。
引用 Unity 手册:
场景包含你游戏的对象。它们可以用来创建主菜单、单个级别和其他任何东西。将每个唯一的场景文件视为一个唯一的级别。在每个场景中,你将放置你的环境、障碍和装饰,本质上是设计和构建你的游戏。
在最新的几个更新中,Unity 已经开始使用一个新的库来访问场景并在它们之间遍历。这个库叫做场景管理。
要使用这个库,我们必须首先包含它。我们通过写作做到这一点
using UnityEngine.SceneManagement
在剧本的开头。
在这个库中,您将遇到和使用最多的类是场景管理器。
在构建中包含场景
为了能够通过场景管理器类访问场景,我们首先需要将场景添加到构建设置中
为此,通过 CTRL+S 保存场景。它将保存在素材文件夹中。
现在进入菜单栏中的文件,选择构建设置。
在打开的窗口中,将场景图标从“项目”选项卡拖放到“构建中的场景”下的空间中。
我们可以以类似的方式添加多个场景,并对它们进行重新排序。场景的顺序决定了它们的场景号和游戏开始时首先载入的场景。
场景经理
场景管理器类包含以下内容:
描述:
运行时的场景管理。
静态属性:
| 场景账户 | 当前加载的场景总数 |
| 场景取消建筑设置 | 构建设置中的场景数。 |
静态方法:
| 创建场景 | 在运行时用给定的名称创建一个空的新场景。 |
| get active scene | 获取当前活动的场景。 |
| 山羊场景 | 在场景管理员的已加载场景列表中获取索引处的场景。 |
| 山羊场景图像索引 | 从构建索引中获取场景结构。 |
| 获取场景名称 | 在加载的场景中搜索具有给定名称的场景。 |
| getscenebypath | 在加载的所有场景中搜索具有给定素材路径的场景。 |
| 加载场景 | 在构建设置中按场景的名称或索引加载场景 |
| loadsceneeasync | 在后台异步加载场景。 |
| 合并场景 | 这将把源场景合并到目标场景中。 |
| 移动游戏对象价格 | 将游戏对象从当前场景移动到新场景。 |
| setactive scene | 将场景设置为活动状态。 |
| 卸载场景 | 销毁与给定场景相关联的所有游戏对象,并将场景从场景管理器中移除。 |
事件:
| 激活已更改的 | 订阅此事件,以便在活动场景发生变化时获得通知。 |
| 场景加载 | 向其中添加一个委托,以便在场景加载后获得通知。 |
| 场景加载 | 向其中添加一个代理,以便在场景卸载时获得通知。 |
礼遇:团结场景经理
Unity3D 中的测试驱动开发(TDD)
原文:https://www.studytonight.com/game-development-in-2D/tdd-unit-testing
测试驱动开发(TDD)是在编写代码本身之前为一段代码编写自动化测试的实践。这基本上意味着我们在测试的基础上创建和重构(改变结构而不改变行为)我们的项目代码。编写代码、测试代码和重构代码的过程都是循环往复的,直到达到令人满意的状态。
通常遵循以下步骤顺序:
- 添加测试(最初会失败)
- 运行所有测试,看看新测试是否失败
- 写一些代码
- 运行测试
- 重构代码
- 重复
遵循这一工作流程可以加快重构代码和进行更改的过程,因为您可以直接看到哪些地方出了问题以及原因。
你可能想知道为什么我们在编写代码之前先编写测试。这是因为在编写代码之后编写测试通常会导致开发人员编写测试来使它们通过。当您首先编写一个失败的测试时,您要确保它失败是有充分的理由的(比如没有正确地实现所需的功能),并且排除误报。
红绿重构循环
要记住的最重要的事情是红绿重构循环。它是 TDD 过程的核心和灵魂。这里每一步都有意义:
- RED: 指写一个肯定会失败的测试用例。
- 绿色:是指更改/编写代码,使在“红色”阶段创建的测试通过,使得之前通过的所有测试仍然会通过。这意味着开发者不能为了通过一个测试而中断项目的工作。
- REFACTOR: 指消除冗余,增加编写代码的可读性等。
这些步骤一遍又一遍地重复,直到所有测试都通过,或者遇到失败的测试是不可能的。
单元测试
单元测试是软件测试的一个层次,其中软件的单个单元/组件被测试。目的是验证软件的每个单元都按设计运行。一个单元是任何软件中最小的可测试部分。它通常有一个或几个输入,通常只有一个输出。
是时候举个例子了!
现在我们相信行动胜于语言。因此,执行任务是最好的学习方式。因此,我们的目标是建立一个基本的单元测试场景,在这个场景中,我们可以测试一个特定类的函数是否如预期的那样运行。
我们将创建一个二次值解算器,当输入为“x”时,我们将得到 f(x)的值。
对于例如让 f(x) = x2 -4x+4 现在对于 x=2 的值,我们得到 f(2)=0。
我们的目标是使用 TDD 流程来创建它。
现在在 Unity 中,打开一个新项目后,点击菜单栏中的窗口>测试运行器。
现在出现了这样一个窗口。
这是 Unity 内置的单元测试器模块。我们将为 TDD 提供服务。
通过将此标签拖到检查器旁边来附加它(自己操作)。
现在我们要知道测试脚本和我们的常规脚本不一样。要使 unity editor 将特定脚本视为测试脚本,第一步是将脚本保存到名为“编辑器”(不带引号)的特定文件夹中。
因此,在素材中创建一个“编辑器”文件夹,并在其中创建一个名为“功能测试器”的脚本
现在设置已经完成,我们将开始开发过程。这里我们将使用红绿重构循环。因此,首先我们将编写一个未通过的测试(我们必须让测试失败)。之后,我们将尝试更正代码,以便测试给出肯定的结果。然后最后我们将尝试使我们的代码尽可能干净和可读。
打开 FunctionTester 脚本,并在其中键入以下代码。
using System;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
[TestFixture]
public class FunctionTester
{
[Test]
public void T00_PassingTest ()
{
Assert.AreEqual (1, 0);
}
}
现在在测试运行器标签中,点击运行所有。
这是我们第一个红色州的完成。标签底部提到测试失败的地方。
现在,对于绿色状态,我们需要更正代码,以便案例测试为真。为此,请将代码的第 11 行改为
Assert.AreEqual (1, 1);
现在点击运行所有的测试返回真。
在这个迭代中,我们不需要重构状态,因为代码是最简单的形式。如果开发人员认为代码令人满意,则只能跳过重构状态。
现在你一定在想这段代码是做什么的。s
在第 5 行,我们将这个类描述为一个[测试夹具]。这告诉 Unity,这个类是我们的 Tester 类,将用于单元测试。
现在我们将作为函数执行我们的每一个测试。在定义函数之前,我们提到它是一个[测试]。这允许测试运行人员访问它并向我们显示结果。
正如您所看到的,第一个测试非常琐碎,但是编写第一个测试是一个很好的实践,因为它确保测试系统正常运行。
[Test]
public void T00_PassingTest ()
{
Assert.AreEqual (1, 0);
}
断言。AreEqual 是 Nunit 库中 Assert 类的一个函数。它检查传入的两个对象是否相等。如果对象不相等,将引发 AssertionException。
这就结束了我们的第一次迭代。
接下来我们将测试当 x=2 时,我们应该从二次方程中得到一个值 0。
现在在第二次迭代中,我们将修改代码如下:
using System;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
[TestFixture]
public class FunctionTester
{
public Function function = new Function();
[Test]
public void T00_PassingTest ()
{
Assert.AreEqual (1, 1);
}
[Test]
public void T01_X2Y0()
{
Assert.AreEqual(function.Value(2f) ,0f);
}
}
这里我们已经开始了第二个 RGR(红绿重构)循环。运行此测试时,我们将在测试 T01 中失败。
现在,您将看到这不会编译。这是因为我们没有函数类。这是我们真正测试的开始。
现在,您将看到这不会编译。这是因为我们没有函数类。这是我们真正测试的开始。
it 内部类型代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Function
{
public float Value (float x)
{
return 8f;
}
}
现在运行测试,我们得到一个失败。
转向绿色状态,我们将函数脚本的第 9 行改为
return 0f;
现在再次进行测试,我们会得到一个肯定的结果
你现在一定在想,为什么我们不在函数中计算任何东西。你必须意识到,我们在 TDD 中唯一的目标就是让所有的测试都通过,并且这个方法能很好地通过测试。
在下一次迭代中,我们将测试 x = 0,f(0) = 4。在函数测试器中为这个测试迭代实现测试(挑战!).尽量不要复制代码,自己写。记住,错误是最好的老师。
查看下面的代码并比较错误:
using System;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
[TestFixture]
public class FunctionTester
{
public Function function = new Function();
[Test]
public void T00_PassingTest ()
{
Assert.AreEqual (1, 1);
}
[Test]
public void T01_X2Y0()
{
Assert.AreEqual(function.Value(2f) ,0f);
}
[Test]
public void T02_X0Y4()
{
Assert.AreEqual (function.Value (0f), 4f);
}
}
该测试将失败,因为我们的值函数返回 0f,与输入无关。
现在是绿色国家。我们想要的是计算 x 的二次方程值的值函数,其中 f(x) = x2-4x+4。
因此,我们将把我们的价值函数改为:
public float Value (float x)
{
return (Mathf.Pow (x,2) - (4f*x) + 4f);
}
现在我们到达了重构状态。看看我们的函数,我们可以看到它非常小,所以重构对我们的代码影响不大。重构在大型脚本中变得很重要。
现在作为一项任务,尝试在 FunctionTester 类中编写尽可能多的测试,并遵循 RGR 循环使测试通过。测试次数越多,模块的准确性越高。
如果绿色状态期间先前的测试失败,该怎么办?
考虑这样一种可能性:为了通过某个特定的测试,您需要对脚本进行更改。这种变化导致之前通过的一个测试失败。如果出现这种情况,我们将再次进入该测试用例的红色状态,而不是进入下一个文本。只有在所有以前的测试用例都通过的情况下,我们才会进入新的测试用例。
结论
这是 TDD 创建一个极其基础和琐碎的项目的一个例子。在这个例子中,这看起来像是一个痛苦,但是当扩大规模(对于更大的项目)时,TDD 是一个福音。它有助于快速有效地识别和纠正错误。因此,尝试在可能出现大量场景的项目中使用它。这也有助于跟踪所有已测试的场景。
Unity3D 中的动画和动画师
原文:https://www.studytonight.com/game-development-in-2D/animation-animator
动画是一款游戏的两个组成部分之一,将它带入生活(另一个是音频)。Unity 的动画系统叫做 Mechanim,它的力量在于将人形模型带入生活。在以前的版本中,使用了另一个名为“动画”的组件,但在 Unity 的最新版本中,它已经贬值了。
在本教程中,我们将看到如何使用动画师创建动画的基础知识。我们将制作一个迷你游戏模块,它的一扇门在我们按下空格时打开,如果我们再次按下空格,它就会关闭。所以让我们开始我们的旅程,希望最终,我们都能通过那扇门。
1.创造我们的环境
在本模块中,我们将设置我们的环境。这意味着我们将创造:
- 基地/地面
- 四壁结构
- 户外的
- 要创建基础右键单击层次面板>三维对象>立方体。双击层次结构中的多维数据集对象。场景窗口聚焦在立方体上。
- 现在,在“检查器”面板中,您将看到变换组件。确保立方体的位置和旋转为(0,0,0)刻度为(1,1,1)。将刻度值更改为(5,0.5,5)。这将是我们的楼层。通过在层次结构中选择立方体,按 F2 键,键入名称并按回车键,将对象重命名为“地板”(不带引号)。
-
Similarly create 3 more cubes and arrange them in such a way that they make 3 walls for the floor. This is a task for the reader.
-
现在开门。基本门有两种类型,滑动门和铰链门。我们要去滑动门。现在类似于最后一步,创建另一面墙来创建一个没有屋顶的房间。将第四面墙命名为“门”。这将是我们的门。
2.设置我们的视图
这个模块是为那些没有打开动画面板的人准备的。如果有,请跳到下一部分。
要打开动画师面板,单击菜单栏上的窗口选项,并从下拉列表中选择动画师。
同样在同一窗口菜单中,选择动画选项打开动画面板。
我们将使用这两者来创建我们的推拉门动画。
3.为门创建动画
为了创建动画,我们首先创建动画动作,然后我们以状态机的形式对这些动作进行排序(查找!)以便我们能够从一种状态过渡到另一种状态。不要被下面的动画师图吓倒。完成本教程后,你将在睡梦中制作这些。
现在来创建动画
-
选择动画面板并点击创建。
-
Name you animation “DoorOpen” and save it in the Asset folder. Similarly make another animation called “DoorClosed” and save it.
-
逐个选择创建的动画文件,并取消选中“循环时间”选项。
-
现在注意这一点,因为它是创造魔法的步骤。在“动画”面板中选择“开门”动画。你会看到一条时间线。这被称为“笨蛋”(也许因为它是“笨蛋”....我不知道)。它将作为动画中将要发生的事情的时间线。
-
单击添加属性按钮,然后选择变换>位置。这里我们可以看到在时间线上形成了 2 颗钻石。这些描述了我们知道物体属性的关键点。给定一组关键点,Unity 会自动插值并生成这两个关键点之间将要发生的移动。继续前进时,请记住这一特性。
-
在上面的时间线上,写有描述时间的数字。点击末尾关键点(菱形)上方的数字。关键点上应该出现一条白线。这表示将对白线下的那部分时间进行修改。现在点击红色按钮开始记录运动。
-
使用变换工具,移动场景视图中的“门”对象,使其根据您的需要达到打开状态。再次按下录制按钮停止录制。您可以按下录制按钮旁边的播放按钮来检查动画。
-
同样,创建“关门”动画。这是用户的任务。
4.使用动画师状态机
现在你有了移动的门,我们的问题是让它们按照我们的意愿移动。为此,我们必须了解动画师及其实际工作。
就像上面提到的,动画师负责将一个动画状态转移到另一个动画状态。举个例子,想象你在玩一个第一人称射击游戏,比如 PUBG 或者 CS: GO。这里如果你只按 W,玩家角色走路或者慢跑,但是只要一按 shift 配合 W 键,玩家就无缝爆发出 Sprint。这种从“行走状态”到“Sprint 状态”的转变,正是动画师所关心的。
回到我们的门口,如果我们打开动画师,我们会看到各种彩色的盒子,上面写着“进入”、“任何状态”、“退出”等。这些是各种动画状态。
其中你会发现一个橙色的箭头,从进入状态开始,一直到开门状态。这个箭头(或任何这样的箭头)描绘了从一个动画状态到另一个动画状态的转换。让我们看看各种状态意味着什么。
-
进入:进入是指场景第一次出现时的动画状态。
-
Exit: This state is used to end the animation and begin again at the Entry state. To make it simple suppose your transition ends in state "foo". Try drawing a transition from "blablabla" to "Entry". You just can't.
现在,如果你真的需要这么做,那就是你使用“退出”的时候。
-
任何状态:任何状态都是一种特殊的状态,总是存在的。它存在于你想去一个特定的状态的情况下,不管你当前处于哪个状态。这是将相同的向外转换添加到机器中所有状态的一种简化方式。请注意任意状态的特殊含义意味着它不能是过渡的终点(即跳转到“任意状态”不能作为选择随机状态进入下一个状态的方式)。
您还会看到一个箭头,从进入状态到开门状态。这不是我们想要的。在这里,场景一开始,门就打开了。我们想要的是门一直等到我们命令它移动。因此,我们需要一个“空闲”状态,即一个没有附加运动的状态。
-
为此,右键单击动画面板空间并从下拉菜单中选择创建状态>清空。
-
现在将这个“新状态”状态重命名为“空闲”(自己动手)。
-
Now we need Idle to be the Default state (state transitioned to after Entry). TO do this right click on Idle and select the Set as Layer Default State
现在开始过渡。转变指的是控制从一种状态转移到下一种状态。您看到的橙色箭头代表过渡。
要创建过渡,请在初始状态> 上单击鼠标右键,从下拉菜单中选择进行过渡>在下一个状态上单击。
所以试着自己创建一个工作状态图,用下图检查它是否正确。
还没有结束。在这里,如果你按 play,门会自动打开和关闭。这是因为我们的过渡是无条件的。初始状态一旦播放完动画,就会发生无条件转换。我们需要控制这里。所以我们将条件应用于过渡。
为了应用条件,我们需要设置一个参数来开关门。为此:
- 从动画师面板的左上角选择参数选项卡。
- 点击下方的+图标,从下拉列表中选择布尔选项。
- 将其重命名为“isDoorOpen”(自己动手)。
- 我们选择一个布尔值,因为使用它可以很容易地描述门的打开和关闭状态。
现在要将条件应用于过渡:
- 单击箭头选择过渡。
- 在“检查器”面板中,单击“条件”选项中的+。
- 按顺序设置条件的值。
“isDoorOpen”的转换 1、2 和 3 的值分别为真、假和真。
因此,我们已经完成了设置我们的条件。我们将通过代码触发这些转换。
5.编写代码
- 创建一个名为“门管理器”的空对象,并向其中添加一个名为“门管理器脚本”的新 C# 脚本。
- 要添加脚本,选择添加组件 >新脚本>将脚本命名为“door managerscript”>按创建并添加
- 在脚本中,键入以下代码并保存:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DoorManagerScript : MonoBehaviour
{
public Animator anim;
private bool trigger;
void Start()
{
anim.SetBool ("isDoorOpen", false);
trigger = false;
}
void Update()
{
trigger = anim.GetBool ("isDoorOpen");
if(Input.GetKeyDown (KeyCode.Space))
{
if(!trigger)
{
anim.SetBool ("isDoorOpen", true);
}
else
{s
anim.SetBool ("isDoorOpen", false);
}
}
}
}
6.穿过门到另一边
嗯,我想祝贺你在 Unity 中创建了你的第一个移动对象。更重要的是,它按照你的命令工作!干得好。这只是机械系统的力量的一瞥,如果它在你有能力的手中。
所以按 play,看看当你按空格键时会发生什么神奇的事情。
在 Unity3D 中更改场景
原文:https://www.studytonight.com/game-development-in-2D/changing-scene
场景管理库最常用的是场景之间的跳转。这是最简单的事情之一,但对游戏的创作至关重要
现在让我们看看它是如何实际完成的
现在在你的资源文件夹中,创建 2 个新场景,并命名为“场景 1”和“场景 2”。
要创建新场景,右键单击素材面板区域并选择创建>场景。
在这里,我们的目标是,我们应该能够在按下按钮(用户界面元素)时在场景之间跳转。我们可以用各种方法做到这一点,但是为了便于理解,我们将使用最简单的方法。我们将创建一个场景生成器对象,它将处理所有的场景变化代码(不管它有多少)。
一般来说,当一个场景从一个场景改变到另一个场景时,游戏对象、脚本等的所有实例都会改变。属于那个场景的被破坏,新场景的被加载。另一种方法是使用dontdestoryonload()函数,该函数将在场景变化时保持一个对象引用,但这将在另一个教程中涉及
场景交换对象创建和预置
好了,回到 Unity 中,在“场景 1”的层次选项卡中,创建一个空游戏对象,并将其命名为“场景交换者”(自己动手)。
在变换中,确保其位置和旋转在<0,0,0>处,刻度在<1,1,1>处。这并不影响工作,但保持游戏对象只拥有它们的转换放在原点是一个很好的做法。
现在给“场景转换器”对象添加一个脚本,并将其命名为“场景转换器”。(自己动手)。
现在在 mono developer/Visual Studio 中打开该脚本,并在其中输入以下代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneChanger : MonoBehaviour
{
public void ChangeScene(string sceneName)
{
SceneManager.LoadScene (name);
}
public void Exit()
{
Application.Quit ();
}
}
在这段代码中,我们包含了单元引擎。场景管理库,允许我们使用场景管理器类。
在变更场景(字符串名称)功能中,我们取输入一个名称为场景名称的字符串。这然后被传递到场景管理器。LoadScene() 功能。该函数加载由其名称定义的新场景(如果存在)。
在退出()功能中,我们使用应用。退出()功能。该功能具有退出应用的基本任务,即类似于屏幕右上角的红色 X 或关闭按钮的功能
这里我们已经创建了一个对象。现在要创建它的预置,只需在层次中选择对象,然后将其拖放到项目选项卡中的素材文件夹中。完成此操作后,您将看到一个与对象同名的蓝色立方体。这是预制的物体。
现在保存场景,双击“场景 2”。在此场景中,只需将场景编辑器预设的拖放到视口或层次选项卡中。将创建场景生成器的实例。
创建用户界面和预设
在前一节中,我们已经创建了一个场景交换对象。现在我们将创建用户界面。
在用户界面中,我们将有一个文本对象来描述场景名称,还有一个按钮来为我们改变场景。
因此,在层级选项卡中右键,选择界面>面板。把面板的颜色改成你想要的(自己试试)。
再次右键单击层级选项卡和选择 UI >文本。调整它的大小,并把它放在任何你想要的地方(自己试试)。
再次在层级标签中右键,选择界面>按钮。调整它的大小,并把它放在任何你想要的地方(自己试试)。
你的最终结果应该是这样的
现在将文本改为“这是场景 1”。同时将按钮中的文本更改为“更改场景”(将按钮的文本对象作为按钮对象的子对象)。结果如下:
现在在层级中选择按钮对象。在检查器选项卡中,单击按钮(脚本)组件中的加号图标。
我们在按钮(脚本)窗口中得到这个。
现在将层级标签中的场景切换对象拖放到对象参考空间中(用红色突出显示)
现在选择功能下拉(红色突出显示)。从下拉列表中,选择场景更改器>更改场景(字符串)。
现在你会在功能下拉下看到一个空格。输入“场景 2”。这里我们所做的是选择我们的场景生成器对象并访问变更场景()功能。“场景 2”是输入。现在只要按下按钮,就会调用 ChangeScene() 功能,场景变为“场景 2”。
现在对“场景 2”进行同样的操作,但输入“场景 1”作为输入,并相应地更改场景 2 中的文本(自己动手)。
现在将场景添加到文件菜单中的构建设置中。这样做是必要的,因为没有这种 Unity 就不会承认场景,它们之间也不会发生任何转变。
当你按下播放键。点击按钮将导致场景改变。
注意:我们没有像在模拟中那样设置退出功能(在 Unity 中播放场景),退出动作被忽略。然而,在游戏的真实构建中,我们可以使用应用 exit()退出。
进阶
Unity:使用Rigidbody.AddForce()
方法移动游戏对象
原文:https://www.studytonight.com/game-development-in-2D/right-way-to-move
在 Unity 中移动游戏对象主要有两种方式:
- 改变位置坐标:通过直接改变游戏对象的位置,而不太考虑其物理或其他类似组件。这就是我们到目前为止所做的,只需在每一帧中给对象的
X
位置添加一个值。 - 刚体物理:在处理遵循物理规则的物体时,对物体施加力或改变其速度比直接位置更新更有意义。看起来更真实。
在本教程中,我们将涉及一个有趣的例子,使用刚体物理的运动,而不是位置改变技巧。到目前为止我们一直在研究射击子弹,对吗?但是我们的子弹只是利用位置变化来行进,而不管它们是什么以及它们在现实世界中是如何运动的。
这也导致了一些问题,比如我们的子弹击中目标后仍然继续前进(查看我们之前的教程中的例子)。
它根本不知道它应该在击中目标后停下来,因为我们对它进行了编程,让它一直向右走。
与其这样做,不如我们对子弹施加一个非常强大的冲击力,就像现实生活中的子弹一样?这样做将使子弹移动,因为它的动量,而不是因为一个编程的位置更新。
让我们来探索这个选项,并且,我们将理解类Rigidbody
提供的AddForce()
方法。打开定义子弹/火球行为的脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FireballBehaviour : MonoBehaviour
{
private float fireballXValue;
public float fireballSpeed;
void Start()
{
// getting the initial position where prefab is created
fireballXValue = gameObject.transform.position.x;
}
// Update is called once per frame
void Update()
{
// adding speed value to the X axis position
// value
fireballXValue += fireballSpeed;
// setting new X value to position
gameObject.transform.position = new Vector2(fireballXValue, gameObject.transform.position.y);
}
}
}
因为我们在这个脚本中写的几乎所有东西都是通过位置变化来处理运动的,所以让我们清除所有东西,这样我们就又有了一个干净的Start()
和Update()
方法。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FireballBehaviour : MonoBehaviour
{
private float fireballXValue;
public float fireballSpeed;
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
使用组件控制游戏对象
现在我们知道,我们可以通过使用引用gameObject
来访问附加到它的脚本中的游戏对象。
此外,我们可以使用GetComponent
功能访问和组件(如刚体、碰撞器等)连接到游戏对象。
之前,我们使用检查器视图来更新任何组件的属性。在这里,我们将尝试在脚本中做到这一点。
首先,我们仍然需要声明Rigidbody2D
变量,但是与其让它成为public
,不如让它成为private
。
private RigidBody2D fireballBody;
现在,在Start()
方法中,我们将添加以下行:
void Start()
{
fireballBody = GetComponent<rigidbody2d>();
}</rigidbody2d>
那么这条线是做什么的呢?这一行代码在某种程度上是检测和设置变量的自动方式。通过调用GetComponent
方法,我们只是告诉 Unity 继续检测组件的类型,在尖括号<>
中为我们的游戏对象指定。在我们的例子中,我们希望脚本检测一个刚体 2D 组件,所以我们将把它放在尖括号内。此方法没有任何重载(变量)。
向刚体组件添加速度和力
既然我们已经控制了火球的刚体,我们该怎么处理它呢?嗯,我们可以给它加上一个速度,或者给它加上一个力。请注意,这两个组件都是 gameObject 背后的物理学的一部分,而不是变换(以及其位置)本身的直接变化。
有什么区别?如果你给你的身体加上一个速度,你就忽略了身体的任何质量。它只是让它走,而不考虑身体有多重。然而,如果你加上一个力,你就考虑到了身体的质量。
也就是说,即使对像大型汽车这样的重物施加很小的速度也会使其移动,但对同一辆汽车施加很小的力只会使其轻微移动。就我们而言,我们会给火球增加一个速度,因为我们可以认为它本身的重量很小。
添加velocity
属性
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FireballBehaviour : MonoBehaviour
{
private RigidBody2D fireballBody;
public float speed;
void Start()
{
fireballBody = GetComponent<rigidbody2d>();
// velocity is a property of RigidBody2D
fireballBody.velocity = new Vector2(speed, 0);
}
// Update is called once per frame
void Update()
{
}
}</rigidbody2d>
等一下!你在Start()
方法中加入了fireballBody.velocity
代码,而不是Update()
方法。为了理解这一点,让我们举个例子。想象一下,你妈妈让你换厨房的灯泡。你说“当然,我会做的”,然后你再做(或者不做,就像我们大多数人一样)。现在想象一下,不管你是否换灯泡,你妈妈都会要求你在你的余生里每秒 60 次更换灯泡。有点可怕,不是吗?我们在这里做着完全相同的事情,在 Unity。如果我们在 Start()方法中设置速度,我们只是告诉游戏改变一次速度,然后继续前进。
*但是,如果我们在 Update()方法中编写相同的代码,我们只会一次又一次地要求 Unity 将刚体的速度设置为我们定义的值。因为我们的价值观暂时不会改变,我们不一定要告诉脚本为已经完成的事情赋值。
使用AddForce()
增加力
现在,让我们探索向游戏对象添加力的方法。
方法AddForce()
的第一个参数只需要一个Vector2
就可以知道要向哪个方向施力。例如,使用new Vector2(4, 5)
的力将水平地向右施加 4 个单位的力,垂直地向上施加 5 个单位的力。
第二个参数有点意思。您将看到附加的第二个参数是名为ForceMode2D
的枚举。强制模式 2D 是一对模式,用于向游戏对象施加力。这些模式被命名为力和冲量。根据您想要施加的力的类型,您可以输入ForceMode2D.Force
(用于施加恒定的、一致的力)或ForceMode2D.Impulse
(用于施加瞬时的、撞击力)。)
在我们的场景中,我们想在火球上施加一个突然的、巨大的力,让它向前发射。施加一个恒定的力会使它从低速加速,这看起来有点奇怪。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FireballBehaviour : MonoBehaviour
{
private RigidBody2D fireballBody;
public float speed;
void Start()
{
fireballBody = GetComponent<rigidbody2d>();
// AddForce is a function of RigidBody2D
fireballBody.AddForce(new Vector2(speed, 0), ForceMode2D.Impulse);
}
// Update is called once per frame
void Update()
{
}
}</rigidbody2d>
如果你在 Unity 中尝试这两种方法,你的火球应该仍然以相同的方式移动,但是这一次,不需要直接修改它的位置,而是使用物理。我们让 Unity 为我们处理这个问题。
了解 Unity3D 画布
原文:https://www.studytonight.com/game-development-in-2D/the-canvas
Unity 中的画布不是一个大画板放在一个木架上。画布实际上是游戏中可以绘制用户界面元素的区域。
什么是 UI 元素? UI 元素只是游戏中(最常见的是在屏幕上)向玩家传递有用信息的元素。这些通常持续存在。用户界面元素的一个最好的例子是一个分数计数器,或者一个健康计等等。
Unity3D 画布和用户界面元素
UI 元素是什么形式暂停菜单、主菜单、HUDs 或平视显示器、计分器等等。在本教程中,我们将讨论一下画布是如何工作的,在下一个教程中,我们将继续在游戏中添加我们自己的用户界面元素。
到目前为止,我们唯一说过的是它在游戏中是一个很大的矩形空间。在 Unity 中,画布也是一个游戏对象,附带一个画布组件。这个画布组件充当屏幕上所有用户界面元素的主控件。这就是为什么所有的用户界面元素都必须是画布游戏对象的子游戏对象。
Unity3D 画布:画布组件属性
让我们看看画布组件。
注:我们缩小了 Graphic Raycaster 组件,因为目前它对我们来说没有另外两个重要。
画布脚本的第一部分是画布本身。它具有改变画布在屏幕上呈现的位置和方式的属性。第二部分画布缩放器,用于根据不同的屏幕大小设置 UI 元素的大小和缩放。
在画布脚本中,我们最重要的属性是渲染模式。
渲染模式中的三种模式决定了画布在游戏中的处理和渲染方式。让我们进一步探索这些选项,以便更好地理解它们。
Unity3D 画布:屏幕空间-覆盖
这种渲染模式将用户界面元素放置在渲染场景的屏幕顶部。这是你在制作平视显示器或任何类似的静态用户界面元素时,大部分时间都会用到的东西。它非常有用,因为它会根据屏幕大小自动将画布中的用户界面元素缩放到所需的大小。
Unity3D 画布:屏幕空间
这与叠加模式的工作原理非常相似,但是在这种模式下,我们指定一个摄像机来渲染我们的用户界面。因此,改变相机的属性,如形状、大小、覆盖区域或分辨率,将改变用户界面在屏幕上的外观。开发人员通常不会使用这个选项,因为他们发现 Overlay 更有用,因为它能够自动缩放用户界面元素。
Unity3D 画布:世界空间
这种模式与其他两种模式大不相同。在世界空间中,用户界面元素被简单地视为场景中的另一个游戏对象,而不是优先渲染。世界空间在处理作为游戏本身一部分的用户界面元素时非常有用,而不仅仅是对玩家来说。
Unity3D:向游戏画布添加用户界面元素
原文:https://www.studytonight.com/game-development-in-2D/adding-ui-elements
现在我们已经很好地了解了 Canvas 是如何工作的,让我们尝试将自己的元素添加到游戏中。我们将从一个非常简单的标签开始。一个标签只是你在用户界面上使用的静态文本。让我们的标签说使用箭头键移动。
首先,为了添加任何用户界面元素,我们现在知道我们首先需要一个画布。然而,当你在一个还没有画布的场景中创建一个用户界面元素时,Unity 为我们省去了在场景中插入一个新画布的麻烦。
要在场景中添加标签,右键单击层次结构,选择用户界面元素→文本。
一旦你点击文本,你会注意到在你的层级视图中有一个新的增加。
您可以安全地忽略或摆脱事件系统游戏对象。顾名思义,它处理的是处理事件,这是我们目前还没有涉及到的事情。查看 Unity 如何添加新的画布并自动使文本元素成为该画布的子元素。
现在,看看文本标签的属性。
你看到的大部分都是不言自明的。可以选择改变文本的颜色、文本大小、字体(通过将字体文件导入到资源中)、对齐方式等等。现在,看看游戏视图。
屏幕上出现的这个新的角(圆点)是什么?尝试缩小游戏,直到您可以完全看到画布。
Unity3D:了解画布大小
画布为什么这么大?你看,Unity 的长度是以单位计量的。这些单位是横跨整个游戏世界的小方块。画布使用默认的比例因子1 UI pixel = 1 Unit
,这意味着画布在场景编辑器中实际上是800
单位长。
现在尺寸理解已经不在我们的视线范围内,选择层次中的文本元素,放大文本,这样你就可以正确地看到它了。让我们给文本一个明亮的红色颜色,并在文本字段中写下我们想要它说的话。
Unity3D 画布:格式化文本用户界面元素
由于默认的标签大小比我们希望它显示的文本略短,我们可以通过拖动到目前为止我们在精灵中使用的蓝色手柄来增加标签框的大小。如果看不到蓝色手柄,只需点击编辑器左上角的最后一个选项,选择文本。
我们还建议尝试更改文本属性中的水平和垂直溢出选项,因为它们处理的问题与我们刚刚通过调整大小解决的问题相同。
现在,将标签拖到巨大画布的右上角。您将会看到 Unity 有很多区域,用户界面元素将在这些区域中自我修复。这包括画布的角和中点。当您处理需要看起来有条理和一致的更复杂的用户界面时,这将非常有用。
最后,进一步更改标签的大小,并增加属性中的字体大小。这确保了我们有一个在游戏中清晰可见的标签。
在下一个教程中,我们将学习如何实时更新文本用户界面元素,以使用它来显示分数和其他游戏进度信息。
Unity3D:实时更新画布上的用户界面元素
原文:https://www.studytonight.com/game-development-in-2D/update-ui-element-in-realtime-unity
在上一个教程中,我们学习了如何将文本标签用户界面元素添加到我们的游戏画布中。
我们只要进口一瓶雪碧就能轻松做到,对吗?我们为什么要费心制作画布?其中一个主要原因是,我们希望能够使用脚本修改文本、计数器和图像。事实上,让我们试试看!
从文本游戏对象中清除文本字段,这样它就什么也不会说了。
创建一个名为ScoreBehavior
的新脚本,并将其打开。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScoreBehaviour : MonoBehaviour
{
private Text thisText;
private int score;
void Start()
{
thisText = GetComponent<Text>();
// set score value to be zero
score = 0;
}
void Update()
{
// When P is hit
if(Input.GetKeyDown(KeyCode.P))
{
// add 500 points to score
score += 500;
}
// update text of Text element
thisText.text = "Score is " + score;
}
}
注:4 号线是这里相当重要的一条代码线。如果您忘记使用using
指令在代码中包含您正在使用的任何资源/类/包,您的 IDE 将会给您一个缺失引用错误。
我们还在这里做什么?首先,我们正在初始化一个名为thisText
的Text
类变量。文本类只有在顶部添加using UnityEngine.UI
时才可用,因为该类是UnityEngine.UI
包的一部分。
在Start()
功能中,你会看到可识别的语句,没有什么异常。第一个语句将thisText
变量分配给附加到游戏对象的文本组件,另一个语句只是将score
初始设置为0
。
在Update()
方法中,我们定义一个输入控件,在每次按下P
键时将500
点添加到分数中。
现在,Text
类有一个text
属性,它被存储为一个字符串,这个值就是那个实例将在游戏中实际显示的内容。事实上,每次在检查器视图的文本字段中键入内容时,您都将Text.text
属性设置为一个值。我们正在做的是在每一帧中更新我们的thisText
对象的文本值。
保存这个脚本,然后返回 Unity。标签好像消失了,但是当你运行游戏的时候。
按几下P
,就应该看到分数更新了!
从其他脚本更新文本用户界面元素
您可以通过在您的脚本中添加一个公共静态方法,并从其他行为脚本中调用它们来扩展这个概念。
什么是静态关键字?
关键字static
使一个方法或变量保持一个状态直到结束。使用定义static
方法的类名可以在其他类中调用。
此外,在static
方法中只能使用static
变量。
这通常是一个通用的概念,在 Java、C# 等编程语言中也是如此。
我们班ScoreBehaviour
会是这样的:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScoreBehaviour : MonoBehaviour
{
private Text thisText;
private static int score;
void Start()
{
thisText = GetComponent<Text>();
// set score value to be zero
score = 0;
}
void Update()
{
// update text of Text element
thisText.text = "Score is " + score;
}
// adding a new method to our class
public static void AddScore()
{
// add 500 points to score
score += 500;
}
}
如果你还记得,在我们捕捉到火球与目标碰撞的教程中,我们定义了一个类TargetBehaviour
,它定义了一个OnCollisionEnter2D
方法。让我们更新该方法,以便在子弹击中目标时更新分数。
public class TargetBehaviour : MonoBehaviour
{
void onCollisionEnter2D(Collision2D col)
{
// When target is hit
if(col.gameObject.tag == "Bullet")
{
Debug.Log("Target was Hit!");
// calling AddScore method
ScoreBehaviour.AddScore();
Destroy(col.gameObject);
Destroy(gameObject);
}
}
}
这个代码现在会在你每次命中目标时将分数改变500
。创建几个目标游戏对象的副本,并尝试它。
太好了。当然,UI 系统不仅仅是制作静态或动态文本。使用这种方法可以添加图像、滑块、按钮和很多熟悉的 UI 元素。我们敦促您尝试探索这些元素,并弄清楚它们在编辑器和脚本中是如何工作的。
从 Unity3D 中的其他行为脚本调用一个方法
原文:https://www.studytonight.com/game-development-in-2D/unity-call-method-from-other-script
在本教程中,我们将学习如何从附加到不同游戏对象的任何其他脚本中调用在一个脚本中定义的public
方法。
一种方法是使用我们在上一个教程中看到并使用的static
方法,但这不是正确的方法。
Unity3D:从其他脚本调用方法
让我们定义一个名为FirstScript
的新行为类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FirstScript : MonoBehaviour
{
void Start()
{
// some code
}
void Update()
{
// some code
}
public void SayHello()
{
Debug.Log("Hey there!");
}
}
现在让我们用名称SecondScript
定义我们的第二个类,并在第二个中调用第一个脚本中定义的方法doSomething()
。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SecondScript : MonoBehaviour
{
public FirstScript first;
void Start()
{
// some code
}
void Update()
{
// calling SayHello() method every frame
first.SayHello();
}
}
你好。你好。你好。...
它会继续打印嘿那里!在控制台中,直到游戏处于播放模式。
Unity3D:为游戏添加音效
原文:https://www.studytonight.com/game-development-in-2D/audio-in-unity
音频是一个非常有趣的概念,不仅仅是在游戏设计中,在研究它的本质时也是如此。它的感知方式取决于很多因素,当你试图控制或使用它时,必须考虑到这些因素。
对音频的感知一般涉及到声源的位置,以及如果它在移动的话,它移动的速度有多快(如果你学过物理学,你可能对多普勒效应很熟悉)。
在 Unity 中,音频源的定位对于表征其来源很重要。例如,我们需要确保播放瀑布声音的游戏对象与实际的瀑布游戏对象相匹配,并且玩家对该声音的感知是真实的。随着玩家越来越近,声音越来越大,确保声音平移随着瀑布相对于玩家的相对位置变化而变化,等等。
我们在 Unity 中处理与音频相关的两个主要组件,它们是:
- 音频监听器
- 音源
让我们来看看这些组件。
音频监听器
这是一个每次创建场景时都会自动附加到主摄像机的组件。它没有任何属性,因为它唯一的工作就是充当感知的点。建议让音频监听器保持原样。
音频源
这是实际上负责播放声音的组件。在常见的开发实践中,当您处理大型复杂结构时,通常最好制作一个空游戏对象来充当音频源,将其制作成一个孩子,这样您就清楚了音频源在哪里。
音频源组件有很多属性可以修改。这包括它的音高、平移、空间混合(我们稍后会讲到),如果你打开三维声音设置,你会发现添加多普勒效果和音量滚降的选项。
然而,这里最让我们感兴趣的是音频剪辑槽。这就是要播放的音效。Unity 支持相当多的常见声音格式,包括.mp3
、.ogg
等。
添加您自己的声音效果
在支持声音的文档得到支持之前,我们必须创建自己的声音效果。我们做了一对小音效的包,可以从这里下载。
让我们通过创建一个新的声音效果文件夹并将声音添加到其中,将这些声音效果导入到我们的项目中。
现在,由于主摄像机已经有了音频监听器,我们所要做的就是将音频源添加到我们相关的游戏对象中。
Unity3D:添加音频源
首先,我们将有一个声音效果,当我们的角色发射火球时播放。为此,我们将简单地为我们角色的射手游戏对象添加一个音频源。转到添加组件→音频→音频源。
在音频剪辑槽中,拖进您想要使用的声音效果。如果你下载了 soundpack,拖进 fire1.mp3 。现在,取消勾选【唤醒时播放 T4】复选框。这确保了这种声音不会在游戏对象一醒来就播放,在我们的例子中是在游戏一开始就播放。
在教程中,我们创建了一个类Shooter
,每次空格键被击中时,它都会实例化一个新的火球,让我们在发射新火球时添加声音。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooter : MonoBehaviour
{
public GameObject fireball;
private AudioSource source;
void Start()
{
source = GetComponent<AudioSource>();
}
void Update()
{
// When spacebar is hit
if(Input.GetKeyDown(KeyCode.Space))
{
// instantiate the fireball object
Instantiate(fireball,
new Vector3(gameObject.transform.position.x, gameObject.transform.position.y, 0),
new Quaternion(0, 0, 0, 0));
// play the sound
source.Play();
}
}
}
除了最初声明的音频源变量之外,当我们调用source.Play()
时,神奇的事情就发生了。这一行代码使引用的音频源播放加载到其插槽中的音频剪辑。它还有一个重载(变体)方法,用于在特定延迟后播放声音效果。
现在,保存这个脚本,只需用您的声音效果填充播放器音频源音频剪辑插槽中的插槽。(使用 fire1.mp3 如果你使用的是我们刚刚下载的 soundpack。)
同样,对于目标,我们将更新教程中使用的类TargetBehaviour
的脚本,检测碰撞,并为其附加一个音频源,然后使用该脚本:
public class TargetBehaviour : MonoBehaviour
{
private AudioSource source;
void Start()
{
source = GetComponent<AudioSource>();
}
void onCollisionEnter2D(Collision2D col)
{
// When target is hit
if(col.gameObject.tag == "Bullet")
{
Debug.Log("Target was Hit!");
// calling AddScore method
ScoreBehaviour.AddScore();
// play sound
source.Play();
Destroy(col.gameObject);
Destroy(gameObject);
}
}
}
当目标被摧毁时,用你的音效填充音频剪辑槽(如果你使用的是我们的 soundpack, dead3.mp3 )。玩游戏,玩家发射火球和击中目标时,可以听到音效!
Unity3D:添加音效摘要
总而言之,您必须做以下事情才能将音频剪辑添加到游戏中:
- 给你的游戏对象添加一个音频源组件,就像你添加一个刚体或长方体对撞机组件一样。
- 在游戏对象附带的脚本中,初始化一个类型为
AudioSource
的变量 - 在
Start()
方法中,使用GetComponent
将AudioSource
组件设置为AudioSource
变量。 - 想要声音播放时,调用
Play()
方法。
Unity3D 教程:到目前为止我们学到了什么
原文:https://www.studytonight.com/game-development-in-2D/a-quick-review
我们几乎完成了本系列的开始阶段。让我们快速回顾一下到目前为止所学的内容。
- 我们已经学习了 Unity 的一般工作原理,如何将精灵和有用的素材导入到我们的项目中。
- 我们已经学会了如何将物理添加到我们的精灵中,以便它们与游戏世界正确互动。
- 我们已经了解了游戏中对撞机和对撞机是什么,以及如何使用它们。
- 我们已经学会了根据需要实例化、修改和销毁游戏对象。
- 我们已经学会了如何在游戏中加入自己的 UI 元素,以及如何加入音效和音乐。
当然,这只是你和 Unity 在制作令人敬畏的游戏的道路上所能做的冰山一角。还有很多东西要学。但是具体怎么做呢?
如何学习
那么,我们所说的如何学习到底是什么意思呢?嗯,我们的意思是说你应该如何去探索你的能力,以及你如何与 Unity 合作。正如我所说的,我们只是学习了使用 Unity 的基础知识。你很可能需要学习额外的东西,然后才能让游戏准备出版。当然,学习不一定意味着获得关于新概念的知识。这也意味着弄清楚如何解决错误,如何让事情按照你希望的方式运行,以及如何以创造性的方式使用特性和素材。
假设我们想学习如何将自己的鼠标光标添加到游戏中。你可能想到的最直接的答案就是谷歌一下。然而,谷歌搜索也有一门艺术。请看下面的图片。你认为哪一个会对我们的问题产生满意的结果?
在我们看来,第二个查询似乎更好一点。让你的问题简单明了是快速回答的关键。一定要在查询中加入 Unity,这样很容易将你的问题误认为是另一个程序或游戏开发环境。(就像下面的谷歌搜索,不,不是我们要找的。)
接下来我们要提到的是论坛。Unity 有一个巨大的、繁荣的论坛,里面充满了有想法的人,有更多经验的人,以及刚刚开始游戏开发之旅的人。我们个人的大部分好奇心得到了满足,因为有人已经在论坛上问过这个问题。许多老开发者后悔在事业巅峰时没有这种水平的社区互动,因为回到游戏开发的旧时代,你几乎是一个人。这就是为什么你应该尽可能多地利用社区论坛。
接下来,学习新东西的另一个很好的资源是 YouTube。一个简单的搜索就能让你找到你想知道的几乎所有东西,因为 Unity 社区在视频分享平台上也非常活跃。
最后,我们有 Unity 的官方文档。这是一系列非常有用的文章和代码示例,涵盖了 Unity 组件和内部工作的所有方面,是当你不能全神贯注于某事或需要弄清楚代码如何工作时的绝佳参考指南。Unity 的文档既可以在线获得,也可以下载。安装 Unity 时可以选择下载文档,也可以从这里下载。