分类 技术 下的文章

“方其梦也,不知其梦也。梦之中又占其梦焉,觉而后知其梦也。”

—— 《庄子·齐物论》

递归是很神奇的,但是在大多数的编程类书藉中对递归讲解的并不好。它们只是给你展示一个递归阶乘的实现,然后警告你递归运行的很慢,并且还有可能因为栈缓冲区溢出而崩溃。“你可以将头伸进微波炉中去烘干你的头发,但是需要警惕颅内高压并让你的头发生爆炸,或者你可以使用毛巾来擦干头发。”难怪人们不愿意使用递归。但这种建议是很糟糕的,因为在算法中,递归是一个非常强大的思想。

我们来看一下这个经典的递归阶乘:

#include <stdio.h>

int factorial(int n)
{
    int previous = 0xdeadbeef;

    if (n == 0 || n == 1) {
        return 1;
    }

    previous = factorial(n-1);
    return n * previous;
}

int main(int argc)
{
    int answer = factorial(5);
    printf("%d\n", answer);
}

递归阶乘 - factorial.c

函数调用自身的这个观点在一开始是让人很难理解的。为了让这个过程更形象具体,下图展示的是当调用 factorial(5) 并且达到 n == 1这行代码 时,栈上 端点的情况:

每次调用 factorial 都生成一个新的 栈帧。这些栈帧的创建和 销毁 是使得递归版本的阶乘慢于其相应的迭代版本的原因。在调用返回之前,累积的这些栈帧可能会耗尽栈空间,进而使你的程序崩溃。

而这些担心经常是存在于理论上的。例如,对于每个 factorial 的栈帧占用 16 字节(这可能取决于栈排列以及其它因素)。如果在你的电脑上运行着现代的 x86 的 Linux 内核,一般情况下你拥有 8 GB 的栈空间,因此,factorial 程序中的 n 最多可以达到 512,000 左右。这是一个 巨大无比的结果,它将花费 8,971,833 比特来表示这个结果,因此,栈空间根本就不是什么问题:一个极小的整数 —— 甚至是一个 64 位的整数 —— 在我们的栈空间被耗尽之前就早已经溢出了成千上万次了。

过一会儿我们再去看 CPU 的使用,现在,我们先从比特和字节回退一步,把递归看作一种通用技术。我们的阶乘算法可归结为:将整数 N、N-1、 … 1 推入到一个栈,然后将它们按相反的顺序相乘。实际上我们使用了程序调用栈来实现这一点,这是它的细节:我们在堆上分配一个栈并使用它。虽然调用栈具有特殊的特性,但是它也只是又一种数据结构而已,你可以随意使用。我希望这个示意图可以让你明白这一点。

当你将栈调用视为一种数据结构,有些事情将变得更加清晰明了:将那些整数堆积起来,然后再将它们相乘,这并不是一个好的想法。那是一种有缺陷的实现:就像你拿螺丝刀去钉钉子一样。相对更合理的是使用一个迭代过程去计算阶乘。

但是,螺丝钉太多了,我们只能挑一个。有一个经典的面试题,在迷宫里有一只老鼠,你必须帮助这只老鼠找到一个奶酪。假设老鼠能够在迷宫中向左或者向右转弯。你该怎么去建模来解决这个问题?

就像现实生活中的很多问题一样,你可以将这个老鼠找奶酪的问题简化为一个图,一个二叉树的每个结点代表在迷宫中的一个位置。然后你可以让老鼠在任何可能的地方都左转,而当它进入一个死胡同时,再回溯回去,再右转。这是一个老鼠行走的 迷宫示例:

每到边缘(线)都让老鼠左转或者右转来到达一个新的位置。如果向哪边转都被拦住,说明相关的边缘不存在。现在,我们来讨论一下!这个过程无论你是调用栈还是其它数据结构,它都离不开一个递归的过程。而使用调用栈是非常容易的:

#include <stdio.h>
#include "maze.h"

int explore(maze_t *node)
{
    int found = 0;

    if (node == NULL)
    {
        return 0;
    }
    if (node->hasCheese){
        return 1;// found cheese
        }

    found = explore(node->left) || explore(node->right);
    return found;
    }

    int main(int argc)
    {
        int found = explore(&maze);
    }

