分类 技术 下的文章

这 13 个 Git 技巧将使你的版本控制技能 +1、+1、+1……

Git 是一个分布式版本控制系统,它已经成为开源世界中源代码控制的默认工具,在 4 月 7 日这天,它 13 岁了。使用 Git 令人沮丧的事情之一是你需要知道更多才能有效地使用 Git。但这也可能是使用 Git 比较美妙的一件事,因为没有什么比发现一个新技巧来简化或提高你的工作流的效率更令人快乐了。

为了纪念 Git 的 13 岁生日,这里有 13 条技巧和诀窍来让你的 Git 经验更加有用和强大。从你可能忽略的一些基本知识开始,并扩展到一些真正的高级用户技巧!

1、 你的 ~/.gitconfig 文件

当你第一次尝试使用 git 命令向仓库提交一个更改时,你可能会收到这样的欢迎信息:

*** Please tell me who you are.

Run

  git config --global user.email "[email protected]"

  git config --global user.name "Your Name"

to set your account's default identity.

你可能没有意识到正是这些命令在修改 ~/.gitconfig 的内容,这是 Git 存储全局配置选项的地方。你可以通过 ~/.gitconfig 文件来做大量的事,包括定义别名、永久性打开(或关闭)特定命令选项,以及修改 Git 工作方式(例如,git diff 使用哪个 diff 算法,或者默认使用什么类型的合并策略)。你甚至可以根据仓库的路径有条件地包含其他配置文件!所有细节请参阅 man git-config

2、 你仓库中的 .git/config 文件

在之前的技巧中,你可能想知道 git config 命令中 --global 标志是干什么的。它告诉 Git 更新 ~/.gitconfig 中的“全局”配置。当然,有全局配置也意味着会有本地配置,显然,如果你省略 --global 标志,git config 将改为更新仓库特有的配置,该配置存储在 .git/config 中。

.git/config 文件中设置的选项将覆盖 ~/.gitconfig 文件中的所有设置。因此,例如,如果你需要为特定仓库使用不同的电子邮件地址,则可以运行 git config user.email "[email protected]"。然后,该仓库中的任何提交都将使用你单独配置的电子邮件地址。如果你在开源项目中工作,而且希望它们显示自己的电子邮件地址,同时仍然使用自己工作邮箱作为主 Git 配置,这非常有用。

几乎任何你可以在 ~/.gitconfig 中设置的东西,你也可以在 .git/config 中进行设置,以使其作用于特定的仓库。在下面的技巧中,当我提到将某些内容添加到 ~/.gitconfig 时,只需记住你也可以在特定仓库的 .git/config 中添加来设置那个选项。

3、 别名

别名是你可以在 ~/.gitconfig 中做的另一件事。它的工作原理就像命令行中的 shell —— 它们设定一个新的命令名称,可以调用一个或多个其他命令,通常使用一组特定的选项或标志。它们对于那些你经常使用的又长又复杂的命令来说非常有效。

你可以使用 git config 命令来定义别名 —— 例如,运行 git config --global --add alias.st status 将使运行 git st 与运行 git status 做同样的事情 —— 但是我在定义别名时发现,直接编辑 ~/.gitconfig 文件通常更容易。

如果你选择使用这种方法,你会发现 ~/.gitconfig 文件是一个 INI 文件。INI 是一种带有特定段落的键值对文件格式。当添加一个别名时,你将改变 [alias] 段落。例如,定义上面相同的 git st 别名时,添加如下到文件:

[alias]
st = status

(如果已经有 [alias] 段落,只需将第二行添加到现有部分。)

4、 shell 命令中的别名

别名不仅仅限于运行其他 Git 子命令 —— 你还可以定义运行其他 shell 命令的别名。这是一个用来处理一个反复发生的、罕见和复杂的任务的很好方式:一旦你确定了如何完成它,就可以在别名下保存该命令。例如,我有一些 复刻 fork 的开源项目的仓库,并进行了一些本地修改。我想跟上项目正在进行的开发工作,并保存我本地的变化。为了实现这个目标,我需要定期将来自上游仓库的更改合并到我复刻的项目中 —— 我通过使用我称之为 upstream-merge 的别名来完成。它是这样定义的:

upstream-merge = !"git fetch origin -v && git fetch upstream -v && git merge upstream/master && git push"

别名定义开头的 ! 告诉 Git 通过 shell 运行这个命令。这个例子涉及到运行一些 git 命令,但是以这种方式定义的别名可以运行任何 shell 命令。

(注意,如果你想复制我的 upstream-merge 别名,你需要确保你有一个名为 upstream 的 Git 远程仓库,指向你已经分配的上游仓库,你可以通过运行 git remote add upstream <URL to repo> 来添加一个。)

