2019年8月

Gamemmode improve gaming performance on Linux

去问一些 Linux 用户为什么他们仍然坚持 Windows 双启动,他们的答案可能是 - “游戏!”。这是真的!幸运的是,开源游戏平台如 Lutris 和专有游戏平台 Steam 已经为 Linux 平台带来了许多游戏,并且近几年来显著改善了 Linux 的游戏体验。今天,我偶然发现了另一款名为 GameMode 的 Linux 游戏相关开源工具,它能让用户提高 Linux 上的游戏性能。

GameMode 基本上是一组守护进程/库,它可以按需优化 Linux 系统的游戏性能。我以为 GameMode 是一个杀死在后台运行的对资源消耗大进程的工具。但它并不是。它实际上只是让 CPU 在用户玩游戏时自动运行在高性能模式下并帮助 Linux 用户从游戏中获得最佳性能。

在玩游戏时,GameMode 通过对宿主机请求临时应用一组优化来显著提升游戏性能。目前,它支持下面这些优化:

  • CPU 调控器,
  • I/O 优先级,
  • 进程 nice 值
  • 内核调度器(SCHED\_ISO),
  • 禁止屏幕保护,
  • GPU 高性能模式(NVIDIA 和 AMD),GPU 超频(NVIDIA),
  • 自定义脚本。

GameMode 是由世界领先的游戏发行商 Feral Interactive 开发的自由开源的系统工具。

安装 GameMode

GameMode 适用于许多 Linux 发行版。

在 Arch Linux 及其变体上,你可以使用任何 AUR 助手程序,如 YayAUR 安装它。

$ yay -S gamemode

在 Debian、Ubuntu、Linux Mint 和其他基于 Deb 的系统上:

$ sudo apt install gamemode

如果 GameMode 不适用于你的系统,你可以按照它的 Github 页面中开发章节下的描述从源码手动编译和安装它。

激活 GameMode 支持以改善 Linux 上的游戏性能

以下是集成支持了 GameMode 的游戏列表,因此我们无需进行任何其他配置即可激活 GameMode 支持。

  • 古墓丽影:崛起
  • 全面战争传奇:不列颠尼亚王座
  • 全面战争:战锤 2
  • 尘埃 4
  • 全面战争:三国

只需运行这些游戏,就会自动启用 GameMode 支持。

这里还有将 GameMode 与 GNOME shell 集成的的扩展。它会在顶部指示 GameMode 何时处于活跃。

对于其他游戏,你可能需要手动请求 GameMode 支持,如下所示。

gamemoderun ./game

我不喜欢游戏,并且我已经很多年没玩游戏了。所以,我无法分享一些实际的基准测试。

但是,我在 Youtube 上找到了一个简短的视频教程,以便为 Lutris 游戏启用 GameMode 支持。对于那些想要第一次尝试 GameMode 的人来说,这是个不错的开始。

通过浏览视频中的评论,我可以说 GameMode 确实提高了 Linux 上的游戏性能。

对于更多细节,请参阅 GameMode 的 GitHub 仓库

相关阅读:

你用过 GameMode 吗?它真的有改善 Linux 上的游戏性能吗?请在下面的评论栏分享你的想法。


via: https://www.ostechnix.com/gamemode-a-tool-to-improve-gaming-performance-on-linux/

作者:sk 选题:lujun9972 译者:geekpi 校对:wxy

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

设计模式可以帮助消除冗余代码。学习如何利用 Java 使用单例模式、工厂模式和观察者模式。

如果你是一名正在致力于计算机科学或者相关学科的程序员或者学生,很快,你将会遇到一条术语 “ 软件设计模式 software design pattern ”。根据维基百科,“软件设计模式是在平常的软件设计工作中所遭遇的问题的一种通用的、可重复使用的解决方案”。我对该定义的理解是:当在从事于一个编码项目时,你经常会思考,“嗯,这里貌似是冗余代码,我觉得是否能改变这些代码使之更灵活和便于修改?”因此,你会开始考虑怎样分割那些保持不变的内容和需要经常改变的内容。

设计模式是一种通过分割那些保持不变的部分和经常变化的部分,让你的代码更容易修改的方法。