递归迷宫求解 下载

当我们在 maze.c:13 中找到奶酪时,栈的情况如下图所示。你也可以在 GDB 输出 中看到更详细的数据,它是使用 命令 采集的数据。

它展示了递归的良好表现,因为这是一个适合使用递归的问题。而且这并不奇怪:当涉及到算法时,递归是规则,而不是例外。它出现在如下情景中——进行搜索时、进行遍历树和其它数据结构时、进行解析时、需要排序时——它无处不在。正如众所周知的 pi 或者 e,它们在数学中像“神”一样的存在,因为它们是宇宙万物的基础,而递归也和它们一样:只是它存在于计算结构中。

Steven Skienna 的优秀著作 算法设计指南 的精彩之处在于,他通过 “战争故事” 作为手段来诠释工作,以此来展示解决现实世界中的问题背后的算法。这是我所知道的拓展你的算法知识的最佳资源。另一个读物是 McCarthy 的 关于 LISP 实现的的原创论文。递归在语言中既是它的名字也是它的基本原理。这篇论文既可读又有趣,在工作中能看到大师的作品是件让人兴奋的事情。

回到迷宫问题上。虽然它在这里很难离开递归,但是并不意味着必须通过调用栈的方式来实现。你可以使用像 RRLL 这样的字符串去跟踪转向,然后,依据这个字符串去决定老鼠下一步的动作。或者你可以分配一些其它的东西来记录追寻奶酪的整个状态。你仍然是实现了一个递归的过程,只是需要你实现一个自己的数据结构。

那样似乎更复杂一些,因为栈调用更合适。每个栈帧记录的不仅是当前节点,也记录那个节点上的计算状态(在这个案例中,我们是否只让它走左边,或者已经尝试向右)。因此,代码已经变得不重要了。然而,有时候我们因为害怕溢出和期望中的性能而放弃这种优秀的算法。那是很愚蠢的!

正如我们所见,栈空间是非常大的,在耗尽栈空间之前往往会遇到其它的限制。一方面可以通过检查问题大小来确保它能够被安全地处理。而对 CPU 的担心是由两个广为流传的有问题的示例所导致的: 哑阶乘 dumb factorial 和可怕的无记忆的 O( 2 n ) Fibonacci 递归。它们并不是栈递归算法的正确代表。

事实上栈操作是非常快的。通常,栈对数据的偏移是非常准确的,它在 缓存 中是热数据,并且是由专门的指令来操作它的。同时,使用你自己定义的在堆上分配的数据结构的相关开销是很大的。经常能看到人们写的一些比栈调用递归更复杂、性能更差的实现方法。最后,现代的 CPU 的性能都是 非常好的 ,并且一般 CPU 不会是性能瓶颈所在。在考虑牺牲程序的简单性时要特别注意,就像经常考虑程序的性能及性能的测量那样。

下一篇文章将是探秘栈系列的最后一篇了,我们将了解尾调用、闭包、以及其它相关概念。然后,我们就该深入我们的老朋友—— Linux 内核了。感谢你的阅读!


via:https://manybutfinite.com/post/recursion/

作者:Gustavo Duarte 译者:qhwdw 校对:FSSlc

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

通过在 shell 中实现多项功能,该作业将使你更加熟悉 Unix 系统调用接口和 shell。你可以在支持 Unix API 的任何操作系统(一台 Linux Athena 机器、装有 Linux 或 Mac OS 的笔记本电脑等)上完成此作业。请在第一次上课前将你的 shell 提交到网站

如果你在练习中遇到困难或不理解某些内容时,你不要羞于给员工邮件列表发送邮件,但我们确实希望全班的人能够自行处理这级别的 C 编程。如果你对 C 不是很熟悉,可以认为这个是你对 C 熟悉程度的检查。再说一次,如果你有任何问题,鼓励你向我们寻求帮助。

下载 xv6 shell 的框架,然后查看它。框架 shell 包含两个主要部分:解析 shell 命令并实现它们。解析器只能识别简单的 shell 命令,如下所示:

ls > y
cat < y | sort | uniq | wc > y1
cat y1
rm y1
ls | sort | uniq | wc
rm y

将这些命令剪切并粘贴到 t.sh 中。