5、 可视化提交图

如果你在一个有很多分支活动的项目上开发,有时可能很难掌握所有正在发生的工作以及它们之间的相关性。各种图形用户界面工具可让你获取不同分支的图片并在所谓的“提交图表”中提交。例如,以下是我使用 GitLab 提交图表查看器可视化的我的一个仓库的一部分:

 title=

如果你是一个专注于命令行的用户或者发现分支切换工具让人分心,那么可以从命令行获得类似的提交视图。这就是 git log 命令的 --graph 参数出现的地方:

 title=

以下命令可视化相同仓库可达到相同效果:

git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative

--graph 选项将图添加到日志的左侧,--abbrev-commit 缩短提交的 SHA 值,--date=relative 以相对方式表示日期,以及 --pretty 来处理所有其他自定义格式。我有个 git lg 别名用于这个功能,它是我最常用的 10 个命令之一。

6、 更优雅的强制推送

有时,你越是想避开越避不开,你会发现你需要运行 git push --force 来覆盖仓库远程副本上的历史记录。你可能得到了一些反馈,需要你进行交互式 变基 rebase ,或者你可能已经搞砸了,并希望隐藏“罪证”。

当其他人在仓库的远程副本的同一分支上进行更改时,会发生强制推送的危险。当你强制推送已重写的历史记录时,这些提交将会丢失。这就是 git push --force-with-lease 出现的原因 -- 如果远程分支已经更新,它不会允许你强制推送,这确保你不会丢掉别人的工作。

7、 git add -N

你是否使用过 git commit -a 在一次行动中提交所有未完成的修改,但在你推送完提交后才发现 git commit -a 忽略了新添加的文件?你可以使用 git add -N (想想 “notify”) 来解决这个问题,告诉 Git 在第一次实际提交它们之前,你希望在提交中包含新增文件。

8、 git add -p

使用 Git 时的最佳做法是确保每次提交都只包含一个逻辑修改 —— 无论这是修复错误还是添加新功能。然而,有时当你在工作时,你的仓库中的修改最终应该使用多个提交。你怎样才能设法把事情分开,使每个提交只包含适当的修改呢?git add --patch 来拯救你了!

这个标志会让 git add 命令查看你工作副本中的所有变化,并为每个变化询问你是否想要将它提交、跳过,或者推迟决定(你可以在运行该命令后选择 ? 来查看其他更强大的选项)。git add -p 是生成结构良好的提交的绝佳工具。

9、 git checkout -p

git add -p 类似,git checkout 命令也接受 --patch-p 选项,这会使其在本地工作副本中显示每个“大块”的改动,并允许丢弃它 —— 简单来说就是将本地工作副本恢复到更改之前的状态。

这真的很棒。例如,当你追踪一个 bug 时引入了一堆调试日志语句,修正了这个 bug 之后,你可以先使用 git checkout -p 移除所有新的调试日志,然后 git add -p 来添加 bug 修复。没有比组合一个优雅的、结构良好的提交更令人满意!

10、 变基时执行命令

有些项目有一个规则,即存储库中的每个提交都必须处于可工作状态 —— 也就是说,在每次提交时,应该可以编译该代码,或者应该运行测试套件而不会失败。 当你在分支上工作时,这并不困难,但是如果你最终因为某种原因需要 变基 rebase 时,那么需要逐步完成每个变基的提交以确保你没有意外地引入一个中断,而这个过程是乏味的。

幸运的是,git rebase 已经覆盖了 -x--exec 选项。git rebase -x <cmd> 将在每个提交在变基中被应用后运行该命令。因此,举个例子,如果你有一个项目,其中使用 npm run tests 运行你的测试套件,git rebase -x npm run tests 将在变基期间每次提交之后运行测试套件。这使你可以查看测试套件是否在任何变基的提交中失败,以便你可以确认测试套件在每次提交时仍能通过。

11、 基于时间的修订引用

很多 Git 子命令都接受一个修订参数来决定命令作用于仓库的哪个部分,可以是某次特定的提交的 SHA1 值,一个分支的名称,甚至是一个符号性的名称如 HEAD(代表当前检出分支最后一次的提交),除了这些简单的形式以外,你还可以附加一个指定的日期或时间作为参数,表示“这个时间的引用”。

这个功能在某些时候会变得十分有用。当你处理最新出现的 bug,自言自语道:“这个功能昨天还是好好的,到底又改了些什么”,不用盯着满屏的 git log 的输出试图弄清楚什么时候更改了提交,你只需运行 git diff HEAD@{yesterday},看看从昨天以来的所有修改。这也适用于更长的时间段(例如 git diff HEAD@{'2 months ago'}),以及一个确切的日期(例如 git diff HEAD@{'2010-01-01 12:00:00'})。

