2018年3月

Q:我想在 Linux / 类Unix 系统上使用 awk 打印文件名。 如何使用 awk 的 BEGIN 特殊模式打印文件名? 我可以使用 gawk/awk 打印当前输入文件的名称吗?(LCTT 译注:读者最好能有一些 awk 的背景知识,否则阅读本文的时候会有一些困惑)

FILENAME 变量中存放着当前输入文件的名称。 您可以使用 FILENAME 显示或打印当前输入文件名,如果在命令行中未指定文件,则 FILENAME 的值为 - (标准输入)(LCTT 译注:多次按下回车键即可看到效果)。 但是,除非由 getline 设置,否则 FILENAMEBEGIN 特殊模式中未定义。

使用 awk 打印文件名

使用语法如下:

awk '{ print FILENAME }' fileNameHere 
awk '{ print FILENAME }' /etc/hosts

因 awk 逐行读取文件,因此,你可能看到多个文件名,为了避免这个情况,你可以使用如下的命令:(LCTT 译注:FNR 表示当前记录数,只在文件中有效)

awk 'FNR == 1{ print FILENAME } ' /etc/passwd 
awk 'FNR == 1{ print FILENAME } ' /etc/hosts

使用 awk 的 BEGIN 特殊规则打印文件名

使用下面的语法:(LCTT 译注:ARGV[I] 表示输入的第 i 个参数)

awk 'BEGIN{print ARGV[1]}' fileNameHere 
awk 'BEGIN{print ARGV[1]}{ print "someting or do something on data" }END{}' fileNameHere 
awk 'BEGIN{print ARGV[1]}' /etc/hosts

示例输出:

/etc/hosts

然而,ARGV[1] 并不是每一次都能奏效,例如:

ls -l /etc/hosts | awk 'BEGIN{print ARGV[1]} { print }'

你需要将它修改如下(假设 ls -l 只产生一行输出):

ls -l /etc/hosts | awk '{ print "File: " $9 ", Owner:" $3 ", Group: " $4 }'

示例输出:

File: /etc/hosts, Owner:root, Group: root

处理由通配符指定的多个文件名

使用如下的示例语法:

awk '{ print FILENAME; nextfile } ' *.c 
awk 'BEGIN{ print "Starting..."} { print FILENAME; nextfile }END{ print "....DONE"} ' *.conf

示例输出:

Starting...
blkid.conf
cryptconfig.conf
dhclient6.conf
dhclient.conf
dracut.conf
gai.conf
gnome_defaults.conf
host.conf
idmapd.conf
idnalias.conf
idn.conf
insserv.conf
iscsid.conf
krb5.conf
ld.so.conf
logrotate.conf
mke2fs.conf
mtools.conf
netscsid.conf
nfsmount.conf
nscd.conf
nsswitch.conf
openct.conf
opensc.conf
request-key.conf
resolv.conf
rsyncd.conf
sensors3.conf
slp.conf
smartd.conf
sysctl.conf
vconsole.conf
warnquota.conf
wodim.conf
xattr.conf
xinetd.conf
yp.conf
....DONE

nextfile 告诉 awk 停止处理当前的输入文件。 下一个输入记录读取来自下一个输入文件。 更多信息,请参见 awk/gawk 命令手册页:

man awk 
man gawk

关于作者

作者是 nixCraft 的创立者,也是经验丰富的系统管理员和 Linux/Unix shell 脚本的培训师。 他曾与全球各行各业的客户合作,涉及 IT,教育,国防和空间研究以及非营利部门等多个行业。 您可以在 TwitterFacebookGoogle+上关注他。 可以通过订阅我的 RSS 来获取更多的关于系统管理,Linux/Unix ,和开源主题的相关资料。


via: https://www.cyberciti.biz/faq/how-to-print-filename-with-awk-on-linux-unix/

作者:Vivek Gite 译者:amwps290 校对:wxy

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

学习在你的 Linux 计算机上摆弄那些软件。

如何在 Linux 上安装应用程序?因为有许多操作系统,这个问题不止有一个答案。应用程序可以可以来自许多来源 —— 几乎不可能数的清,并且每个开发团队都可以以他们认为最好的方式提供软件。知道如何安装你所得到的软件是成为操作系统高级用户的一部分。

仓库

十多年来,Linux 已经在使用软件库来分发软件。在这种情况下,“仓库”是一个托管可安装软件包的公共服务器。Linux 发行版提供了一条命令,以及该命令的图形界面,用于从服务器获取软件并将其安装到你的计算机。这是一个非常简单的概念,它已经成为所有主流手机操作系统的模式,最近,该模式也成为了两大闭源计算机操作系统的“应用商店”。

 title=

不是应用程序商店

从软件仓库安装是在 Linux 上安装应用程序的主要方法,它应该是你寻找想要安装的任何应用程序的首选地方。

从软件仓库安装,通常需要一个命令,如:

$ sudo dnf install inkscape