你可以按如下方式编译框架 shell 的代码:

$ gcc sh.c

它会生成一个名为 a.out 的文件,你可以运行它:

$ ./a.out < t.sh

执行会崩溃,因为你还没有实现其中的几个功能。在本作业的其余部分中,你将实现这些功能。

执行简单的命令

实现简单的命令,例如:

$ ls

解析器已经为你构建了一个 execcmd,所以你唯一需要编写的代码是 runcmd 中的 case ' '。要测试你可以运行 “ls”。你可能会发现查看 exec 的手册页是很有用的。输入 man 3 exec

你不必实现引用(即将双引号之间的文本视为单个参数)。

I/O 重定向

实现 I/O 重定向命令,这样你可以运行:

echo "6.828 is cool" > x.txt
cat < x.txt

解析器已经识别出 '>' 和 '<',并且为你构建了一个 redircmd,所以你的工作就是在 runcmd 中为这些符号填写缺少的代码。确保你的实现在上面的测试输入中正确运行。你可能会发现 openman 2 open) 和 close 的 man 手册页很有用。

请注意,此 shell 不会像 bashtcshzsh 或其他 UNIX shell 那样处理引号,并且你的示例文件 x.txt 预计包含引号。

实现管道

实现管道,这样你可以运行命令管道,例如:

$ ls | sort | uniq | wc

解析器已经识别出 “|”,并且为你构建了一个 pipecmd,所以你必须编写的唯一代码是 runcmd 中的 case '|'。测试你可以运行上面的管道。你可能会发现 pipeforkclosedup 的 man 手册页很有用。

现在你应该可以正确地使用以下命令:

$ ./a.out < t.sh

无论是否完成挑战任务,不要忘记将你的答案提交给网站

挑战练习

如果你想进一步尝试,可以将所选的任何功能添加到你的 shell。你可以尝试以下建议之一:

  • 实现由 ; 分隔的命令列表
  • 通过实现 () 来实现子 shell
  • 通过支持 wait 在后台执行命令
  • 实现参数引用

所有这些都需要改变解析器和 runcmd 函数。


via: https://sipb.mit.edu/iap/6.828/lab/shell/

作者:mit 译者:geekpi 校对:wxy

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

在第三篇文章中,我们将解释如何生成用于日常工作的 PGP 子密钥。

在本系列教程中,我们提供了使用 PGP 的实用指南。在此之前,我们介绍了基本工具和概念,并介绍了如何生成并保护您的主 PGP 密钥。在第三篇文章中,我们将解释如何生成用于日常工作的 PGP 子密钥。

清单

  1. 生成 2048 位加密子密钥(必要)
  2. 生成 2048 位签名子密钥(必要)
  3. 生成一个 2048 位验证子密钥(推荐)
  4. 将你的公钥上传到 PGP 密钥服务器(必要)
  5. 设置一个刷新的定时任务(必要)

注意事项

现在我们已经创建了主密钥,让我们创建用于日常工作的密钥。我们创建 2048 位的密钥是因为很多专用硬件(我们稍后会讨论这个)不能处理更长的密钥,但同样也是出于实用的原因。如果我们发现自己处于一个 2048 位 RSA 密钥也不够好的世界,那将是由于计算或数学有了基本突破,因此更长的 4096 位密钥不会产生太大的差别。

创建子密钥

要创建子密钥,请运行:

$ gpg --quick-add-key [fpr] rsa2048 encr
$ gpg --quick-add-key [fpr] rsa2048 sign

用你密钥的完整指纹替换 [fpr]

你也可以创建验证密钥,这能让你将你的 PGP 密钥用于 ssh:

$ gpg --quick-add-key [fpr] rsa2048 auth

你可以使用 gpg --list-key [fpr] 来查看你的密钥信息:

pub rsa4096 2017-12-06 [C] [expires: 2019-12-06]
 111122223333444455556666AAAABBBBCCCCDDDD
uid [ultimate] Alice Engineer <[email protected]>
uid [ultimate] Alice Engineer <[email protected]>
sub rsa2048 2017-12-06 [E]
sub rsa2048 2017-12-06 [S]

上传你的公钥到密钥服务器