你也可以将这些基于日期的修订参数与使用修订参数的任何 Git 子命令一起使用。在 gitrevisions 手册页中有关于具体使用哪种格式的详细信息。

12、 全知的 reflog

你是不是试过在变基时干掉过某次提交,然后发现你需要保留那个提交中一些东西?你可能觉得这些信息已经永远找不回来了,只能重新创建。但是如果你在本地工作副本中提交了,提交就会被添加到引用日志(reflog)中 ,你仍然可以访问到。

运行 git reflog 将在本地工作副本中显示当前分支的所有活动的列表,并为你提供每个提交的 SHA1 值。一旦发现你变基时放弃的那个提交,你可以运行 git checkout <SHA1> 跳转到该提交,复制任何你需要的信息,然后再运行 git checkout HEAD 返回到分支最近的提交去。

13、 自己清理

哎呦! 事实证明,我的基本数学技能不如我的 Git 技能。 Git 最初是在 2005 年发布的,这意味着它今年会变成 13 岁,而不是 12 岁(LCTT 译注:本文原来是以 12 岁生日为题的)。为了弥补这个错误,这里有可以让我们变成十三岁的第 13 条技巧。

如果你使用基于分支的工作流,随着在一个长期项目上的工作,除非你在每个分支合并时清理干净,否则你最终会得到一大堆分支。这使得你难于找到想要的分支,分支的森林会让你无从找起。甚至更糟糕的是,如果你有大量活跃的分支,确定一个分支是否被合并(可以被安全删除)或仍然没有被合并而应该留下会非常繁琐。幸运的是,Git 可以帮到你:只需要运行 git branch --merged 就可以得到已经被合并到你的当前分支的分支列表,或者 git branch --no-merged 找出被合并到其它分支的分支。默认情况下这会列出你本地工作副本的分支,但是如果你在命令行包括 --remote-r 参数,它也会列出仅存于远程仓库的已合并分支。

重要提示:如果你计划使用 git branch --merged 的输出来清理那些已合并的分支,你要小心它的输出也包括了当前分支(毕竟,这个当前的分支就被合并到当前分支!)。确保你在任何销毁动作之前排除了该分支(如果你忘记了,参见第 12 条技巧来学习 reflog 怎样帮你把分支找回来,希望有用……)。

以上是全部内容

希望这些技巧中至少有一个能够教给你一些关于 Git 的新东西,Git 是一个有 13 年历史的项目,并且在持续创新和增加新功能中。你最喜欢的 Git 技巧是什么?


via: https://opensource.com/article/18/4/git-tips

作者:John SJ Anderson 选题:lujun9972 译者:MjSeven 校对:wxy

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

在读这篇文章之前,确保你对 Python 全局、局部和非局部变量 有一定的基础。

global 关键字简介

在 Python 中,global 关键字允许你修改当前范围之外的变量。它用于创建全局变量并在本地上下文中更改变量。

global 关键字的规则

在 Python 中,有关 global 关键字基本规则如下:

  • 当我们在一个函数中创建一个变量时,默认情况下它是本地变量。
  • 当我们在一个函数之外定义一个变量时,默认情况下它是全局变量。你不必使用 global 关键字。
  • 我们使用 global 关键字在一个函数中来读写全局变量。
  • 在一个函数外使用 global 关键字没有效果。

使用 global 关键字(含示例)

我们来举个例子。

示例 1:从函数内部访问全局变量

c = 1 # 全局变量
def add():
    print(c)

add()

运行程序,输出为:

1

但是我们可能有一些场景需要从函数内部修改全局变量。

示例 2:在函数内部修改全局变量

c = 1 # 全局变量
def add():
    c = c + 2 # 将 c 增加 2
    print(c)
add()

运行程序,输出显示错误:

UnboundLocalError: local variable 'c' referenced before assignment

这是因为在函数中,我们只能访问全局变量但是不能修改它。

解决的办法是使用 global 关键字。

示例 3:使用 global 在函数中改变全局变量

c = 0 # global variable

def add():
    global c
    c = c + 2 # 将 c 增加 2
    print("Inside add():", c)

add()
print("In main:", c)

运行程序,输出为:

Inside add(): 2
In main: 2

在上面的程序中,我们在 add() 函数中定义了 c 将其作为全局关键字。

然后,我们给变量 c 增加 2,即 c = c + 2。之后,我们调用了 add() 函数。最后,打印全局变量 c