不出意外的话,每个从事编程项目的人都可能会有同样的思考。特别是那些工业级别的项目,在那里通常工作着数十甚至数百名开发者;协作过程表明必须有一些标准和规则来使代码更加优雅并适应变化。这就是为什么我们有了 面向对象编程(OOP)和 软件框架工具。设计模式有点类似于 OOP,但它通过将变化视为自然开发过程的一部分而进一步发展。基本上,设计模式利用了一些 OOP 的思想,比如抽象和接口,但是专注于改变的过程。

当你开始开发项目时,你经常会听到这样一个术语重构,它意味着通过改变代码使它变得更优雅和可复用;这就是设计模式耀眼的地方。当你处理现有代码时(无论是由其他人构建还是你自己过去构建的),了解设计模式可以帮助你以不同的方式看待事物,你将发现问题以及改进代码的方法。

有很多种设计模式,其中单例模式、工厂模式和观察者模式三种最受欢迎,在这篇文章中我将会一一介绍它们。

如何遵循本指南

无论你是一位有经验的编程工作者还是一名刚刚接触的新手,我想让这篇教程让每个人都很容易理解。设计模式概念并不容易理解,减少开始旅程时的学习曲线始终是首要任务。因此,除了这篇带有图表和代码片段的文章外,我还创建了一个 GitHub 仓库,你可以克隆仓库并在你的电脑上运行这些代码来实现这三种设计模式。你也可以观看我创建的 YouTube视频

必要条件

如果你只是想了解一般的设计模式思想,则无需克隆示例项目或安装任何工具。但是,如果要运行示例代码,你需要安装以下工具:

  • Java 开发套件(JDK):我强烈建议使用 OpenJDK
  • Apache Maven:这个简单的项目使用 Apache Maven 构建;好的是许多 IDE 自带了Maven。
  • 交互式开发编辑器(IDE):我使用 社区版 IntelliJ,但是你也可以使用 Eclipse IDE 或者其他你喜欢的 Java IDE。
  • Git:如果你想克隆这个工程,你需要 Git 客户端。

安装好 Git 后运行下列命令克隆这个工程:

git clone https://github.com/bryantson/OpensourceDotComDemos.git

然后在你喜欢的 IDE 中,你可以将 TopDesignPatterns 仓库中的代码作为 Apache Maven 项目导入。

我使用的是 Java,但你也可以使用支持抽象原则)的任何编程语言来实现设计模式。

单例模式:避免每次创建一个对象

单例模式 singleton pattern 是非常流行的设计模式,它的实现相对来说很简单,因为你只需要一个类。然而,许多开发人员争论单例设计模式的是否利大于弊,因为它缺乏明显的好处并且容易被滥用。很少有开发人员直接实现单例;相反,像 Spring Framework 和 Google Guice 等编程框架内置了单例设计模式的特性。

但是了解单例模式仍然有巨大的用处。单例模式确保一个类仅创建一次且提供了一个对它的全局访问点。

单例模式:确保仅创建一个实例且避免在同一个项目中创建多个实例。

下面这幅图展示了典型的类对象创建过程。当客户端请求创建一个对象时,构造函数会创建或者实例化一个对象并调用方法返回这个类给调用者。但是每次请求一个对象都会发生这样的情况:构造函数被调用,一个新的对象被创建并且它返回了一个独一无二的对象。我猜面向对象语言的创建者有每次都创建一个新对象的理由,但是单例过程的支持者说这是冗余的且浪费资源。

 title=

下面这幅图使用单例模式创建对象。这里,构造函数仅当对象首次通过调用预先设计好的 getInstance() 方法时才会被调用。这通常通过检查该值是否为 null 来完成,并且这个对象被作为私有变量保存在单例类的内部。下次 getInstance() 被调用时,这个类会返回第一次被创建的对象。而没有新的对象产生;它只是返回旧的那一个。

 title=

下面这段代码展示了创建单例模式最简单的方法:

package org.opensource.demo.singleton;

public class OpensourceSingleton {

    private static OpensourceSingleton uniqueInstance;

    private OpensourceSingleton() {
    }