实际使用的命令取决于你所使用的 Linux 发行版。Fedora 使用 dnf,OpenSUSE 使用 zypper,Debian 和 Ubuntu 使用 apt,Slackware 使用 sbopkg,FreeBSD 使用 pkg_add,而基于 lllumos 的 Openlndiana 使用 pkg。无论你使用什么,该命令通常要搜索你想要安装应用程序的正确名称,因为有时候你认为的软件名称不是它官方或独有的名称:

$ sudo dnf search pyqt
PyQt.x86_64 : Python bindings for Qt3
PyQt4.x86_64 : Python bindings for Qt4
python-qt5.x86_64 : PyQt5 is Python bindings for Qt5

一旦你找到要安装的软件包的名称后,使用 install 子命令执行实际的下载和自动安装:

$ sudo dnf install python-qt5

有关从软件仓库安装的具体信息,请参阅你的 Linux 发行版的文档。

图形工具通常也是如此。搜索你认为你想要的,然后安装它。

与底层命令一样,图形安装程序的名称取决于你正在运行的 Linux 发行版。相关的应用程序通常使用“软件(software)”或“包(package)”等关键字进行标记,因此请在你的启动项或菜单中搜索这些词汇,然后你将找到所需的内容。 由于开源全由用户来选择,所以如果你不喜欢你的发行版提供的图形用户界面(GUI),那么你可以选择安装替代品。 你知道该如何做到这一点。

额外仓库

你的 Linux 发行版为其打包的软件提供了标准仓库,通常也有额外的仓库。例如,EPEL 服务于 Red Hat Enterprise Linux 和 CentOS,RPMFusion 服务于 Fedora,Ubuntu 有各种级别的支持以及个人包存档(PPA),Packman 为 OpenSUSE 提供额外的软件以及 SlackBuilds.org 为 Slackware 提供社区构建脚本。

默认情况下,你的 Linux 操作系统设置为只查看其官方仓库,因此如果你想使用其他软件集合,则必须自己添加额外库。你通常可以像安装软件包一样安装仓库。实际上,当你安装例如 GNU Ring 视频聊天,Vivaldi web 浏览器,谷歌浏览器等许多软件时,你的实际安装是访问他们的私有仓库,从中将最新版本的应用程序安装到你的机器上。

 title=

安装仓库

你还可以通过编辑文本文件将仓库手动添加到你的软件包管理器的配置目录,或者运行命令来添加添加仓库。像往常一样,你使用的确切命令取决于 Linux 发行版本。例如,这是一个 dnf 命令,它将一个仓库添加到系统中:

$ sudo dnf config-manager --add-repo=http://example.com/pub/centos/7

不使用仓库来安装应用程序

仓库模型非常流行,因为它提供了用户(你)和开发人员之间的链接。重要更新发布之后,系统会提示你接受更新,并且你可以从一个集中位置接受所有更新。

然而,有时候一个软件包还没有放到仓库中时。这些安装包有几种形式。

Linux 包

有时候,开发人员会以通用的 Linux 打包格式分发软件,例如 RPM、DEB 或较新但非常流行的 FlatPak 或 Snap 格式。你不是访问仓库下载的,你只是得到了这个包。

例如,视频编辑器 Lightworks 为 APT 用户提供了一个 .deb 文件,RPM 用户提供了 .rpm 文件。当你想要更新时,可以到网站下载最新的适合的文件。

这些一次性软件包可以使用从仓库进行安装时所用的一样的工具进行安装。如果双击下载的软件包,图形安装程序将启动并逐步完成安装过程。

或者,你可以从终端进行安装。这里的区别在于你从互联网下载的独立包文件不是来自仓库。这是一个“本地”安装,这意味着你的软件安装包不需要下载来安装。大多数软件包管理器都是透明处理的:

$ sudo dnf install ~/Downloads/lwks-14.0.0-amd64.rpm

在某些情况下,你需要采取额外的步骤才能使应用程序运行,因此请仔细阅读有关你正在安装软件的文档。

通用安装脚本

一些开发人员以几种通用格式发布他们的包。常见的扩展名包括 .run.sh。NVIDIA 显卡驱动程序、像 Nuke 和 Mari 这样的 Foundry visual FX 软件包以及来自 GOG 的许多非 DRM 游戏都是用这种安装程序。(LCTT 译注:DRM 是数字版权管理。)

这种安装模式依赖于开发人员提供安装“向导”。一些安装程序是图形化的,而另一些只是在终端中运行。

有两种方式来运行这些类型的安装程序。

1、 你可以直接从终端运行安装程序:

$ sh ./game/gog_warsow_x.y.z.sh

2、 另外,你可以通过标记其为可执行文件来运行它。要标记为安装程序可执行文件,右键单击它的图标并选择其属性。

 title=

给安装程序可执行权限。

一旦你允许其运行,双击图标就可以安装了。

 title=

GOG 安装程序

对于其余的安装程序,只需要按照屏幕上的说明进行操作。

AppImage 便携式应用程序