正如我们所看到的,在函数外的全局变量也发生了变化,c = 2

Python 模块中的全局变量

在 Python 中,我们创建一个单独的模块 config.py 来保存全局变量并在同一个程序中的 Python 模块之间共享信息。

以下是如何通过 Python 模块共享全局变量。

示例 4:在Python模块中共享全局变量

创建 config.py 文件来存储全局变量

a = 0
b = "empty"

创建 update.py 文件来改变全局变量

import config

config.a = 10
config.b = "alphabet"

创建 main.py 文件来测试其值的变化

import config
import update

print(config.a)
print(config.b)

运行 main.py,输出为:

10
alphabet

在上面,我们创建了三个文件: config.py, update.pymain.py

config.py 模块中保存了全局变量 ab。在 update.py 文件中,我们导入了 config.py 模块并改变了 ab 的值。同样,在 main.py 文件,我们导入了 config.pyupdate.py 模块。最后,我们打印并测试全局变量的值,无论它们是否被改变。

在嵌套函数中的全局变量

以下是如何在嵌套函数中使用全局变量。

示例 5:在嵌套函数中使用全局变量

def foo():
    x = 20
    def bar():
         global x
         x = 25

    print("Before calling bar: ", x)
    print("Calling bar now")
    bar()
    print("After calling bar: ", x)

foo()
print("x in main : ", x)

输出为:

Before calling bar: 20
Calling bar now
After calling bar: 20
x in main : 25

在上面的程序中,我们在一个嵌套函数 bar() 中声明了全局变量。在 foo() 函数中, 变量 x 没有全局关键字的作用。

调用 bar() 之前和之后, 变量 x 取本地变量的值,即 x = 20。在 foo() 函数之外,变量 x 会取在函数 bar() 中的值,即 x = 25。这是因为在 bar() 中,我们对 x 使用 global 关键字创建了一个全局变量(本地范围)。

如果我们在 bar() 函数内进行了任何修改,那么这些修改就会出现在本地范围之外,即 foo()


via: https://www.programiz.com/python-programming/global-keyword

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

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

概览

sudo 表示 “superuser do”。 它允许已验证的用户以其他用户的身份来运行命令。其他用户可以是普通用户或者超级用户。然而,大部分时候我们用它来以提升的权限来运行命令。

sudo 命令与安全策略配合使用,默认安全策略是 sudoers,可以通过文件 /etc/sudoers 来配置。其安全策略具有高度可拓展性。人们可以开发和分发他们自己的安全策略作为插件。

与 su 的区别

在 GNU/Linux 中,有两种方式可以用提升的权限来运行命令:

  • 使用 su 命令
  • 使用 sudo 命令

su 表示 “switch user”。使用 su,我们可以切换到 root 用户并且执行命令。但是这种方式存在一些缺点:

  • 我们需要与他人共享 root 的密码。
  • 因为 root 用户为超级用户,我们不能授予受控的访问权限。
  • 我们无法审查用户在做什么。

sudo 以独特的方式解决了这些问题。

  1. 首先,我们不需要妥协来分享 root 用户的密码。普通用户使用他们自己的密码就可以用提升的权限来执行命令。
  2. 我们可以控制 sudo 用户的访问,这意味着我们可以限制用户只执行某些命令。
  3. 除此之外,sudo 用户的所有活动都会被记录下来,因此我们可以随时审查进行了哪些操作。在基于 Debian 的 GNU/Linux 中,所有活动都记录在 /var/log/auth.log 文件中。

本教程后面的部分阐述了这些要点。

实际动手操作 sudo

现在,我们对 sudo 有了大致的了解。让我们实际动手操作吧。为了演示,我使用 Ubuntu。但是,其它发行版本的操作应该是相同的。

允许 sudo 权限

让我们添加普通用户为 sudo 用户吧。在我的情形中,用户名为 linuxtechi

1) 按如下所示编辑 /etc/sudoers 文件:

$ sudo visudo

2) 添加以下行来允许用户 linuxtechi 有 sudo 权限:

linuxtechi ALL=(ALL) ALL

上述命令中:

  • linuxtechi 表示用户名
  • 第一个 ALL 指示允许从任何终端、机器访问 sudo
  • 第二个 (ALL) 指示 sudo 命令被允许以任何用户身份执行
  • 第三个 ALL 表示所有命令都可以作为 root 执行

以提升的权限执行命令

要用提升的权限执行命令,只需要在命令前加上 sudo,如下所示:

$ sudo cat /etc/passwd

当你执行这个命令时,它会询问 linuxtechi 的密码,而不是 root 用户的密码。