    public static OpensourceSingleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new OpensourceSingleton();
        }
        return uniqueInstance;
    }

}

在调用方,这里展示了如何调用单例类来获取对象:

Opensource newObject = Opensource.getInstance();

这段代码很好的验证了单例模式的思想:

  1. getInstance() 被调用时,它通过检查 null 值来检查对象是否已经被创建。
  2. 如果值为 null,它会创建一个新对象并把它保存到私有域,返回这个对象给调用者。否则直接返回之前被创建的对象。

单例模式实现的主要问题是它忽略了并行进程。当多个进程使用线程同时访问资源时,这个问题就产生了。对于这种情况有对应的解决方案,它被称为双重检查锁,用于多线程安全,如下所示:

package org.opensource.demo.singleton;

public class ImprovedOpensourceSingleton {

    private volatile static ImprovedOpensourceSingleton uniqueInstance;

    private ImprovedOpensourceSingleton() {}

    public static ImprovedOpensourceSingleton getInstance() {
        if (uniqueInstance == null) {
            synchronized (ImprovedOpensourceSingleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new ImprovedOpensourceSingleton();
                }
            }
        }
        return uniqueInstance;
    }

}

再强调一下前面的观点,确保只有在你认为这是一个安全的选择时才直接实现你的单例模式。最好的方法是通过使用一个制作精良的编程框架来利用单例功能。

工厂模式:将对象创建委派给工厂类以隐藏创建逻辑

工厂模式 factory pattern 是另一种众所周知的设计模式,但是有一小点复杂。实现工厂模式的方法有很多,而下列的代码示例为最简单的实现方式。为了创建对象,工厂模式定义了一个接口,让它的子类去决定实例化哪一个类。

工厂模式:将对象创建委派给工厂类,因此它能隐藏创建逻辑。

下列的图片展示了最简单的工厂模式是如何实现的。

 title=

客户端请求工厂类创建类型为 x 的某个对象,而不是客户端直接调用对象创建。根据其类型,工厂模式决定要创建和返回的对象。

在下列代码示例中,OpensourceFactory 是工厂类实现,它从调用者那里获取类型并根据该输入值决定要创建和返回的对象:

package org.opensource.demo.factory;

public class OpensourceFactory {

    public OpensourceJVMServers getServerByVendor(String name) {
        if(name.equals("Apache")) {
            return new Tomcat();
        }
        else if(name.equals("Eclipse")) {
            return new Jetty();
        }
        else if (name.equals("RedHat")) {
            return new WildFly();
        }
        else {
            return null;
        }
    }
}

OpenSourceJVMServer 是一个 100% 的抽象类(即接口类),它指示要实现的是什么,而不是怎样实现:

package org.opensource.demo.factory;

public interface OpensourceJVMServers {
    public void startServer();
    public void stopServer();
    public String getName();
}

这是一个 OpensourceJVMServers 类的实现示例。当 RedHat 被作为类型传递给工厂类,WildFly 服务器将被创建:

package org.opensource.demo.factory;

public class WildFly implements OpensourceJVMServers {
    public void startServer() {
        System.out.println("Starting WildFly Server...");
    }

    public void stopServer() {
        System.out.println("Shutting Down WildFly Server...");
    }

    public String getName() {
        return "WildFly";
    }
}

观察者模式:订阅主题并获取相关更新的通知

最后是 观察者模式 observer pattern 。像单例模式那样,很少有专业的程序员直接实现观察者模式。但是,许多消息队列和数据服务实现都借用了观察者模式的概念。观察者模式在对象之间定义了一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都将被自动地通知和更新。

观察者模式:如果有更新,那么订阅了该话题/主题的客户端将被通知。

理解观察者模式的最简单方法是想象一个邮件列表,你可以在其中订阅任何主题,无论是开源、技术、名人、烹饪还是您感兴趣的任何其他内容。每个主题维护者一个它的订阅者列表,在观察者模式中它们相当于观察者。当某一个主题更新时,它所有的订阅者(观察者)都将被通知这次改变。并且订阅者总是能取消某一个主题的订阅。

如下图所示,客户端可以订阅不同的主题并添加观察者以获得最新信息的通知。因为观察者不断的监听着这个主题,这个观察者会通知客户端任何发生的改变。

 title=