你的密钥创建已完成,因此现在需要你将其上传到一个公共密钥服务器,使其他人能更容易找到密钥。 (如果你不打算实际使用你创建的密钥,请跳过这一步,因为这只会在密钥服务器上留下垃圾数据。)

$ gpg --send-key [fpr]

如果此命令不成功,你可以尝试指定一台密钥服务器以及端口,这很有可能成功:

$ gpg --keyserver hkp://pgp.mit.edu:80 --send-key [fpr]

大多数密钥服务器彼此进行通信,因此你的密钥信息最终将与所有其他密钥信息同步。

关于隐私的注意事项:密钥服务器是完全公开的,因此在设计上会泄露有关你的潜在敏感信息,例如你的全名、昵称以及个人或工作邮箱地址。如果你签名了其他人的钥匙或某人签名了你的钥匙,那么密钥服务器还会成为你的社交网络的泄密者。一旦这些个人信息发送给密钥服务器,就不可能被编辑或删除。即使你撤销签名或身份,它也不会将你的密钥记录删除,它只会将其标记为已撤消 —— 这甚至会显得更显眼。

也就是说,如果你参与公共项目的软件开发,以上所有信息都是公开记录,因此通过密钥服务器另外让这些信息可见,不会导致隐私的净损失。

上传你的公钥到 GitHub

如果你在开发中使用 GitHub(谁不是呢?),则应按照他们提供的说明上传密钥:

要生成适合粘贴的公钥输出,只需运行:

$ gpg --export --armor [fpr]

设置一个刷新定时任务

你需要定期刷新你的钥匙环,以获取其他人公钥的最新更改。你可以设置一个定时任务来做到这一点:

$ crontab -e

在新行中添加以下内容:

@daily /usr/bin/gpg2 --refresh >/dev/null 2>&1

注意:检查你的 gpggpg2 命令的完整路径,如果你的 gpg 是旧式的 GnuPG v.1,请使用 gpg2。

通过 Linux 基金会和 edX 的免费“Introduction to Linux” 课程了解关于 Linux 的更多信息。


via: https://www.linux.com/blog/learn/pgp/2018/2/protecting-code-integrity-pgp-part-3-generating-pgp-subkeys

作者:Konstantin Ryabitsev 译者:geekpi 校对:wxy

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

如何使用 iptables 防火墙保护你的网络免遭黑客攻击。

即便是被入侵检测和隔离系统所保护的远程网络,黑客们也在寻找各种精巧的方法入侵。IDS/IPS 不能停止或者减少那些想要接管你的网络控制权的黑客攻击。不恰当的配置允许攻击者绕过所有部署的安全措施。

在这篇文章中,我将会解释安全工程师或者系统管理员该怎样避免这些攻击。

几乎所有的 Linux 发行版都带着一个内建的防火墙来保护运行在 Linux 主机上的进程和应用程序。大多数防火墙都按照 IDS/IPS 解决方案设计,这样的设计的主要目的是检测和避免恶意包获取网络的进入权。

Linux 防火墙通常有两种接口:iptables 和 ipchains 程序(LCTT 译注:在支持 systemd 的系统上,采用的是更新的接口 firewalld)。大多数人将这些接口称作 iptables 防火墙或者 ipchains 防火墙。这两个接口都被设计成包过滤器。iptables 是有状态防火墙,其基于先前的包做出决定。ipchains 不会基于先前的包做出决定,它被设计为无状态防火墙。

在这篇文章中,我们将会专注于内核 2.4 之后出现的 iptables 防火墙。

有了 iptables 防火墙,你可以创建策略或者有序的规则集,规则集可以告诉内核该如何对待特定的数据包。在内核中的是Netfilter 框架。Netfilter 既是框架也是 iptables 防火墙的项目名称。作为一个框架,Netfilter 允许 iptables 勾连被设计来操作数据包的功能。概括地说,iptables 依靠 Netfilter 框架构筑诸如过滤数据包数据的功能。

每个 iptables 规则都被应用到一个表中的链上。一个 iptables 链就是一个比较包中相似特征的规则集合。而表(例如 nat 或者 mangle)则描述不同的功能目录。例如, mangle 表用于修改包数据。因此,特定的修改包数据的规则被应用到这里;而过滤规则被应用到 filter 表,因为 filter 表过滤包数据。