以其他用户执行命令

除此之外,我们可以使用 sudo 以另一个用户身份执行命令。例如,在下面的命令中,用户 linuxtechi 以用户 devesh 的身份执行命令:

$ sudo -u devesh whoami
[sudo] password for linuxtechi:
devesh

内置命令行为

sudo 的一个限制是 —— 它无法使用 Shell 的内置命令。例如, history 记录是内置命令,如果你试图用 sudo 执行这个命令,那么会提示如下的未找到命令的错误:

$ sudo history
[sudo] password for linuxtechi:
sudo: history: command not found

访问 root shell

为了克服上述问题,我们可以访问 root shell,并在那里执行任何命令,包括 Shell 的内置命令。

要访问 root shell, 执行下面的命令:

$ sudo bash

执行完这个命令后——您将观察到提示符变为井号(#)。

技巧

这节我们将讨论一些有用的技巧,这将有助于提高生产力。大多数命令可用于完成日常任务。

以 sudo 用户执行之前的命令

让我们假设你想用提升的权限执行之前的命令,那么下面的技巧将会很有用:

$ sudo !4

上面的命令将使用提升的权限执行历史记录中的第 4 条命令。

在 Vim 里面使用 sudo 命令

很多时候,我们编辑系统的配置文件时,在保存时才意识到我们需要 root 访问权限来执行此操作。因为这个可能让我们丢失我们对文件的改动。没有必要惊慌,我们可以在 Vim 中使用下面的命令来解决这种情况:

:w !sudo tee %

上述命令中:

  • 冒号 (:) 表明我们处于 Vim 的退出模式
  • 感叹号 (!) 表明我们正在运行 shell 命令
  • sudotee 都是 shell 命令
  • 百分号 (%) 表明从当前行开始的所有行

使用 sudo 执行多个命令

至今我们用 sudo 只执行了单个命令,但我们可以用它执行多个命令。只需要用分号 (;) 隔开命令,如下所示:

$ sudo -- bash -c 'pwd; hostname; whoami'

上述命令中

  • 双连字符 (--) 停止命令行切换
  • bash 表示要用于执行命令的 shell 名称
  • -c 选项后面跟着要执行的命令

无密码运行 sudo 命令

当第一次执行 sudo 命令时,它会提示输入密码,默认情形下密码被缓存 15 分钟。但是,我们可以避免这个操作,并使用 NOPASSWD 关键字禁用密码认证,如下所示:

linuxtechi ALL=(ALL) NOPASSWD: ALL

限制用户执行某些命令

为了提供受控访问,我们可以限制 sudo 用户只执行某些命令。例如,下面的行只允许执行 echols 命令 。

linuxtechi ALL=(ALL) NOPASSWD: /bin/echo /bin/ls

深入了解 sudo

让我们进一步深入了解 sudo 命令。

$ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 145040 Jun 13  2017 /usr/bin/sudo

如果仔细观察文件权限,则发现 sudo 上启用了 setuid 位。当任何用户运行这个二进制文件时,它将以拥有该文件的用户权限运行。在所示情形下,它是 root 用户。

为了演示这一点,我们可以使用 id 命令,如下所示:

$ id
uid=1002(linuxtechi) gid=1002(linuxtechi) groups=1002(linuxtechi)

当我们不使用 sudo 执行 id 命令时,将显示用户 linuxtechi 的 id。

$ sudo id
uid=0(root) gid=0(root) groups=0(root)

但是,如果我们使用 sudo 执行 id 命令时,则会显示 root 用户的 id。

结论

从这篇文章可以看出 —— sudo 为普通用户提供了更多受控访问。使用这些技术,多用户可以用安全的方式与 GNU/Linux 进行交互。


via: https://www.linuxtechi.com/quick-tips-sudo-command-linux-systems/

作者:Pradeep Kumar 译者:szcf-weiya 校对:wxy

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

学习如何在 Linux 终端使用命令行工具 speedtest 测试网速,或者仅用一条 python 命令立刻获得网速的测试结果。

在Linux终端测试网速

我们都会在连接到一个新的网络或者 WIFI 的时候去测试网络带宽。 为什么不用我们自己的服务器!下面将会教你如何在 Linux 终端测试网速。

我们多数都会使用 Ookla 的 Speedtest 来测试网速。 这在桌面上是很简单的操作,访问他们的网站点击“Go”浏览即可。它将使用最近的服务器来扫描你的本地主机来测试网速。 如果你使用的是移动设备,他们有对应的移动端 APP。但如果你使用的是只有命令行终端,界面的则会有些不同。下面让我们一起看看如何在Linux的终端来测试网速。

如果你只是想偶尔的做一次网速测试而不想去下载测试工具,那么请往下看如何使用命令完成测试。

第一步:下载网速测试命令行工具。

首先,你需要从 GitHub 上下载 speedtest 命令行工具。现在,它也被包含在许多其它的 Linux 仓库中,如果已经在你的库中,你可以直接在你的 Linux 发行版上进行安装

让我们继续下载和安装过程,安装的 git 包取决于你的 Linux 发行版。然后按照下面的方法来克隆 Github speedtest 存储库

[root@kerneltalks ~]# git clone https://github.com/sivel/speedtest-cli.git
Cloning into 'speedtest-cli'...
remote: Counting objects: 913, done.
remote: Total 913 (delta 0), reused 0 (delta 0), pack-reused 913
Receiving objects: 100% (913/913), 251.31 KiB | 143.00 KiB/s, done.
Resolving deltas: 100% (518/518), done.

它将会被克隆到你当前的工作目录,新的名为 speedtest-cli 的目录将会被创建,你将在新的目录下看到如下的文件。

[root@kerneltalks ~]# cd speedtest-cli
[root@kerneltalks speedtest-cli]# ll
total 96
-rw-r--r--. 1 root root  1671 Oct  7 16:55 CONTRIBUTING.md
-rw-r--r--. 1 root root 11358 Oct  7 16:55 LICENSE
-rw-r--r--. 1 root root    35 Oct  7 16:55 MANIFEST.in
-rw-r--r--. 1 root root  5215 Oct  7 16:55 README.rst
-rw-r--r--. 1 root root    20 Oct  7 16:55 setup.cfg
-rw-r--r--. 1 root root  3196 Oct  7 16:55 setup.py
-rw-r--r--. 1 root root  2385 Oct  7 16:55 speedtest-cli.1
-rw-r--r--. 1 root root  1200 Oct  7 16:55 speedtest_cli.py
-rwxr-xr-x. 1 root root 47228 Oct  7 16:55 speedtest.py
-rw-r--r--. 1 root root   333 Oct  7 16:55 tox.ini

名为 speedtest.py 的 Python 脚本文件就是用来测试网速的。

你可以将这个脚本链接到 /usr/bin 下,以便这台机器上的所有用户都能使用。或者你可以为这个脚本创建一个命令别名,这样就能让所有用户很容易使用它。

运行 Python 脚本

现在,直接运行这个脚本,不需要添加任何参数,它将会搜寻最近的服务器来测试你的网速。

[root@kerneltalks speedtest-cli]# python speedtest.py
Retrieving speedtest.net configuration...
Testing from Amazon (35.154.184.126)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by Spectra (Mumbai) [1.15 km]: 8.174 ms
Testing download speed................................................................................
Download: 548.13 Mbit/s
Testing upload speed................................................................................................
Upload: 323.95 Mbit/s

Oh! 不要被这个网速惊讶道。我在 AWE EX2 的服务器上。那是亚马逊数据中心的网速!

这个脚本可以添加有不同的选项。

下面的几个选项对这个脚本可能会很有用处:

要搜寻你附近的网路测试服务器,使用 --listgrep 加上地名来列出所有附近的服务器。

[root@kerneltalks speedtest-cli]#  python speedtest.py --list | grep -i mumbai
 2827) Bharti Airtel Ltd (Mumbai, India) [1.15 km]
 8978) Spectra (Mumbai, India) [1.15 km]
 4310) Hathway Cable and Datacom Ltd (Mumbai, India) [1.15 km]
 3315) Joister Broadband (Mumbai, India) [1.15 km]
 1718) Vodafone India (Mumbai, India) [1.15 km]
 6454) YOU Broadband India Pvt Ltd. (Mumbai, India) [1.15 km]
 9764) Railtel Corporation of india Ltd (Mumbai, India) [1.15 km]
 9584) Sheng Li Telecom (Mumbai, India) [1.15 km]
 7605) Idea Cellular Ltd. (Mumbai, India) [1.15 km]
 8122) Sify Technologies Ltd (Mumbai, India) [1.15 km]
 9049) I-ON (Mumbai, India) [1.15 km]
 6403) YOU Broadband India Pvt Ltd., Mumbai (Mumbai, India) [1.15 km]