让我们来看看观察者模式的代码示例,从主题/话题类开始:

package org.opensource.demo.observer;

public interface Topic {

    public void addObserver(Observer observer);
    public void deleteObserver(Observer observer);
    public void notifyObservers();
}

这段代码描述了一个为不同的主题去实现已定义方法的接口。注意一个观察者如何被添加、移除和通知的。

这是一个主题的实现示例:

package org.opensource.demo.observer;

import java.util.List;
import java.util.ArrayList;

public class Conference implements Topic {
    private List<Observer> listObservers;
    private int totalAttendees;
    private int totalSpeakers;
    private String nameEvent;

    public Conference() {
        listObservers = new ArrayList<Observer>();
    }

    public void addObserver(Observer observer) {
        listObservers.add(observer);
    }

    public void deleteObserver(Observer observer) {
        int i = listObservers.indexOf(observer);
        if (i >= 0) {
            listObservers.remove(i);
        }
    }

    public void notifyObservers() {
        for (int i=0, nObservers = listObservers.size(); i < nObservers; ++ i) {
            Observer observer = listObservers.get(i);
            observer.update(totalAttendees,totalSpeakers,nameEvent);
        }
    }

    public void setConferenceDetails(int totalAttendees, int totalSpeakers, String nameEvent) {
        this.totalAttendees = totalAttendees;
        this.totalSpeakers = totalSpeakers;
        this.nameEvent = nameEvent;
        notifyObservers();
    }
}

这段代码定义了一个特定主题的实现。当发生改变时,这个实现调用它自己的方法。注意这将获取观察者的数量,它以列表方式存储,并且可以通知和维护观察者。

这是一个观察者类:

package org.opensource.demo.observer;

public interface Observer {
    public void update(int totalAttendees, int totalSpeakers, String nameEvent);
}

这个类定义了一个接口,不同的观察者可以实现该接口以执行特定的操作。

例如,实现了该接口的观察者可以在会议上打印出与会者和发言人的数量:

package org.opensource.demo.observer;

public class MonitorConferenceAttendees implements Observer {
    private int totalAttendees;
    private int totalSpeakers;
    private String nameEvent;
    private Topic topic;

    public MonitorConferenceAttendees(Topic topic) {
        this.topic = topic;
        topic.addObserver(this);
    }

    public void update(int totalAttendees, int totalSpeakers, String nameEvent) {
        this.totalAttendees = totalAttendees;
        this.totalSpeakers = totalSpeakers;
        this.nameEvent = nameEvent;
        printConferenceInfo();
    }

    public void printConferenceInfo() {
        System.out.println(this.nameEvent + " has " + totalSpeakers + " speakers and " + totalAttendees + " attendees");
    }
}

接下来

现在你已经阅读了这篇对于设计模式的介绍引导,你还可以去寻求了解其他设计模式,例如外观模式,模版模式和装饰器模式。也有一些并发和分布式系统的设计模式如断路器模式和锚定模式。

可是,我相信最好的磨砺你的技能的方式首先是通过在你的业余项目或者练习中实现这些设计模式。你甚至可以开始考虑如何在实际项目中应用这些设计模式。接下来,我强烈建议你查看 OOP 的 SOLID 原则。之后,你就准备好了解其他设计模式。


via: https://opensource.com/article/19/7/understanding-software-design-patterns

作者:Bryant Son 选题:lujun9972 译者:arrowfeng 校对:wxy

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

微软表示,默认密码、未打补丁的设备,物联网设备库存不足是导致俄罗斯的 STRONTIUM 黑客组织发起针对公司的攻击的原因。

在微软安全响应中心周一发布的博客文章中,该公司称,STRONTIUM 黑客组织对未披露名字的微软客户进行了基于 IoT 的攻击,安全研究人员相信 STRONTIUM 黑客组织和俄罗斯 GRU 军事情报机构有密切的关系。

微软在博客中说,它在 4 月份发现的攻击针对三种特定的物联网设备:一部 VoIP 电话、一部视频解码器和一台打印机(该公司拒绝说明品牌),并将它们用于获得对不特定的公司网络的访问权限。其中两个设备遭到入侵是因为没有更改过制造商的默认密码,而另一个设备则是因为没有应用最新的安全补丁。