AppImage 格式对于 Linux 相对来说比较新,尽管它的概念是基于 NeXT 和 Rox 的。这个想法很简单:运行应用程序所需的一切都应该放在一个目录中,然后该目录被视为一个“应用程序”。要运行该应用程序,只需双击该图标即可运行。不需要也要不应该把应用程序安装在传统意义的地方;它从你在硬盘上的任何地方运行都行。

尽管它可以作为独立应用运行,但 AppImage 通常提供一些系统集成。

 title=

AppImage 系统集成

如果你接受此条件,则将一个本地的 .desktop 文件安装到你的主目录。.desktop 文件是 Linux 桌面的应用程序菜单和 mimetype 系统使用的一个小配置文件。实质上,只是将桌面配置文件放置在主目录的应用程序列表中“安装”应用程序,而不实际安装它。你获得了安装某些东西的所有好处,以及能够在本地运行某些东西的好处,即“便携式应用程序”。

应用程序目录

有时,开发人员只是编译一个应用程序,然后将结果发布到下载中,没有安装脚本,也没有打包。通常,这意味着你下载了一个 TAR 文件,然后 解压缩,然后双击可执行文件(通常是你下载软件的名称)。

 title=

下载 Twine

当使用这种软件方式交付时,你可以将它放在你下载的地方,当你需要它时,你可以手动启动它,或者你可以自己进行快速但是麻烦的安装。这包括两个简单的步骤:

  1. 将目录保存到一个标准位置,并在需要时手动启动它。
  2. 将目录保存到一个标准位置,并创建一个 .desktop 文件,将其集成到你的系统中。

如果你只是为自己安装应用程序,那么传统上会在你的主目录中放个 bin (“ 二进制文件 binary ” 的简称)目录作为本地安装的应用程序和脚本的存储位置。如果你的系统上有其他用户需要访问这些应用程序,传统上将二进制文件放置在 /opt 中。最后,这取决于你存储应用程序的位置。

下载通常以带版本名称的目录进行,如 twine_2.13 或者 pcgen-v6.07.04。由于假设你将在某个时候更新应用程序,因此将版本号删除或创建目录的符号链接是个不错的主意。这样,即使你更新应用程序本身,为应用程序创建的启动程序也可以保持不变。

要创建一个 .desktop 启动文件,打开一个文本编辑器并创建一个名为 twine.desktop 的文件。桌面条目规范FreeDesktop.org 定义。下面是一个简单的启动器,用于一个名为 Twine 的游戏开发 IDE,安装在系统范围的 /opt 目录中:

[Desktop Entry]
Encoding=UTF-8
Name=Twine
GenericName=Twine
Comment=Twine
Exec=/opt/twine/Twine
Icon=/usr/share/icons/oxygen/64x64/categories/applications-games.png
Terminal=false
Type=Application
Categories=Development;IDE;

棘手的一行是 Exec 行。它必须包含一个有效的命令来启动应用程序。通常,它只是你下载的东西的完整路径,但在某些情况下,它更复杂一些。例如,Java 应用程序可能需要作为 Java 自身的参数启动。

Exec=java -jar /path/to/foo.jar

有时,一个项目包含一个可以运行的包装脚本,这样你就不必找出正确的命令:

Exec=/opt/foo/foo-launcher.sh

在这个 Twine 例子中,没有与该下载的软件捆绑的图标,因此示例 .desktop 文件指定了 KDE 桌面附带的通用游戏图标。你可以使用类似的解决方法,但如果你更具艺术性,可以创建自己的图标,或者可以在 Internet 上搜索一个好的图标。只要 Icon 行指向一个有效的 PNG 或 SVG 文件,你的应用程序就会以该图标为代表。

示例脚本还将应用程序类别主要设置为 Development,因此在 KDE、GNOME 和大多数其他应用程序菜单中,Twine 出现在开发类别下。

为了让这个例子出现在应用程序菜单中,把 twine.desktop 文件放这到两个地方之一:

  • 如果你将应用程序存储在你自己的家目录下,那么请将其放在 ~/.local/share/applications
  • 如果你将应用程序存储在 /opt 目录或者其他系统范围的位置,并希望它出现在所有用户的应用程序菜单中,请将它放在 /usr/share/applications 目录中。

现在,该应用程序已安装,因为它需要与系统的其他部分集成。

从源代码编译

最后,还有真正的通用格式安装格式:源代码。从源代码编译应用程序是学习如何构建应用程序,如何与系统交互以及如何定制应用程序的好方法。尽管如此,它绝不是一个点击按钮式过程。它需要一个构建环境,通常需要安装依赖库和头文件,有时还要进行一些调试。

要了解更多关于从源代码编译的内容,请阅读我这篇文章

现在你明白了

有些人认为安装软件是一个神奇的过程,只有开发人员理解,或者他们认为它“激活”了应用程序,就好像二进制可执行文件在“安装”之前无效。学习许多不同的安装方法会告诉你安装实际上只是“将文件从一个地方复制到系统中适当位置”的简写。 没有什么神秘的。只要你去了解每次安装,不是期望应该如何发生,并且寻找开发者为安装过程设置了什么,那么通常很容易,即使它与你的习惯不同。