然后你就能从搜寻结果中看到,第一列是服务器识别号,紧接着是公司的名称和所在地,最后是离你的距离。

如果要使用指定的服务器来测试网速,后面跟上 --server 加上服务器的识别号。

[root@kerneltalks speedtest-cli]# python speedtest.py --server 2827
Retrieving speedtest.net configuration...
Testing from Amazon (35.154.184.126)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by Bharti Airtel Ltd (Mumbai) [1.15 km]: 13.234 ms
Testing download speed................................................................................
Download: 93.47 Mbit/s
Testing upload speed................................................................................................
Upload: 69.25 Mbit/s

如果想得到你的测试结果的分享链接,使用 --share,你将会得到测试结果的链接。

[root@kerneltalks speedtest-cli]# python speedtest.py --share
Retrieving speedtest.net configuration...
Testing from Amazon (35.154.184.126)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by Spectra (Mumbai) [1.15 km]: 7.471 ms
Testing download speed................................................................................
Download: 621.00 Mbit/s
Testing upload speed................................................................................................
Upload: 367.37 Mbit/s
Share results: http://www.speedtest.net/result/6687428141.png

输出中的最后一行就是你的测试结果的链接。下载下来的图片内容如下 :

这就是全部的过程!如果你不想了解这些技术细节,你也可以使用如下的一行命令迅速测出你的网速。