以这种方式受到攻击的设备成为了安全的网络的后门,允许攻击者自由扫描这些网络以获得进一步的漏洞,并访问其他系统获取更多的信息。攻击者也被发现其在调查受攻击网络上的管理组,试图获得更多访问权限,以及分析本地子网流量以获取其他数据。

STRONTIUM,也被称为 Fancy Bear、Pawn Storm、Sofacy 和 APT28,被认为是代表俄罗斯政府进行的一系列恶意网络活动的幕后黑手,其中包括 2016 年对民主党全国委员会的攻击,对世界反兴奋剂机构的攻击,针对记者调查马来西亚航空公司 17 号航班在乌克兰上空被击落的情况,向美国军人的妻子发送捏造的死亡威胁等等。

根据 2018 年 7 月特别顾问罗伯特·穆勒办公室发布的起诉书,STRONTIUM 袭击的指挥者是一群俄罗斯军官,所有这些人都被 FBI 通缉与这些罪行有关。

微软通知客户发现其遭到了民族国家的攻击,并在过去 12 个月内发送了大约 1,400 条与 STRONTIUM 相关的通知。微软表示,其中大多数(五分之四)是对政府、军队、国防、IT、医药、教育和工程领域的组织的攻击,其余的则是非政府组织、智囊团和其他“政治附属组织”。

根据微软团队的说法,漏洞的核心是机构缺乏对其网络上运行的所有设备的充分认识。另外,他们建议对在企业环境中运行的所有 IoT 设备进行编目,为每个设备实施自定义安全策略,在可行的情况下在各自独立的网络上屏蔽物联网设备,并对物联网组件执行定期补丁和配置审核。


via: https://www.networkworld.com/article/3430356/microsoft-finds-russia-backed-attacks-that-exploit-iot-devices.html

作者:Jon Gold 选题:lujun9972 译者:wxy 校对:wxy

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

COPR 是个人软件仓库集合,它不在 Fedora 中。这是因为某些软件不符合轻松打包的标准;或者它可能不符合其他 Fedora 标准,尽管它是自由而开源的。COPR 可以在 Fedora 套件之外提供这些项目。COPR 中的软件不受 Fedora 基础设施的支持,或者是由项目自己背书的。但是,这是一种尝试新的或实验性的软件的一种巧妙的方式。

这是 COPR 中一组新的有趣项目。

Duc

duc 是磁盘使用率检查和可视化工具的集合。Duc 使用索引数据库来保存系统上文件的大小。索引完成后,你可以通过命令行界面或 GUI 快速查看磁盘使用情况。

安装说明

仓库目前为 EPEL 7、Fedora 29 和 30 提供 duc。要安装 duc,请使用以下命令:

sudo dnf copr enable terrywang/duc
sudo dnf install duc

MuseScore

MuseScore 是一个处理音乐符号的软件。使用 MuseScore,你可以使用鼠标、虚拟键盘或 MIDI 控制器创建乐谱。然后,MuseScore 可以播放创建的音乐或将其导出为 PDF、MIDI 或 MusicXML。此外,它还有一个由 MuseScore 用户创建的含有大量乐谱的数据库。

安装说明

仓库目前为 Fedora 29 和 30 提供 MuseScore。要安装 MuseScore,请使用以下命令:

sudo dnf copr enable jjames/MuseScore
sudo dnf install musescore

动态墙纸编辑器

动态墙纸编辑器 是一个可在 GNOME 中创建和编辑随时间变化的壁纸集合的工具。这可以使用 XML 文件来完成,但是,动态墙纸编辑器通过其图形界面使其变得简单,你可以在其中简单地添加图片、排列图片并设置每张图片的持续时间以及它们之间的过渡。

安装说明

仓库目前为 Fedora 30 和 Rawhide 提供动态墙纸编辑器。要安装它,请使用以下命令:

sudo dnf copr enable atim/dynamic-wallpaper-editor
sudo dnf install dynamic-wallpaper-editor

Manuskript