重要的是安装器要诚实于你。 如果你遇到未经你的同意尝试安装其他软件的安装程序(或者它可能会以混淆或误导的方式请求同意),或者尝试在没有明显原因的情况下对系统执行检查,则不要继续安装。

好的软件是灵活的、诚实的、开放的。 现在你知道如何在你的计算机上获得好软件了。


via: https://opensource.com/article/18/1/how-install-apps-linux

作者:Seth Kenlon 译者:MjSeven 校对:wxy

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

用一些简单的脚本,可以很容易地清理文档和其它大量的 HTML 文件。但是首先你需要解析它们。

作为 Scribus 文档团队的长期成员,我要随时了解最新的源代码更新,以便对文档进行更新和补充。 我最近在刚升级到 Fedora 27 系统的计算机上使用 Subversion 进行检出操作时,对于下载该文档所需要的时间我感到很惊讶,文档由 HTML 页面和相关图像组成。 我恐怕该项目的文档看起来比项目本身大得多,并且怀疑其中的一些内容是“僵尸”文档——不再使用的 HTML 文件以及 HTML 中无法访问到的图像。

我决定为自己创建一个项目来解决这个问题。 一种方法是搜索未使用的现有图像文件。 如果我可以扫描所有 HTML 文件中的图像引用,然后将该列表与实际图像文件进行比较,那么我可能会看到不匹配的文件。

这是一个典型的图像标签:

<img src="images/edit_shapes.png" ALT="Edit examples" ALIGN=left>

我对 src= 之后的第一组引号之间的部分很感兴趣。 在寻找了一些解决方案后,我找到一个名为 BeautifulSoup 的 Python 模块。 脚本的核心部分如下所示:

soup = BeautifulSoup(all_text, 'html.parser')
match = soup.findAll("img")
if len(match) > 0:
    for m in match:
        imagelist.append(str(m))

我们可以使用这个 findAll 方法来挖出图片标签。 这是一小部分输出:

<img src="images/pdf-form-ht3.png"/><img src="images/pdf-form-ht4.png"/><img src="images/pdf-form-ht5.png"/><img src="images/pdf-form-ht6.png"/><img align="middle" alt="GSview - Advanced Options Panel" src="images/gsadv1.png" title="GSview - Advanced Options Panel"/><img align="middle" alt="Scribus External Tools Preferences" src="images/gsadv2.png" title="Scribus External Tools Preferences"/>

到现在为止还挺好。我原以为下一步就可以搞定了,但是当我在脚本中尝试了一些字符串方法时,它返回了有关标记的错误而不是字符串的错误。 我将输出保存到一个文件中,并在 KWrite 中进行编辑。 KWrite 的一个好处是你可以使用正则表达式(regex)来做“查找和替换”操作,所以我可以用 \n<img 替换 <img,这样可以看得更清楚。 KWrite 的另一个好处是,如果你用正则表达式做了一个不明智的选择,你还可以撤消。

但我认为,肯定有比这更好的东西,所以我转而使用正则表达式,或者更具体地说 Python 的 re 模块。 这个新脚本的相关部分如下所示:

match = re.findall(r'src="(.*)/>', all_text)
if len(match)>0:
    for m in match:
        imagelist.append(m)

它的一小部分输出如下所示:

images/cmcanvas.png" title="Context Menu for the document canvas" alt="Context Menu for the document canvas" /></td></tr></table><br images/eps-imp1.png" title="EPS preview in a file dialog" alt="EPS preview in a file dialog" images/eps-imp5.png" title="Colors imported from an EPS file" alt="Colors imported from an EPS file" images/eps-imp4.png" title="EPS font substitution" alt="EPS font substitution" images/eps-imp2.png" title="EPS import progress" alt="EPS import progress" images/eps-imp3.png" title="Bitmap conversion failure" alt="Bitmap conversion failure"

乍一看,它看起来与上面的输出类似,并且附带有去除图像的标签部分的好处,但是有令人费解的是还夹杂着表格标签和其他内容。 我认为这涉及到这个正则表达式 src="(.*)/>,这被称为贪婪,意味着它不一定停止在遇到 /> 的第一个实例。我应该补充一点,我也尝试过 src="(.*)",这真的没有什么更好的效果,我不是一个正则表达式专家(只是做了这个),找了各种方法来改进这一点但是并没什么用。

做了一系列的事情之后,甚至尝试了 Perl 的 HTML::Parser 模块,最终我试图将这与我为 Scribus 编写的一些脚本进行比较,这些脚本逐个字符的分析文本内容,然后采取一些行动。 为了最终目的,我终于想出了所有这些方法,并且完全不需要正则表达式或 HTML 解析器。 让我们回到展示的那个 img 标签的例子。

<img src="images/edit_shapes.png" ALT="Edit examples" ALIGN=left>