iptables 规则有一个匹配集,以及一个诸如 Drop 或者 Deny 的目标,这可以告诉 iptables 对一个包做什么以符合规则。因此,没有目标和匹配集,iptables 就不能有效地处理包。如果一个包匹配了一条规则,目标会指向一个将要采取的特定措施。另一方面,为了让 iptables 处理,每个数据包必须匹配才能被处理。

现在我们已经知道 iptables 防火墙如何工作,让我们着眼于如何使用 iptables 防火墙检测并拒绝或丢弃欺骗地址吧。

打开源地址验证

作为一个安全工程师,在处理远程的欺骗地址的时候,我采取的第一步是在内核打开源地址验证。

源地址验证是一种内核层级的特性,这种特性丢弃那些伪装成来自你的网络的包。这种特性使用反向路径过滤器方法来检查收到的包的源地址是否可以通过包到达的接口可以到达。(LCTT 译注:到达的包的源地址应该可以从它到达的网络接口反向到达,只需反转源地址和目的地址就可以达到这样的效果)

利用下面简单的脚本可以打开源地址验证而不用手工操作:

#!/bin/sh
#作者: Michael K Aboagye
#程序目标: 打开反向路径过滤
#日期: 7/02/18
#在屏幕上显示 “enabling source address verification”
echo -n "Enabling source address verification…"
#将值0覆盖为1来打开源地址验证
echo 1 > /proc/sys/net/ipv4/conf/default/rp_filter
echo "completed"

上面的脚本在执行的时候只显示了 Enabling source address verification 这条信息而不会换行。默认的反向路径过滤的值是 00 表示没有源验证。因此,第二行简单地将默认值 0 覆盖为 11 表示内核将会通过确认反向路径来验证源地址。

最后,你可以使用下面的命令通过选择 DROP 或者 REJECT 目标之一来丢弃或者拒绝来自远端主机的欺骗地址。但是,处于安全原因的考虑,我建议使用 DROP 目标。

像下面这样,用你自己的 IP 地址代替 IP-address 占位符。另外,你必须选择使用 REJECT 或者 DROP 中的一个,这两个目标不能同时使用。

iptables -A INPUT -i internal_interface -s IP_address -j REJECT / DROP  
iptables -A INPUT -i internal_interface -s 192.168.0.0/16  -j REJECT / DROP

这篇文章只提供了如何使用 iptables 防火墙来避免远端欺骗攻击的基础知识。


via: https://opensource.com/article/18/2/block-local-spoofed-addresses-using-linux-firewall

作者:Michael Kwaku Aboagye 译者:leemeans 校对:wxy

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

有很多监控工具可用来监控本地和远程 Linux 系统,一个很好的例子是 Cockpit。但是,这些工具的安装和使用比较复杂,至少对于新手管理员来说是这样。新手管理员可能需要花一些时间来弄清楚如何配置这些工具来监视系统。如果你想要以快速且粗略地在局域网中一次监控多台主机,你可能需要了解一下 “rwho” 工具。只要安装了 rwho 实用程序,它将立即快速地监控本地和远程系统。你什么都不用配置!你所要做的就是在要监视的系统上安装 “rwho” 工具。

请不要将 rwho 视为功能丰富且完整的监控工具。这只是一个简单的工具,它只监视远程系统的“正常运行时间”(uptime),“负载”(load)和登录的用户。使用 “rwho” 使用程序,我们可以发现谁在哪台计算机上登录;一个被监视的计算机的列表,列出了正常运行时间(自上次重新启动以来的时间);有多少用户登录了;以及在过去的 1、5、15 分钟的平均负载。不多不少!而且,它只监视同一子网中的系统。因此,它非常适合小型和家庭办公网络。

在 Linux 中监控多台主机

让我来解释一下 rwho 是如何工作的。每个在网络上使用 rwho 的系统都将广播关于它自己的信息,其他计算机可以使用 rwhod 守护进程来访问这些信息。因此,网络上的每台计算机都必须安装 rwho。此外,为了分发或访问其他主机的信息,必须允许 rwho 端口(例如端口 513/UDP)通过防火墙/路由器。

好的,让我们来安装它。

我在 Ubuntu 16.04 LTS 服务器上进行了测试,rwho 在默认仓库中可用,所以,我们可以使用像下面这样的 APT 软件包管理器来安装它。