Manuskript 是一个给作者的工具,旨在让创建大型写作项目更容易。它既可以作为编写文本的编辑器,也可以作为组织故事本身、故事人物和单个情节的注释的工具。

安装说明

仓库目前为 Fedora 29、30 和 Rawhide 提供 Manuskript。要安装 Manuskript,请使用以下命令:

sudo dnf copr enable notsag/manuskript
sudo dnf install manuskript

via: https://fedoramagazine.org/4-cool-new-projects-to-try-in-copr-for-august-2019/

作者:Dominik Turecek 选题:lujun9972 译者:geekpi 校对:wxy

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

这篇文章是关于如何在使用 cp 命令进行备份以及同步时提高效率。

去年七月,我写了一篇关于 cp 命令的两种绝佳用法的文章:备份一个文件,以及同步一个文件夹的备份。

虽然这些工具确实很好用,但同时,输入这些命令太过于累赘了。为了解决这个问题,我在我的 Bash 启动文件里创建了一些 Bash 快捷方式。现在,我想把这些捷径分享给你们,以便于你们在需要的时候可以拿来用,或者是给那些还不知道怎么使用 Bash 的别名以及函数的用户提供一些思路。

使用 Bash 别名来更新一个文件夹的副本

如果要使用 cp 来更新一个文件夹的副本,通常会使用到的命令是:

cp -r -u -v SOURCE-FOLDER DESTINATION-DIRECTORY

其中 -r 代表“向下递归访问文件夹中的所有文件”,-u 代表“更新目标”,-v 代表“详细模式”,SOURCE-FOLDER 是包含最新文件的文件夹的名称,DESTINATION-DIRECTORY 是包含必须同步的SOURCE-FOLDER 副本的目录。

因为我经常使用 cp 命令来复制文件夹,我会很自然地想起使用 -r 选项。也许再想地更深入一些,我还可以想起用 -v 选项,如果再想得再深一层,我会想起用选项 -u(不知道这个选项是代表“更新”还是“同步”还是一些什么其它的)。

或者,还可以使用Bash 的别名功能来将 cp 命令以及其后的选项转换成一个更容易记忆的单词,就像这样:

alias sync='cp -r -u -v'

如果我将其保存在我的主目录中的 .bash_aliases 文件中,然后启动一个新的终端会话,我可以使用该别名了,例如:

sync Pictures /media/me/4388-E5FE

可以将我的主目录中的图片文件夹与我的 USB 驱动器中的相同版本同步。

不清楚 sync 是否已经定义了?你可以在终端里输入 alias 这个单词来列出所有正在使用的命令别名。

喜欢吗?想要现在就立即使用吗?那就现在打开终端,输入:

echo "alias sync='cp -r -u -v'" >> ~/.bash_aliases

然后启动一个新的终端窗口并在命令提示符下键入 alias。你应该看到这样的东西:

me@mymachine~$ alias

alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias gvm='sdk'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'
alias sync='cp -r -u -v'
me@mymachine:~$

这里你能看到 sync 已经定义了。

使用 Bash 函数来为备份编号

若要使用 cp 来备份一个文件,通常使用的命令是:

cp --force --backup=numbered WORKING-FILE BACKED-UP-FILE

其中 --force 代表“强制制作副本”,--backup= numbered 代表“使用数字表示备份的生成”,WORKING-FILE 是我们希望保留的当前文件,BACKED-UP-FILEWORKING-FILE 的名称相同,并附加生成信息。

我们不仅需要记得所有 cp 的选项,我们还需要记得去重复输入 WORKING-FILE 的名字。但当Bash 的函数功能已经可以帮我们做这一切,为什么我们还要不断地重复这个过程呢?就像这样:

再一次提醒,你可将下列内容保存入你在家目录下的 .bash_aliases 文件里:

function backup {
    if [ $# -ne 1 ]; then
        echo "Usage: $0 filename"
    elif [ -f $1 ] ; then
        echo "cp --force --backup=numbered $1 $1"
        cp --force --backup=numbered $1 $1
    else
        echo "$0: $1 is not a file"
    fi
}

我将此函数称之为 backup,因为我的系统上没有任何其他名为 backup 的命令,但你可以选择适合的任何名称。

第一个 if 语句是用于检查是否提供有且只有一个参数,否则,它会用 echo 命令来打印出正确的用法。

elif 语句是用于检查提供的参数所指向的是一个文件,如果是的话,它会用第二个 echo 命令来打印所需的 cp 的命令(所有的选项都是用全称来表示)并且执行它。

如果所提供的参数不是一个文件,文件中的第三个 echo 用于打印错误信息。

在我的家目录下,如果我执行 backup 这个命令,我可以发现目录下多了一个文件名为checkCounts.sql.~1~ 的文件,如果我再执行一次,便又多了另一个名为 checkCounts.sql.~2~ 的文件。

成功了!就像所想的一样,我可以继续编辑 checkCounts.sql,但如果我可以经常地用这个命令来为文件制作快照的话,我可以在我遇到问题的时候回退到最近的版本。

也许在未来的某个时间,使用 git 作为版本控制系统会是一个好主意。但像上文所介绍的 backup 这个简单而又好用的工具,是你在需要使用快照的功能时却还未准备好使用 git 的最好工具。

结论

在我的上一篇文章里,我保证我会通过使用脚本,shell 里的函数以及别名功能来简化一些机械性的动作来提高生产效率。

在这篇文章里,我已经展示了如何在使用 cp 命令同步或者备份文件时运用 shell 函数以及别名功能来简化操作。如果你想要了解更多,可以读一下这两篇文章:怎样通过使用命令别名功能来减少敲击键盘的次数 以及由我的同事 Greg 和 Seth 写的 Shell 编程:shift 方法和自定义函数介绍


via: https://opensource.com/article/18/1/two-great-uses-cp-command-update

作者:Chris Hermansen 译者:zyk2290 校对:wxy

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

今天的消息,又挣扎了两年的《Linux Journal》,宣布倒闭了。他们宣布

2019 年 8 月 7 日,Linux Journal 关闭了大门。所有员工都被解雇了,公司没有任何经营资金可以继续以任何身份持续下去了。这个网站在接下来的几个星期内将继续维持,如果可以的话,希望可以保持更长时间的存档。

—— Linux Journal,LLC

这不是 Linux Journal 第一次发出悲呼。在一年半前,他们就宣布了停刊,但幸而在宣布停刊之后得到了社区的援手,得以复活,又持续了一年多。他们甚至对新的希望报以了很大的信心,在他们庆祝 25 周年的时候,还写了一篇文章来分析发生了什么,以及将来的想法。而且,确实,他们也在努力做出了新的改变。

但是,不管什么原因吧,这份创刊于 1994 的 Linux 杂志,在放弃了纸质杂志、电子杂志之后,可能要变成一个历史遗迹了。他们在网站上,用一张血红的纸张上扯破露出“TIME TO SAY GOODBYE”表达了对这份持续了 25 年的努力的不甘和哀伤——我是真能感受到这背后的哀伤。

说起来,Linux Journal 真是一个非常有价值的杂志/门户/社区,与之相比,我们的 Linux 中国社区就逊色多了,但是正是同一时刻,我也面临了 Linux 中国是否能继续下去的一些风刀雪箭,莫非天意?

说起来,Linux 中国也持续性的走了至少 6 年了 —— 如果从 2013 年 9 月 10 日 LCTT 成立算起的话。刚刚我在朋友圈发了一条消息,询问大家觉得 Linux 中国有无商业价值,不敢太严肃的问,怕引来各种联想。当然,有很多开玩笑的回答,也有一些感性的估计,也有一些用心的感激。其实,何必问呢,答案我心里有啊。

或许,Linux 中国有一些社会价值,也许帮到过许多人,也有很多人在这里付出了很多、很多的努力,但是,我们这 6 年没有尺寸进益,这说明了什么,我们究竟有没有商业价值?

很多人都知道,我一直坚持 Linux 中国的公益性、非商业性,也主张 Linux 中国是大家的,而不是我的或谁的。可是如果连起码的商业平衡也不能积累,是不是从一开始就是一个乌托邦式的空中楼阁?

Linux Journal 就倒在我的身侧,我遥望远方……

老王写于昆明,2019/8/8