要想在终端使用一条命令测试网速。

我们将使用 curl 工具来在线抓取上面使用的 Python 脚本然后直接用 Python 执行脚本。

[root@kerneltalks ~]# curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python -

上面的脚本将会运行脚本输出结果到屏幕上。

[root@kerneltalks speedtest-cli]# curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python -
Retrieving speedtest.net configuration...
Testing from Amazon (35.154.184.126)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by Spectra (Mumbai) [1.15 km]: 12.599 ms
Testing download speed................................................................................
Download: 670.88 Mbit/s
Testing upload speed................................................................................................
Upload: 355.84 Mbit/s

这是在 RHEL 7 上执行的结果,在 Ubuntu、Debian、Fedora 或者 CentOS 上一样可以执行。


via: https://kerneltalks.com/tips-tricks/how-to-test-internet-speed-in-linux-terminal/

作者:Shrikant Lavhate 译者:FelixYFZ 校对:wxy

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

是否你刚刚接触 Vi 还是想进阶,这些技巧可以很快让你成为高级用户。

Vi 编辑器是 Unix 和像 Linux 这样的类 Unix 系统中 Linux 最流行的编辑器之一。无论您是 vi 新手还是想进阶,这里有 11 个技巧可以增强你使用的方式。

编辑

编辑长文本时可能很难受,特别是编辑其中某一行时,需要移动许久才能到这行。这有个很快的方法:

1、 :set number 这个命令可是在编辑器左边显示行号。

您可以在命令行中输入 vi +26 samp.txt 命令直接打开文件到达 26 行,在 vi 编辑器中也可以输入 :26 跳转到 26 行。

快速导航

2、 i 将工作方式从“命令模式”更改为“输入模式”,并在当前光标位置开始插入内容。

3、 a 除了是光标之后开始插入内容,与上面的效果是一样的。

4、 o 在光标的下一行位置开始插入内容。

删除

如果您发现错误或错别字,能快速的修正是很重要的。好在 Vi 都事先想好了。

了解 Vi 的删除功能,保证你不会意外按下某个键并永久删除一行或多段内容,这点至关重要。

5、 x 删除当前光标的字符。

6、 dd 删除当前行 (是的,整行内容!)

下面看可怕的部分:30dd 从当前行开始删除以下 30 行!使用此命令请慎重。

搜索

您可以在“命令模式”搜索关键字,而不用在大量文本内容中手动导航查找特定的单词或内容。

7、 :/<keyword> 搜索 < > 中的单词并将光标移动到第一个匹配项。

8、 导航到该单词的下一个匹配项,请输入 n 并继续按下, 直到找到您要找的内容。

例如,在这个图像中我要搜索包含 ssh 的内容, Vi 光标就会突出第一个结果的开始位置。

按下 n 之后, Vi 光标就会突出下一个匹配项。

保存并退出

开发人员 (或其他人) 可能会发现这个命令很有用。

9、 :x 保存您的工作并退出 Vi 。

10、 如果你想节省哪怕是纳秒,那么这有个更快的回到终端的方法。不用在键盘上按 Shift+: ,而是按下 Shift+q (或者大写字母 Q ) 来进入 Ex 模式 。但是如果你只是想按下 x 来保存退出,那就没有什么区别(如上所示)。

替换

如果您想将文中的某个单词全部替换为一个单词,这有个很巧妙的招式。例如,如果您想在一个大文件中将 “desktop” 替换为 “laptop” ,那么单调的搜索每个出现的 “desktop” 将其删掉,然后再输入 “laotop” ,是很浪费时间的。

11、 :%s/desktop/laptop/g 这个命令将在整个文件中的 “desktop” 用 “laptop” 替换,他就像 Linux 的 sed 命令一样。