我决定回到 src= 这一块。 一种方法是等待 s 出现,然后看下一个字符是否是 r,下一个是 c,下一个是否 =。 如果是这样,那就匹配上了! 那么两个双引号之间的内容就是我所需要的。 这种方法的问题在于需要连续识别上面这样的结构。 一种查看代表一行 HTML 文本的字符串的方法是:

for c in all_text:

但是这个逻辑太乱了,以至于不能持续匹配到前面的 c,还有之前的字符,更之前的字符,更更之前的字符。

最后,我决定专注于 = 并使用索引方法,以便我可以轻松地引用字符串中的任何先前或将来的字符。 这里是搜索部分:

    index = 3
    while index < linelength:
        if (all_text[index] == '='):
            if (all_text[index-3] == 's') and (all_text[index-2] == 'r') and (all_text[index-1] == 'c'):
                imagefound(all_text, imagelist, index)
                index += 1
            else:
                index += 1
        else:
            index += 1

我用第四个字符开始搜索(索引从 0 开始),所以我在下面没有出现索引错误,并且实际上,在每一行的第四个字符之前不会有等号。 第一个测试是看字符串中是否出现了 =,如果没有,我们就会前进。 如果我们确实看到一个等号,那么我们会看前三个字符是否是 src。 如果全都匹配了,就调用函数 imagefound

def imagefound(all_text, imagelist, index):
    end = 0
    index += 2
    newimage = ''
    while end == 0:
        if (all_text[index] != '"'):
            newimage = newimage + all_text[index]
            index += 1
        else:
            newimage = newimage + '\n'
            imagelist.append(newimage)
            end = 1
            return

我们给函数发送当前索引,它代表着 =。 我们知道下一个字符将会是 ",所以我们跳过两个字符,并开始向名为 newimage 的控制字符串添加字符,直到我们发现下一个 ",此时我们完成了一次匹配。 我们将字符串加一个换行符(\n)添加到列表 imagelist 中并返回(return),请记住,在剩余的这个 HTML 字符串中可能会有更多图片标签,所以我们马上回到搜索循环中。

以下是我们的输出现在的样子:

images/text-frame-link.png
images/text-frame-unlink.png
images/gimpoptions1.png
images/gimpoptions3.png
images/gimpoptions2.png
images/fontpref3.png
images/font-subst.png
images/fontpref2.png
images/fontpref1.png
images/dtp-studio.png

啊,干净多了,而这只花费几秒钟的时间。 我本可以将索引前移 7 步来剪切 images/ 部分,但我更愿意把这个部分保存下来,以确保我没有剪切掉图像文件名的第一个字母,这很容易用 KWrite 编辑成功 —— 你甚至不需要正则表达式。 做完这些并保存文件后,下一步就是运行我编写的另一个脚本 sortlist.py

#!/usr/bin/env python
# -*- coding: utf-8  -*-
# sortlist.py

import os

imagelist = []
for line in open('/tmp/imagelist_parse4.txt').xreadlines():
    imagelist.append(line)

imagelist.sort()

outfile = open('/tmp/imagelist_parse4_sorted.txt', 'w')
outfile.writelines(imagelist)
outfile.close()

这会读取文件内容,并存储为列表,对其排序,然后另存为另一个文件。 之后,我可以做到以下几点:

ls /home/gregp/development/Scribus15x/doc/en/images/*.png > '/tmp/actual_images.txt'

然后我需要在该文件上运行 sortlist.py,因为 ls 方法的排序与 Python 不同。 我原本可以在这些文件上运行比较脚本,但我更愿意以可视方式进行操作。 最后,我成功找到了 42 个图像,这些图像没有来自文档的 HTML 引用。

这是我的完整解析脚本:

#!/usr/bin/env python
# -*- coding: utf-8  -*-
# parseimg4.py

import os

def imagefound(all_text, imagelist, index):
    end = 0
    index += 2
    newimage = ''
    while end == 0:
        if (all_text[index] != '"'):
            newimage = newimage + all_text[index]
            index += 1
        else:
            newimage = newimage + '\n'
            imagelist.append(newimage)
            end = 1
            return

htmlnames = []
imagelist = []
tempstring = ''
filenames = os.listdir('/home/gregp/development/Scribus15x/doc/en/')
for name in filenames:
    if name.endswith('.html'):
        htmlnames.append(name)
#print htmlnames
for htmlfile in htmlnames:
    all_text = open('/home/gregp/development/Scribus15x/doc/en/' + htmlfile).read()
    linelength = len(all_text)
    index = 3
    while index < linelength:
        if (all_text[index] == '='):
            if (all_text[index-3] == 's') and (all_text[index-2] == 'r') and
(all_text[index-1] == 'c'):
                imagefound(all_text, imagelist, index)
                index += 1
            else:
                index += 1
        else:
            index += 1

outfile = open('/tmp/imagelist_parse4.txt', 'w')
outfile.writelines(imagelist)
outfile.close()
imageno = len(imagelist)
print str(imageno) + " images were found and saved"

脚本名称为 parseimg4.py,这并不能真实反映我陆续编写的脚本数量(包括微调的和大改的以及丢弃并重新开始写的)。 请注意,我已经对这些目录和文件名进行了硬编码,但是很容易变得通用化,让用户输入这些信息。 同样,因为它们是工作脚本,所以我将输出发送到 /tmp 目录,所以一旦重新启动系统,它们就会消失。

这不是故事的结尾,因为下一个问题是:僵尸 HTML 文件怎么办? 任何未使用的文件都可能会引用图像,不能被前面的方法所找出。 我们有一个 menu.xml 文件作为联机手册的目录,但我还需要考虑 TOC(LCTT 译注:TOC 是 table of contents 的缩写)中列出的某些文件可能引用了不在 TOC 中的文件,是的,我确实找到了一些这样的文件。

最后我可以说,这是一个比图像搜索更简单的任务,而且开发的过程对我有很大的帮助。

关于作者

Greg Pittman 是 Kentucky 州 Louisville 市的一名退休的神经学家,从二十世纪六十年代的 Fortran IV 语言开始长期以来对计算机和编程有着浓厚的兴趣。 当 Linux 和开源软件出现的时候,Greg 深受启发,去学习更多知识,并实现最终贡献的承诺。 他是 Scribus 团队的成员。更多关于我


via: https://opensource.com/article/18/1/parsing-html-python

作者:Greg Pittman 译者:Flowsnow 校对:wxy

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

Google 的工程总监 Chen Goldberg 在最近的奥斯汀 KubeCon 和 CloudNativeCon上说,Kubernetes 的扩展能力是它的秘密武器。

在建立帮助工程师提高工作效率的工具的竞赛中,Goldberg 谈到他曾经领导过一个开发这样一个平台的团队。尽管平台最初有用,但它无法扩展,并且修改也很困难。

幸运的是,Goldberg 说,Kubernetes 没有这些问题。首先,Kubernetes 是一个自我修复系统,因为它使用的控制器实现了“ 协调环 Reconciliation Loop ”。在协调环中,控制器观察系统的当前状态并将其与所需状态进行比较。一旦它确定了这两个状态之间的差异,它就会努力实现所需的状态。这使得 Kubernetes 非常适合动态环境。

3 种扩展 Kubernetes 的方式

Goldberg 然后解释说,要建立控制器,你需要资源,也就是说,你需要扩展 Kubernetes。有三种方法可以做到这一点,从最灵活(但也更困难)到最简单的依次是:使用 Kube 聚合器、使用 API​​ 服务器构建器或创建 自定义资源定义 Custom Resource Definition (CRD)。

后者甚至可以使用极少的代码来扩展 Kubernetes 的功能。为了演示它是如何完成的,Goggle 软件工程师 Anthony Yeh 上台展示了为 Kubernetes 添加一个状态集。 (状态集对象用于管理有状态应用,即需要存储应用状态的程序,跟踪例如用户身份及其个人设置。)使用 catset,在一个 100 行 JavaScript 的文件中实现的 CRD,Yeh 展示了如何将状态集添加到 Kubernetes 部署中。之前的扩展不是 CRD,需要 24 个文件和 3000 多行代码。

为解决 CRD 可靠性问题,Goldberg 表示,Kubernetes 已经启动了一项认证计划,允许公司在 Kubernetes 社区注册和认证其扩展。在一个月内,已有 30 多家公司报名参加该计划。

Goldberg 继续解释 Kubernetes 的可扩展性如何成为今年 KubeCon 的热门话题,以及 Google 和 IBM 如何构建一个使用 CRD 管理和保护微服务的平台。或者一些开发人员如何将机器学习带入 Kubernetes,另外展示开放服务代理以及在混合设置上的服务消费。

Goldberg 总结说,可扩展性是种增能。而且,Kubernetes 的可扩展性使其成为开发者的通用平台,并且易于使用,这使得他们可以运行任何应用程序。

你可以在下面观看整个视频:


via: https://www.linux.com/blog/event/kubecon/2018/2/3-ways-extend-power-kubernetes

作者:PAUL BROWN 译者:geekpi 校对:wxy

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

在本系列早先的文章中,我们讨论了关于如何在 Windows 10 上开启 WSL 之旅 的内容。作为本系列的最后一篇文章,我们准备探讨一些能在 Windows 10 上广泛使用的 Linux 命令。

话题深入之前,请先让我们明确本教程所适用的人群。本文适用于使用 Windows 10 系统,但是又想在 Azure、AWS 或是私有云平台上学习 Linux 的初级开发者。换句话说,就是为了帮助初次接触 Linux 系统的 Windows 10 用户。

您的工作任务决定了您所需要的命令,而我的需求可能和您的不一样。本文旨在帮助您在 Windwos 10 上舒服的使用 Linux。不过请牢记,WSL 并不提供硬件访问的功能,比如声卡、GPU,至少官方是这么描述的。但是这可能并不能阻止 Linux 用户的折腾精神。很多用户不仅完成了硬件访问,甚至已经在 Windows 10 上安装上了 Linux 桌面程序。但是本文并不会涉及这些内容,我们可能会讨论这些,但不是现在。

下面是我们需要着手的任务。

如何让您的 Linux 系统保持到最新的版本

因为 Linux 运行在了 Windows 系统中,所以您将被剥夺 Linux 系统所提供的所有安全特性。另外,如果不及时给 Linux 系统打补丁,你的 Windows 设备将被迫暴露在外界威胁中,所以还请保持您的 Linux 为最新版本。

WSL 官方支持 openSUSE/SUSE Linux Enterprise 和 Ubuntu。您也可以安装其他发行版,但是我只需要它们当中的二者之一就可以完成我的所有工作,毕竟,我只需要访问一些 Linux 基础程序。

更新 openSUSE Leap:

sudo zypper up

如果您想升级系统,您可以运行下面的命令:

sudo zypper dup

更新 Ubuntu:

sudo apt-get update
sudo apt-get dist-upgrade

这样你就安全了,由于 Linux 系统的更新是渐进式的,所以更新系统成为了我的日常。不像 Windows 10 的更新通常需要重启系统,而 Linux 不同,一般只有 KB 或是 MB 级的更新,无需重启。

管理文件目录

系统更新之后,我们来看看一些或普通或不太普通的任务。

系统更新之外的第二重要的任务是使用 Linux 管理本地和远程文件。我承认我更青睐图形界面程序,但是终端能提供更可靠、更有价值的服务。要不你使用资源管理器移动 1 TB 的文件试试?我通常使用 rsync 命令来移动大量文件。如果中断任务,rsync 可以在上次停止的位置继续工作。

虽然您可能更习惯使用 cp 或是 mv 命令复制、移动文件,但是我还是喜欢灵活的 rsync 命令,了解 rsync 对远程文件传输也有帮助。使用 rsync 大半为了完成下面三个任务:

使用 rsync 复制整个目录:

rsync -avzP /source-directory /destination directory

使用 rsync 移动文件:

rsync --remove-source-files -avzP /source-directory /destination-directory

在成功复制目标目录之后,此命令将删除源文件。

使用 rsync 同步文件:

我的文件可能在多处存储。但是,我只会在主要位置中增加或是删除。如果不使用专业的软件,同步文件可能会给用户带来挑战,而 rsync 刚好可以简化这个过程。这个命令可以让两个目录文件内容同步。不过要注意,这是一个单向同步,即从源位置同步到目标位置。

rsync --delete -avzP /source-directory /destination-directory

如果源目录中没有找到文件,上述命令将删除目标目录中的文件。换言之,它创建了源目录的一个镜像。

文件自动备份

保持文件备份是一项乏味的工作。为了保持我的设备的完全同步,我运行了一个 cron 作业在夜间保持我的所有目录同步。不过我会留一个外部驱动器,基本上每周我都会手动同步一次。由于可能删掉我不想删除的文件,所以我并没有使用 --delete 选项。我会根据情况手动决定是否使用这个选项。

创建 cron 作业,打开 crontab:

crontab -e

移动大文件时,我会选择在系统空闲的深夜执行该命令。此命令将在每天早上 1 点运行,您大概可以这样修改它:

# 0 1 * * * rsync -avzP /source-directory /destination-directory

这是使用 crontab 的定时作业的命令结构:

# m h dom mon dow command

在此,m = 分钟,h = 小时,dom = 本月的某天,mon = 月,dow = 本周的某天。

我们将在每天早上 1 点运行这条命令。您可以选择 dow 或是 dom(比如,每月 5 号)等。您可以在 这里 阅读更多相关内容。

管理远程服务器

在 Windows 系统上使用 WSL 的优势之一就是能方便管理云上的 Linux 服务器,WSL 能提供原生的 Linux 工具给您。首先,您需要使用 ssh 命令登录远程 Linux 服务器。

比如,我的服务器 ip 是 192.168.0.112;端口为 2018(不是默认的 22 端口);Linux 用户名是 swapnil,密码是 “就不告诉你”。

ssh -p2018 [email protected]

它会向您询问用户密码,然后您就可以登录到 Linux 服务器了。现在您可以在 Linux 服务器上执行任意您想执行的所有操作了。不需使用 PuTTY 程序了。

使用 rsync ,您可以很轻易的在本地机器和远程机器之间传输文件。源目录还是目标目录取决于您是上传文件到服务器,还是下载文件到本地目录,您可以使用 username@IP-address-of-server:/path-of-directory 来指定目录。

如果我想复制一些文本内容到服务器的 home 目录,命令如下:

rsync -avzP /source-directory-on-local-machine ‘ssh -p2018’ [email protected]:/home/swapnil/Documents/

这将会复制这些文件到远程服务器中 Documents 目录。

总结

本教程主要是为了证明您可以在 Windows 10 系统上通过 WSL 完成 Linux 方面的很大一部分的任务。通常来说,它提高了生产效率。现在,Linux 的世界已经向 Windwos 10 系统张开怀抱了,尽情探索吧。如果您有任何疑问,或是想了解 WSL 涉及到的其他层面,欢迎在下方的评论区分享您的想法。

Administering Linux on Azure (LFS205) 课程中了解更多,可以在 这里 注册。


via: https://www.linux.com/blog/learn/2018/3/most-useful-linux-commands-you-can-run-windows-10

作者:SAPNIL BHARTIYA 译者:CYLeft 校对:wxy

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

Q:如何对我存放在 /var/www/html/ 目录中的所有文件设置只读权限?

你可以使用 chmod 命令对 Linux/Unix/macOS/OS X/*BSD 操作系统上的所有文件来设置只读权限。这篇文章介绍如何在 Linux/Unix 的 web 服务器(如 Nginx、 Lighttpd、 Apache 等)上来设置只读文件权限。

如何设置文件为只读模式

语法为:

### 仅针对文件 ###
chmod 0444 /var/www/html/*
chmod 0444 /var/www/html/*.php

如何设置目录为只读模式

语法为:

### 仅针对目录 ###
chmod 0444 /var/www/html/
chmod 0444 /path/to/your/dir/
# ***************************************************************************
# 假如 web 服务器的用户/用户组是 www-data,文件拥有者是 ftp-data 用户/用户组
# ***************************************************************************
# 设置目录所有文件为只读
chmod -R 0444 /var/www/html/
# 设置文件/目录拥有者为 ftp-data
chown -R ftp-data:ftp-data /var/www/html/
# 所有目录和子目录的权限为 0445 (这样 web 服务器的用户或用户组就可以读取我们的文件)
find /var/www/html/ -type d -print0 | xargs -0 -I {} chmod 0445 "{}"

找到所有 /var/www/html 下的所有文件(包括子目录),键入:

### 仅对文件有效 ###
find /var/www/html -type f -iname "*" -print0 | xargs -I {} -0 chmod 0444 {}

然而,你需要在 /var/www/html 目录及其子目录上设置只读和执行权限,如此才能让 web 服务器能够访问根目录,键入:

### 仅对目录有效 ###
find /var/www/html -type d -iname "*" -print0 | xargs -I {} -0 chmod 0544 {}

警惕写权限

请注意在 /var/www/html/ 目录上的写权限会允许任何人删除文件或添加新文件。也就是说,你可能需要设置一个只读权限给 /var/www/html/ 目录本身。

### web根目录只读 ###
chmod 0555 /var/www/html

在某些情况下,根据你的设置要求,你可以改变文件的属主和属组来设置严格的权限。

### 如果 /var/www/html 目录的拥有人是普通用户,你可以设置拥有人为:root:root 或 httpd:httpd (推荐) ###
chown -R root:root /var/www/html/

### 确保 apache 拥有 /var/www/html/ ###
chown -R apache:apache /var/www/html/

关于 NFS 导出目录

你可以在 /etc/exports 文件中指定哪个目录应该拥有只读或者读写权限 。这个文件定义各种各样的共享在 NFS 服务器和他们的权限。如:

# 对任何人只读权限
/var/www/html *(ro,sync) 

# 对192.168.1.10(upload.example.com)客户端读写权限访问
/var/www/html 192.168.1.10(rw,sync)

关于用于 MS-Windows客户端的 Samba(CIFS)只读共享

要以只读共享 sales,更新 smb.conf,如下:

[sales]
comment = Sales Data
path = /export/cifs/sales
read only = Yes
guest ok = Yes

关于文件系统表(fstab)

你可以在 Unix/Linux 上的 /etc/fstab 文件中配置挂载某些文件为只读模式。

你需要有专用分区,不要设置其他系统分区为只读模式。

如下在 /etc/fstab 文件中设置 /srv/html 为只读模式。

/dev/sda6 /srv/html ext4 ro 1 1

你可以使用 mount 命令重新挂载分区为只读模式(使用 root 用户)

# mount -o remount,ro /dev/sda6 /srv/html

或者

# mount -o remount,ro /srv/html

上面的命令会尝试重新挂载已挂载的文件系统到 /srv/html上。这是改变文件系统挂载标志的常用方法,特别是让只读文件改为可写的。这种方式不会改变设备或者挂载点。让文件变得再次可写,键入:

# mount -o remount,rw /dev/sda6 /srv/html

# mount -o remount,rw /srv/html

Linux:chattr 命令

你可以在 Linux 文件系统上使用 chattr 命令改变文件属性为只读,如:

chattr +i /path/to/file.php
chattr +i /var/www/html/

# 查找任何在/var/www/html下的文件并设置为只读#
find /var/www/html -iname "*" -print0 | xargs -I {} -0 chattr +i {}

通过提供 -i 选项可删除只读属性:

chattr -i /path/to/file.php

FreeBSD、Mac OS X 和其他 BSD Unix 用户可使用chflags命令

### 设置只读 ##
chflags schg /path/to/file.php

### 删除只读 ##
chflags noschg /path/to/file.php

via: https://www.cyberciti.biz/faq/howto-set-readonly-file-permission-in-linux-unix/

作者:Vivek Gite 译者:yizhuoyan 校对:wxy

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