$ sudo apt-get install rwho

在基于 RPM 的系统如 CentOS、 Fedora、 RHEL 上,使用以下命令来安装它:

$ sudo yum install rwho

如果你在防火墙/路由器之后,确保你已经允许使用 rwhod 513 端口。另外,使用命令验证 rwhod 守护进程是否正在运行:

$ sudo systemctl status rwhod

如果它尚未启动,运行以下命令启用并启动 rwhod 服务:

$ sudo systemctl enable rwhod
$ sudo systemctl start rwhod

现在是时候来监视系统了。运行以下命令以发现谁在哪台计算机上登录:

$ rwho
ostechni ostechnix:pts/5 Mar 12 17:41
root server:pts/0 Mar 12 17:42

正如你所看到的,目前我的局域网中有两个系统。本地系统用户是 ostechnix (Ubuntu 16.04 LTS),远程系统的用户是 root (CentOS 7)。可能你已经猜到了,rwhowho 命令相似,但它会监视远程系统。

而且,我们可以使用以下命令找到网络上所有正在运行的系统的正常运行时间:

$ ruptime
ostechnix up 2:17, 1 user, load 0.09, 0.03, 0.01
server up 1:54, 1 user, load 0.00, 0.01, 0.05

这里,ruptime(类似于 uptime 命令)显示了我的 Ubuntu(本地) 和 CentOS(远程)系统的总运行时间。明白了吗?棒极了!以下是我的 Ubuntu 16.04 LTS 系统的示例屏幕截图:

你可以在以下位置找到有关局域网中所有其他机器的信息:

$ ls /var/spool/rwho/
whod.ostechnix whod.server

它很小,但却非常有用,可以发现谁在哪台计算机上登录,以及正常运行时间和系统负载详情。

建议阅读:

请注意,这种方法有一个严重的漏洞。由于有关每台计算机的信息都通过网络进行广播,因此该子网中的每个人都可能获得此信息。通常情况下可以,但另一方面,当有关网络的信息分发给非授权用户时,这可能是不必要的副作用。因此,强烈建议在受信任和受保护的局域网中使用它。

更多的信息,查找 man 手册页。

$ man rwho

好了,这就是全部了。更多好东西要来了,敬请期待!

干杯!


via: https://www.ostechnix.com/how-to-quickly-monitor-multiple-hosts-in-linux/

作者:SK 译者:MjSeven 校对:wxy

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

通过这 10 个基础命令开始掌握 Linux 命令行。

你可能认为你是 Linux 新手,但实际上并不是。全球互联网用户有 3.74 亿,他们都以某种方式使用 Linux,因为 Linux 服务器占据了互联网的 90%。大多数现代路由器运行 Linux 或 Unix,TOP500 超级计算机 也依赖于 Linux。如果你拥有一台 Android 智能手机,那么你的操作系统就是由 Linux 内核构建的。

换句话说,Linux 无处不在。

但是使用基于 Linux 的技术和使用 Linux 本身是有区别的。如果你对 Linux 感兴趣,但是一直在使用 PC 或者 Mac 桌面,你可能想知道你需要知道什么才能使用 Linux 命令行接口(CLI),那么你来到了正确的地方。

下面是你需要知道的基本的 Linux 命令。每一个都很简单,也很容易记住。换句话说,你不必成为比尔盖茨就能理解它们。

1、 ls

你可能会想:“这是(is)什么东西?”不,那不是一个印刷错误 —— 我真的打算输入一个小写的 l。ls,或者说 “list”, 是你需要知道的使用 Linux CLI 的第一个命令。这个 list 命令在 Linux 终端中运行,以显示在存放在相应文件系统下的所有主要目录。例如,这个命令:

ls /applications

显示存储在 applications 文件夹下的每个文件夹,你将使用它来查看文件、文件夹和目录。

显示所有隐藏的文件都可以使用命令 ls -a

2、 cd

这个命令是你用来跳转(或“更改”)到一个目录的。它指导你如何从一个文件夹导航到另一个文件夹。假设你位于 Downloads 文件夹中,但你想到名为 Gym Playlist 的文件夹中,简单地输入 cd Gym Playlist 将不起作用,因为 shell 不会识别它,并会报告你正在查找的文件夹不存在(LCTT 译注:这是因为目录名中有空格)。要跳转到那个文件夹,你需要包含一个反斜杠。改命令如下所示:

cd Gym\ Playlist

要从当前文件夹返回到上一个文件夹,你可以在该文件夹输入 cd ..。把这两个点想象成一个后退按钮。

3、 mv

该命令将文件从一个文件夹转移到另一个文件夹;mv 代表“移动”。你可以使用这个简单的命令,就像你把一个文件拖到 PC 上的一个文件夹一样。

例如,如果我想创建一个名为 testfile 的文件来演示所有基本的 Linux 命令,并且我想将它移动到我的 Documents 文件夹中,我将输入这个命令:

mv /home/sam/testfile /home/sam/Documents/

命令的第一部分(mv)说我想移动一个文件,第二部分(home/sam/testfile)表示我想移动的文件,第三部分(/home/sam/Documents/)表示我希望传输文件的位置。

4、 快捷键

好吧,这不止一个命令,但我忍不住把它们都包括进来。为什么?因为它们能节省时间并避免经历头痛。

  • CTRL+K 从光标处剪切文本直至本行结束
  • CTRL+Y 粘贴文本
  • CTRL+E 将光标移到本行的末尾
  • CTRL+A 将光标移动到本行的开头
  • ALT+F 跳转到下一个空格处
  • ALT+B 回到前一个空格处
  • ALT+Backspace 删除前一个词
  • CTRL+W 剪切光标前一个词
  • Shift+Insert 将文本粘贴到终端中
  • Ctrl+D 注销

这些命令在许多方面都能派上用场。例如,假设你在命令行文本中拼错了一个单词:

sudo apt-get intall programname

你可能注意到 install 拼写错了,因此该命令无法工作。但是快捷键可以让你很容易回去修复它。如果我的光标在这一行的末尾,我可以按下两次 ALT+B 来将光标移动到下面用 ^ 符号标记的地方:

sudo apt-get^intall programname

现在,我们可以快速地添加字母 s 来修复 install,十分简单!

5、 mkdir

这是你用来在 Linux 环境下创建目录或文件夹的命令。例如,如果你像我一样喜欢 DIY,你可以输入 mkdir DIY 为你的 DIY 项目创建一个目录。

6、 at

如果你想在特定时间运行 Linux 命令,你可以将 at 添加到语句中。语法是 at 后面跟着你希望命令运行的日期和时间,然后命令提示符变为 at>,这样你就可以输入在上面指定的时间运行的命令。

例如:

at 4:08 PM Sat
at> cowsay 'hello'
at> CTRL+D

这将会在周六下午 4:08 运行 cowsay 程序。

7、 rmdir

这个命令允许你通过 Linux CLI 删除一个目录。例如:

rmdir testdirectory

请记住,这个命令不会删除里面有文件的目录。这只在删除空目录时才起作用。

8、 rm

如果你想删除文件,rm 命令就是你想要的。它可以删除文件和目录。要删除一个文件,键入 rm testfile,或者删除一个目录和里面的文件,键入 rm -r

9、 touch

touch 命令,也就是所谓的 “make file 的命令”,允许你使用 Linux CLI 创建新的、空的文件。很像 mkdir 创建目录,touch 会创建文件。例如,touch testfile 将会创建一个名为 testfile 的空文件。

10、 locate

这个命令是你在 Linux 系统中用来查找文件的命令。就像在 Windows 中搜索一样,如果你忘了存储文件的位置或它的名字,这是非常有用的。

例如,如果你有一个关于区块链用例的文档,但是你忘了标题,你可以输入 locate -blockchain 或者通过用星号分隔单词来查找 "blockchain use cases",或者星号(*)。例如:

locate -i*blockchain*use*cases*

还有很多其他有用的 Linux CLI 命令,比如 pkill 命令,如果你开始关机但是你意识到你并不想这么做,那么这条命令很棒。但是这里描述的 10 个简单而有用的命令是你开始使用 Linux 命令行所需的基本知识。


via: https://opensource.com/article/18/4/10-commands-new-linux-users

作者:Sam Bocetta 译者:MjSeven 校对:wxy

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