这个例子中我用 “user” 替换了 “root” :

这些技巧应该能帮组任何想开始学 Vi 的人。我有遗漏其他巧妙的提示吗?请在评论中分享他们。


via: https://opensource.com/article/18/1/top-11-vi-tips-and-tricks

作者:Archit Modi 译者:MZqk 校对:wxy

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

Linux 内核正在盯着你,当它检测到系统上运行的某些东西违反了正常内核行为时,它会关闭系统并发出一个“oops”!

如果你检查你的 Linux 系统上运行的进程,你可能会对一个叫做 “kerneloops” 的进程感到好奇。提示一下,它是 “kernel oops”,而不是 “kerne loops”。

坦率地说,“oops” 是 Linux 内核的一部分出现了偏差行为。你有做错了什么吗?可能没有。但有一些不对劲。而那个做了错事的进程可能已经被 CPU 结束。最糟糕的是,内核可能会报错并突然关闭系统。

请注意,“oops” 不是首字母缩略词。它不代表像“ 面向对象的编程和系统 object-oriented programming and systems ” 或“ 超出程序规范 out of procedural specs ” 之类的东西。它实际上就是“哎呀” (oops),就像你刚掉下一杯酒或踩在你的猫身上。哎呀! “oops” 的复数是 “oopses”。

oops 意味着系统上运行的某些东西违反了内核有关正确行为的规则。也许代码尝试采取不允许的代码路径或使用无效指针。不管它是什么,内核 —— 总是在监测进程的错误行为 —— 很可能会阻止特定进程,并将它做了什么的消息写入控制台、 /var/log/dmesg/var/log/kern.log 中。

oops 可能是由内核本身引起的,也可能是某些进程试图让内核违反在系统上能做的事以及它们被允许做的事。

oops 将生成一个 崩溃签名 crash signature ,这可以帮助内核开发人员找出错误并提高代码质量。

系统上运行的 kerneloops 进程可能如下所示:

kernoops 881 1 0 Feb11 ? 00:00:01 /usr/sbin/kerneloops

你可能会注意到该进程不是由 root 运行的,而是由名为 “kernoops” 的用户运行的,并且它的运行时间极少。实际上,分配给这个特定用户的唯一任务是运行 kerneloops。

$ sudo grep kernoops /etc/passwd
kernoops:x:113:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false

如果你的 Linux 系统不带有 kerneloops(比如 Debian),你可以考虑添加它。查看这个 Debian 页面了解更多信息。

什么时候应该关注 oops?

一般 oops 没什么大不了的。它在一定程度上取决于特定进程所扮演的角色。它也取决于 oops 的类别。

有些 oops 很严重,会导致 系统恐慌 system panic 。从技术上讲,系统恐慌是 oops 的一个子集(即更严重的 oops)。当内核检测到的问题足够严重以至于内核认为它(内核)必须立即停止运行以防止数据丢失或对系统造成其他损害时会出现。因此,系统需要暂停并重新启动,以防止任何不一致导致不可用或不可靠。所以系统恐慌实际上是为了保护自己免受不可挽回的损害。

总之,所有的内核恐慌都是 oops,但并不是所有的 oops 都是内核恐慌。

/var/log/kern.log 和相关的轮转日志(/var/log/kern.log.1/var/log/kern.log.2 等)包含由内核生成并由 syslog 处理的日志。

kerneloops 程序收集并默认将错误信息提交到 http://oops.kernel.org/,在那里它会被分析并呈现给内核开发者。此进程的配置详细信息在 /etc/kerneloops.conf 文件中指定。你可以使用下面的命令轻松查看设置:

$ sudo cat /etc/kerneloops.conf | grep -v ^# | grep -v ^$
[sudo] password for shs:
allow-submit = ask
allow-pass-on = yes
submit-url = http://oops.kernel.org/submitoops.php
log-file = /var/log/kern.log
submit-pipe = /usr/share/apport/kernel_oops

在上面的(默认)设置中,内核问题可以被提交,但要求用户获得许可。如果设置为 allow-submit = always,则不会询问用户。

调试内核问题是使用 Linux 系统的更高级技巧之一。幸运的是,大多数 Linux 用户很少或从没有经历过 oops 或内核恐慌。不过,知道 kerneloops 这样的进程在系统中执行什么操作,了解可能会报告什么以及系统何时遇到严重的内核冲突也是很好的。


via: https://www.networkworld.com/article/3254778/linux/what-is-a-linux-oops.html

作者:Sandra Henry-Stocker 译者:geekpi 校对:wxy

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