mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-02-13 00:11:22 +08:00
commit
a0d19e11f5
.travis.ymlMakefileREADME.md
published
20090718 Vmware Linux Guest Add a New Hard Disk Without Rebooting Guest.md20160117 How to use curl command with proxy username-password on Linux- Unix.md20170131 Book review Ours to Hack and to Own.md20170209 INTRODUCING DOCKER SECRETS MANAGEMENT.md20170426 Important Docker commands for Beginners.md20170512 Which Official Ubuntu Flavor Is Best for You.md20170515 Commands to check System & Hardware Information.md20170524 View Counting at Reddit.md20170802 Creating SWAP partition using FDISK - FALLOCATE commands.md20170804 Add speech to your Fedora system.md20170915 12 ip Command Examples for Linux Users.md20170915 Fake A Hollywood Hacker Screen in Linux Terminal.md20170924 Simulate System Loads.md20170925 A Commandline Fuzzy Search Tool For Linux.md20170925 Linux Free Command Explained for Beginners (6 Examples).md20171011 What is a firewall.md20171031 Migrating to Linux- An Introduction.md
201711
20141028 When Does Your OS Run.md20170202 Understanding Firewalld in Multi-Zone Configurations.md20170227 Ubuntu Core in LXD containers.md20170418 INTRODUCING MOBY PROJECT A NEW OPEN-SOURCE PROJECT TO ADVANCE THE SOFTWARE CONTAINERIZATION MOVEMENT.md20170531 Understanding Docker Container Host vs Container OS for Linux and Windows Containers.md20170608 The Life-Changing Magic of Tidying Up Code.md20170706 Wildcard Certificates Coming January 2018.md20170825 Guide to Linux App Is a Handy Tool for Every Level of Linux User.md20170905 GIVE AWAY YOUR CODE BUT NEVER YOUR TIME.md20170928 3 Python web scrapers and crawlers.md20171002 Scaling the GitLab database.md20171003 PostgreSQL Hash Indexes Are Now Cool.md20171004 No the Linux desktop hasnt jumped in popularity.md20171007 Instant 100 command line productivity boost.md20171008 8 best languages to blog about.md20171009 CyberShaolin Teaching the Next Generation of Cybersecurity Experts.md20171010 Getting Started Analyzing Twitter Data in Apache Kafka through KSQL.md20171011 How to set up a Postgres database on a Raspberry Pi.md20171011 Why Linux Works.md20171013 6 reasons open source is good for business.md20171013 Best of PostgreSQL 10 for the DBA.md20171015 How to implement cloud-native computing with Kubernetes.md20171015 Monitoring Slow SQL Queries via Slack.md20171015 Why Use Docker with R A DevOps Perspective.md20171016 Introducing CRI-O 1.0.md20171017 A tour of Postgres Index Types.md20171017 Image Processing on Linux.md20171018 How containers and microservices change security.md20171018 Learn how to program in Python by building a simple dice game.md20171018 Tips to Secure Your Network in the Wake of KRACK.md20171019 3 Simple Excellent Linux Network Monitors.md20171019 How to manage Docker containers in Kubernetes with Java.md20171020 3 Tools to Help You Remember Linux Commands.md20171020 Running Android on Top of a Linux Graphics Stack.md20171024 Top 5 Linux pain points in 2017.md20171024 Who contributed the most to open source in 2017 Let s analyze GitHub’s data and find out.md20171024 Why Did Ubuntu Drop Unity Mark Shuttleworth Explains.md20171025 How to roll your own backup solution with BorgBackup, Rclone and Wasabi cloud storage.md20171026 But I dont know what a container is .md20171026 Why is Kubernetes so popular.md20171101 How to use cron in Linux.md20171101 We re switching to a DCO for source code contributions.md20171106 4 Tools to Manage EXT2 EXT3 and EXT4 Health in Linux.md20171106 Finding Files with mlocate.md20171106 Linux Foundation Publishes Enterprise Open Source Guides.md20171106 Most companies can t buy an open source community clue. Here s how to do it right.md20171107 AWS adopts home-brewed KVM as new hypervisor.md20171107 How I created my first RPM package in Fedora.md20171108 Build and test applications with Ansible Container.md20171110 File better bugs with coredumpctl.md20171114 Linux totally dominates supercomputers.md20171116 5 Coolest Linux Terminal Emulators.md20171117 How to Easily Remember Linux Commands.md20171118 Getting started with OpenFaaS on minikube.md20171128 tmate – Instantly Share Your Terminal Session To Anyone In Seconds.md
20171109 Learn how to use tcpdump command with examples.md20171115 How to Fix the ‘No Space Left on Device- Error on Linux.md20171115 Security Jobs Are Hot Get Trained and Get Noticed.md20171120 Adopting Kubernetes step by step.md20171120 Save Files Directly To Google Drive And Download 10 Times Faster.md20171127 Migrating to Linux Disks Files and Filesystems.md20171128 A generic introduction to Gitlab CI.md201712
19951001 Writing man Pages Using groff.md20060808 Fix The Display and Console Gibberish on a Linux - Unix - OS X - BSD Systems.md20090701 The One in Which I Call Out Hacker News.md20130402 Dynamic linker tricks Using LD_PRELOAD to cheat inject features and investigate programs.md20160922 A Linux users guide to Logical Volume Management.md20161216 Kprobes Event Tracing on ARMv8.md20170215 How to take screenshots on Linux using Scrot.md20170219 How to auto start LXD containers at boot time in Linux.md20170219 How to protects Linux and Unix machines from accidental shutdowns-reboots with molly-guard.md20170413 More Unknown Linux Commands.md20170530 How to Improve a Legacy Codebase.md20170622 A users guide to links in the Linux filesystem.md20170630 LinchPin A simplified cloud orchestration tool using Ansible.md20170717 Neo4j and graph databases Getting started.md20170719 Containing System Services in Red Hat Enterprise Linux – Part 1.md20170730 Complete Beginners to PRO guide for GIT commands.md20170910 Cool vim feature sessions.md20170918 Executing Commands and Scripts at Reboot & Startup in Linux.md
2
.travis.yml
Normal file
2
.travis.yml
Normal file
@ -0,0 +1,2 @@
|
||||
language: c
|
||||
script: make -s check
|
51
Makefile
Normal file
51
Makefile
Normal file
@ -0,0 +1,51 @@
|
||||
DIR_PATTERN := (news|talk|tech)
|
||||
NAME_PATTERN := [0-9]{8} [a-zA-Z0-9_.,() -]*\.md
|
||||
|
||||
RULES := rule-source-added \
|
||||
rule-translation-requested \
|
||||
rule-translation-completed \
|
||||
rule-translation-revised \
|
||||
rule-translation-published
|
||||
.PHONY: check match $(RULES)
|
||||
|
||||
CHANGE_FILE := /tmp/changes
|
||||
|
||||
check: $(CHANGE_FILE)
|
||||
echo 'PR #$(TRAVIS_PULL_REQUEST) Changes:'
|
||||
cat $(CHANGE_FILE)
|
||||
echo
|
||||
echo 'Check for rules...'
|
||||
make -k $(RULES) 2>/dev/null | grep '^Rule Matched: '
|
||||
|
||||
$(CHANGE_FILE):
|
||||
git --no-pager diff $(TRAVIS_BRANCH) FETCH_HEAD --no-renames --name-status > $@
|
||||
|
||||
rule-source-added:
|
||||
echo 'Unmatched Files:'
|
||||
egrep -v '^A\s*"?sources/$(DIR_PATTERN)/$(NAME_PATTERN)"?' $(CHANGE_FILE) || true
|
||||
echo '[End of Unmatched Files]'
|
||||
[ $(shell egrep '^A\s*"?sources/$(DIR_PATTERN)/$(NAME_PATTERN)"?' $(CHANGE_FILE) | wc -l) -ge 1 ]
|
||||
[ $(shell egrep -v '^A\s*"?sources/$(DIR_PATTERN)/$(NAME_PATTERN)"?' $(CHANGE_FILE) | wc -l) = 0 ]
|
||||
echo 'Rule Matched: $(@)'
|
||||
|
||||
rule-translation-requested:
|
||||
[ $(shell egrep '^M\s*"?sources/$(DIR_PATTERN)/$(NAME_PATTERN)"?' $(CHANGE_FILE) | wc -l) = 1 ]
|
||||
[ $(shell cat $(CHANGE_FILE) | wc -l) = 1 ]
|
||||
echo 'Rule Matched: $(@)'
|
||||
|
||||
rule-translation-completed:
|
||||
[ $(shell egrep '^D\s*"?sources/$(DIR_PATTERN)/$(NAME_PATTERN)"?' $(CHANGE_FILE) | wc -l) = 1 ]
|
||||
[ $(shell egrep '^A\s*"?translated/$(DIR_PATTERN)/$(NAME_PATTERN)"?' $(CHANGE_FILE) | wc -l) = 1 ]
|
||||
[ $(shell cat $(CHANGE_FILE) | wc -l) = 2 ]
|
||||
echo 'Rule Matched: $(@)'
|
||||
|
||||
rule-translation-revised:
|
||||
[ $(shell egrep '^M\s*"?translated/$(DIR_PATTERN)/$(NAME_PATTERN)"?' $(CHANGE_FILE) | wc -l) = 1 ]
|
||||
[ $(shell cat $(CHANGE_FILE) | wc -l) = 1 ]
|
||||
echo 'Rule Matched: $(@)'
|
||||
|
||||
rule-translation-published:
|
||||
[ $(shell egrep '^D\s*"?translated/$(DIR_PATTERN)/$(NAME_PATTERN)"?' $(CHANGE_FILE) | wc -l) = 1 ]
|
||||
[ $(shell egrep '^A\s*"?published/$(NAME_PATTERN)' $(CHANGE_FILE) | wc -l) = 1 ]
|
||||
[ $(shell cat $(CHANGE_FILE) | wc -l) = 2 ]
|
||||
echo 'Rule Matched: $(@)'
|
@ -61,6 +61,8 @@ LCTT 的组成
|
||||
* 2017/03/16 提升 GHLandy、bestony、rusking 为新的 Core 成员。创建 Comic 小组。
|
||||
* 2017/04/11 启用头衔制,为各位重要成员颁发头衔。
|
||||
* 2017/11/21 鉴于 qhwdw 快速而上佳的翻译质量,提升 qhwdw 为新的 Core 成员。
|
||||
* 2017/11/19 wxy 在上海交大举办的 2017 中国开源年会上做了演讲:《[如何以翻译贡献参与开源社区](https://linux.cn/article-9084-1.html)》。
|
||||
* 2018/01/11 提升 lujun9972 成为核心成员,并加入选题组。
|
||||
|
||||
核心成员
|
||||
-------------------------------
|
||||
@ -88,6 +90,7 @@ LCTT 的组成
|
||||
- 核心成员 @ucasFL,
|
||||
- 核心成员 @rusking,
|
||||
- 核心成员 @qhwdw,
|
||||
- 核心成员 @lujun9972
|
||||
- 前任选题 @DeadFire,
|
||||
- 前任校对 @reinoir222,
|
||||
- 前任校对 @PurlingNayuki,
|
||||
|
@ -0,0 +1,231 @@
|
||||
在不重启的情况下为 Vmware Linux 客户机添加新硬盘
|
||||
======
|
||||
|
||||
作为一名系统管理员,我经常需要用额外的硬盘来扩充存储空间或将系统数据从用户数据中分离出来。我将告诉你在将物理块设备加到虚拟主机的这个过程中,如何将一个主机上的硬盘加到一台使用 VMWare 软件虚拟化的 Linux 客户机上。
|
||||
|
||||
你可以显式的添加或删除一个 SCSI 设备,或者重新扫描整个 SCSI 总线而不用重启 Linux 虚拟机。本指南在 Vmware Server 和 Vmware Workstation v6.0 中通过测试(更老版本应该也支持)。所有命令在 RHEL、Fedora、CentOS 和 Ubuntu Linux 客户机 / 主机操作系统下都经过了测试。
|
||||
|
||||
### 步骤 1:添加新硬盘到虚拟客户机
|
||||
|
||||
首先,通过 vmware 硬件设置菜单添加硬盘。点击 “VM > Settings”
|
||||
|
||||
![Fig.01:Vmware Virtual Machine Settings ][1]
|
||||
|
||||
或者你也可以按下 `CTRL + D` 也能进入设置对话框。
|
||||
|
||||
点击 “Add” 添加新硬盘到客户机:
|
||||
|
||||
![Fig.02:VMWare adding a new hardware][2]
|
||||
|
||||
选择硬件类型为“Hard disk”然后点击 “Next”:
|
||||
|
||||
![Fig.03 VMware Adding a new disk wizard ][3]
|
||||
|
||||
选择 “create a new virtual disk” 然后点击 “Next”:
|
||||
|
||||
![Fig.04:Vmware Wizard Disk ][4]
|
||||
|
||||
设置虚拟磁盘类型为 “SCSI” ,然后点击 “Next”:
|
||||
|
||||
![Fig.05:Vmware Virtual Disk][5]
|
||||
|
||||
按需要设置最大磁盘大小,然后点击 “Next”
|
||||
|
||||
![Fig.06:Finalizing Disk Virtual Addition ][6]
|
||||
|
||||
最后,选择文件存放位置然后点击 “Finish”。
|
||||
|
||||
### 步骤 2:重新扫描 SCSI 总线,在不重启虚拟机的情况下添加 SCSI 设备
|
||||
|
||||
输入下面命令重新扫描 SCSI 总线:
|
||||
|
||||
```
|
||||
echo "- - -" > /sys/class/scsi_host/host# /scan
|
||||
fdisk -l
|
||||
tail -f /var/log/message
|
||||
```
|
||||
|
||||
输出为:
|
||||
|
||||
![Linux Vmware Rescan New Scsi Disk Without Reboot][7]
|
||||
|
||||
你需要将 `host#` 替换成真实的值,比如 `host0`。你可以通过下面命令来查出这个值:
|
||||
|
||||
`# ls /sys/class/scsi_host`
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
host0
|
||||
```
|
||||
|
||||
然后输入下面过命令来请求重新扫描:
|
||||
|
||||
```
|
||||
echo "- - -" > /sys/class/scsi_host/host0/scan
|
||||
fdisk -l
|
||||
tail -f /var/log/message
|
||||
```
|
||||
|
||||
输出为:
|
||||
|
||||
```
|
||||
Jul 18 16:29:39 localhost kernel: Vendor: VMware, Model: VMware Virtual S Rev: 1.0
|
||||
Jul 18 16:29:39 localhost kernel: Type: Direct-Access ANSI SCSI revision: 02
|
||||
Jul 18 16:29:39 localhost kernel: target0:0:1: Beginning Domain Validation
|
||||
Jul 18 16:29:39 localhost kernel: target0:0:1: Domain Validation skipping write tests
|
||||
Jul 18 16:29:39 localhost kernel: target0:0:1: Ending Domain Validation
|
||||
Jul 18 16:29:39 localhost kernel: target0:0:1: FAST-40 WIDE SCSI 80.0 MB/s ST (25 ns, offset 127)
|
||||
Jul 18 16:29:39 localhost kernel: SCSI device sdb: 2097152 512-byte hdwr sectors (1074 MB)
|
||||
Jul 18 16:29:39 localhost kernel: sdb: Write Protect is off
|
||||
Jul 18 16:29:39 localhost kernel: sdb: cache data unavailable
|
||||
Jul 18 16:29:39 localhost kernel: sdb: assuming drive cache: write through
|
||||
Jul 18 16:29:39 localhost kernel: SCSI device sdb: 2097152 512-byte hdwr sectors (1074 MB)
|
||||
Jul 18 16:29:39 localhost kernel: sdb: Write Protect is off
|
||||
Jul 18 16:29:39 localhost kernel: sdb: cache data unavailable
|
||||
Jul 18 16:29:39 localhost kernel: sdb: assuming drive cache: write through
|
||||
Jul 18 16:29:39 localhost kernel: sdb: unknown partition table
|
||||
Jul 18 16:29:39 localhost kernel: sd 0:0:1:0: Attached scsi disk sdb
|
||||
Jul 18 16:29:39 localhost kernel: sd 0:0:1:0: Attached scsi generic sg1 type 0
|
||||
Jul 18 16:29:39 localhost kernel: Vendor: VMware, Model: VMware Virtual S Rev: 1.0
|
||||
Jul 18 16:29:39 localhost kernel: Type: Direct-Access ANSI SCSI revision: 02
|
||||
Jul 18 16:29:39 localhost kernel: target0:0:2: Beginning Domain Validation
|
||||
Jul 18 16:29:39 localhost kernel: target0:0:2: Domain Validation skipping write tests
|
||||
Jul 18 16:29:39 localhost kernel: target0:0:2: Ending Domain Validation
|
||||
Jul 18 16:29:39 localhost kernel: target0:0:2: FAST-40 WIDE SCSI 80.0 MB/s ST (25 ns, offset 127)
|
||||
Jul 18 16:29:39 localhost kernel: SCSI device sdc: 2097152 512-byte hdwr sectors (1074 MB)
|
||||
Jul 18 16:29:39 localhost kernel: sdc: Write Protect is off
|
||||
Jul 18 16:29:39 localhost kernel: sdc: cache data unavailable
|
||||
Jul 18 16:29:39 localhost kernel: sdc: assuming drive cache: write through
|
||||
Jul 18 16:29:39 localhost kernel: SCSI device sdc: 2097152 512-byte hdwr sectors (1074 MB)
|
||||
Jul 18 16:29:39 localhost kernel: sdc: Write Protect is off
|
||||
Jul 18 16:29:39 localhost kernel: sdc: cache data unavailable
|
||||
Jul 18 16:29:39 localhost kernel: sdc: assuming drive cache: write through
|
||||
Jul 18 16:29:39 localhost kernel: sdc: unknown partition table
|
||||
Jul 18 16:29:39 localhost kernel: sd 0:0:2:0: Attached scsi disk sdc
|
||||
Jul 18 16:29:39 localhost kernel: sd 0:0:2:0: Attached scsi generic sg2 type 0
|
||||
```
|
||||
|
||||
#### 如何删除 /dev/sdc 这块设备?
|
||||
|
||||
除了重新扫描整个总线外,你也可以使用下面命令添加或删除指定磁盘:
|
||||
|
||||
```
|
||||
# echo 1 > /sys/block/devName/device/delete
|
||||
# echo 1 > /sys/block/sdc/device/delete
|
||||
```
|
||||
|
||||
#### 如何添加 /dev/sdc 这块设备?
|
||||
|
||||
使用下面语法添加指定设备:
|
||||
|
||||
```
|
||||
# echo "scsi add-single-device <H> <B> <T> <L>" > /proc/scsi/scsi
|
||||
```
|
||||
|
||||
这里,
|
||||
|
||||
* <H>:主机
|
||||
* <B>:总线(通道)
|
||||
* <T>:目标 (Id)
|
||||
* <L>:LUN 号
|
||||
|
||||
例如。使用参数 `host#0`,`bus#0`,`target#2`,以及 `LUN#0` 来添加 `/dev/sdc`,则输入:
|
||||
|
||||
```
|
||||
# echo "scsi add-single-device 0 0 2 0">/proc/scsi/scsi
|
||||
# fdisk -l
|
||||
# cat /proc/scsi/scsi
|
||||
```
|
||||
|
||||
结果输出:
|
||||
|
||||
```
|
||||
Attached devices:
|
||||
Host: scsi0 Channel: 00 Id: 00 Lun: 00
|
||||
Vendor: VMware, Model: VMware Virtual S Rev: 1.0
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Host: scsi0 Channel: 00 Id: 01 Lun: 00
|
||||
Vendor: VMware, Model: VMware Virtual S Rev: 1.0
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Host: scsi0 Channel: 00 Id: 02 Lun: 00
|
||||
Vendor: VMware, Model: VMware Virtual S Rev: 1.0
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
```
|
||||
|
||||
### 步骤 #3:格式化新磁盘
|
||||
|
||||
现在使用 [fdisk 并通过 mkfs.ext3][8] 命令创建分区:
|
||||
|
||||
```
|
||||
# fdisk /dev/sdc
|
||||
### [if you want ext3 fs] ###
|
||||
# mkfs.ext3 /dev/sdc3
|
||||
### [if you want ext4 fs] ###
|
||||
# mkfs.ext4 /dev/sdc3
|
||||
```
|
||||
|
||||
### 步骤 #4:创建挂载点并更新 /etc/fstab
|
||||
|
||||
```
|
||||
# mkdir /disk3
|
||||
```
|
||||
|
||||
打开 `/etc/fstab` 文件,输入:
|
||||
|
||||
```
|
||||
# vi /etc/fstab
|
||||
```
|
||||
|
||||
加入下面这行:
|
||||
|
||||
```
|
||||
/dev/sdc3 /disk3 ext3 defaults 1 2
|
||||
```
|
||||
|
||||
若是 ext4 文件系统则加入:
|
||||
|
||||
```
|
||||
/dev/sdc3 /disk3 ext4 defaults 1 2
|
||||
```
|
||||
|
||||
保存并关闭文件。
|
||||
|
||||
#### 可选操作:为分区加标签
|
||||
|
||||
[你可以使用 e2label 命令为分区加标签 ][9]。假设,你想要为 `/backupDisk` 这块新分区加标签,则输入:
|
||||
|
||||
```
|
||||
# e2label /dev/sdc1 /backupDisk
|
||||
```
|
||||
|
||||
详情参见 "[Linux 分区的重要性 ][10]。
|
||||
|
||||
### 关于作者
|
||||
|
||||
作者是 nixCraft 的创始人,也是一名经验丰富的系统管理员,还是 Linux 操作系统 /Unix shell 脚本培训师。他曾服务过全球客户并与多个行业合作过,包括 IT,教育,国防和空间研究,以及非盈利机构。你可以在 [Twitter][11],[Facebook][12],[Google+][13] 上关注他。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.cyberciti.biz/tips/vmware-add-a-new-hard-disk-without-rebooting-guest.html
|
||||
|
||||
作者:[Vivek Gite][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.cyberciti.biz
|
||||
[1]:https://www.cyberciti.biz/media/new/tips/2009/07/virtual-machine-settings-1.png (Vmware Virtual Machine Settings )
|
||||
[2]:https://www.cyberciti.biz/media/new/tips/2009/07/vmware-add-hardware-wizard-2.png (VMWare adding a new hardware)
|
||||
[3]:https://www.cyberciti.biz/media/new/tips/2009/07/vmware-add-hardware-anew-disk-3.png (VMware Adding a new disk wizard )
|
||||
[4]:https://www.cyberciti.biz/media/new/tips/2009/07/vmware-add-hardware-4.png (Vmware Wizard Disk )
|
||||
[5]:https://www.cyberciti.biz/media/new/tips/2009/07/add-hardware-5.png (Vmware Virtual Disk)
|
||||
[6]:https://www.cyberciti.biz/media/new/tips/2009/07/vmware-final-disk-file-add-hdd-6.png (Finalizing Disk Virtual Addition)
|
||||
[7]:https://www.cyberciti.biz/media/new/tips/2009/07/vmware-linux-rescan-hard-disk.png (Linux Vmware Rescan New Scsi Disk Without Reboot)
|
||||
[8]:https://www.cyberciti.biz/faq/linux-disk-format/
|
||||
[9]:https://www.cyberciti.biz/faq/linux-modify-partition-labels-command-to-change-diskname/
|
||||
[10]:https://www.cyberciti.biz/faq/linux-partition-howto-set-labels/>how%20to%20label%20a%20Linux%20partition</a>%E2%80%9D%20for%20more%20info.</p><h2>Conclusion</h2><p>The%20VMware%20guest%20now%20has%20an%20additional%20virtualized%20storage%20device.%20%20The%20procedure%20works%20for%20all%20physical%20block%20devices,%20this%20includes%20CD-ROM,%20DVD%20and%20floppy%20devices.%20Next,%20time%20I%20will%20write%20about%20adding%20an%20additional%20virtualized%20storage%20device%20using%20XEN%20software.</p><h2>See%20also</h2><ul><li><a%20href=
|
||||
[11]:https://twitter.com/nixcraft
|
||||
[12]:https://facebook.com/nixcraft
|
||||
[13]:https://plus.google.com/+CybercitiBiz
|
@ -0,0 +1,176 @@
|
||||
如何让 curl 命令通过代理访问
|
||||
======
|
||||
|
||||
我的系统管理员给我提供了如下代理信息:
|
||||
|
||||
```
|
||||
IP: 202.54.1.1
|
||||
Port: 3128
|
||||
Username: foo
|
||||
Password: bar
|
||||
```
|
||||
|
||||
该设置在 Google Chrome 和 Firefox 浏览器上很容易设置。但是我要怎么把它应用到 `curl` 命令上呢?我要如何让 curl 命令使用我在 Google Chrome 浏览器上的代理设置呢?
|
||||
|
||||
很多 Linux 和 Unix 命令行工具(比如 `curl` 命令,`wget` 命令,`lynx` 命令等)使用名为 `http_proxy`,`https_proxy`,`ftp_proxy` 的环境变量来获取代理信息。它允许你通过代理服务器(使用或不使用用户名/密码都行)来连接那些基于文本的会话和应用。
|
||||
|
||||
本文就会演示一下如何让 `curl` 通过代理服务器发送 HTTP/HTTPS 请求。
|
||||
|
||||
### 让 curl 命令使用代理的语法
|
||||
|
||||
语法为:
|
||||
|
||||
```
|
||||
## Set the proxy address of your uni/company/vpn network ##
|
||||
export http_proxy=http://your-ip-address:port/
|
||||
|
||||
## http_proxy with username and password
|
||||
export http_proxy=http://user:password@your-proxy-ip-address:port/
|
||||
|
||||
## HTTPS version ##
|
||||
export https_proxy=https://your-ip-address:port/
|
||||
export https_proxy=https://user:password@your-proxy-ip-address:port/
|
||||
```
|
||||
|
||||
另一种方法是使用 `curl` 命令的 `-x` 选项:
|
||||
|
||||
```
|
||||
curl -x <[protocol://][user:password@]proxyhost[:port]> url
|
||||
--proxy <[protocol://][user:password@]proxyhost[:port]> url
|
||||
--proxy http://user:password@Your-Ip-Here:Port url
|
||||
-x http://user:password@Your-Ip-Here:Port url
|
||||
```
|
||||
|
||||
### 在 Linux 上的一个例子
|
||||
|
||||
首先设置 `http_proxy`:
|
||||
|
||||
```
|
||||
## proxy server, 202.54.1.1, port: 3128, user: foo, password: bar ##
|
||||
export http_proxy=http://foo:bar@202.54.1.1:3128/
|
||||
export https_proxy=$http_proxy
|
||||
## Use the curl command ##
|
||||
curl -I https://www.cyberciti.biz
|
||||
curl -v -I https://www.cyberciti.biz
|
||||
```
|
||||
|
||||
输出为:
|
||||
|
||||
```
|
||||
* Rebuilt URL to: www.cyberciti.biz/
|
||||
* Trying 202.54.1.1...
|
||||
* Connected to 1202.54.1.1 (202.54.1.1) port 3128 (#0)
|
||||
* Proxy auth using Basic with user 'foo'
|
||||
> HEAD HTTP://www.cyberciti.biz/ HTTP/1.1
|
||||
> Host: www.cyberciti.biz
|
||||
> Proxy-Authorization: Basic x9VuUml2xm0vdg93MtIz
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: */*
|
||||
> Proxy-Connection: Keep-Alive
|
||||
>
|
||||
< HTTP/1.1 200 OK
|
||||
HTTP/1.1 200 OK
|
||||
< Server: nginx
|
||||
Server: nginx
|
||||
< Date: Sun, 17 Jan 2016 11:49:21 GMT
|
||||
Date: Sun, 17 Jan 2016 11:49:21 GMT
|
||||
< Content-Type: text/html; charset=UTF-8
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
< Vary: Accept-Encoding
|
||||
Vary: Accept-Encoding
|
||||
< X-Whom: Dyno-l1-com-cyber
|
||||
X-Whom: Dyno-l1-com-cyber
|
||||
< Vary: Cookie
|
||||
Vary: Cookie
|
||||
< Link: <http://www.cyberciti.biz/wp-json/>; rel="https://api.w.org/"
|
||||
Link: <http://www.cyberciti.biz/wp-json/>; rel="https://api.w.org/"
|
||||
< X-Frame-Options: SAMEORIGIN
|
||||
X-Frame-Options: SAMEORIGIN
|
||||
< X-Content-Type-Options: nosniff
|
||||
X-Content-Type-Options: nosniff
|
||||
< X-XSS-Protection: 1; mode=block
|
||||
X-XSS-Protection: 1; mode=block
|
||||
< X-Cache: MISS from server1
|
||||
X-Cache: MISS from server1
|
||||
< X-Cache-Lookup: MISS from server1:3128
|
||||
X-Cache-Lookup: MISS from server1:3128
|
||||
< Connection: keep-alive
|
||||
Connection: keep-alive
|
||||
|
||||
<
|
||||
* Connection #0 to host 10.12.249.194 left intact
|
||||
```
|
||||
|
||||
本例中,我来下载一个 pdf 文件:
|
||||
|
||||
```
|
||||
$ export http_proxy="vivek:myPasswordHere@10.12.249.194:3128/"
|
||||
$ curl -v -O http://dl.cyberciti.biz/pdfdownloads/b8bf71be9da19d3feeee27a0a6960cb3/569b7f08/cms/631.pdf
|
||||
```
|
||||
|
||||
也可以使用 `-x` 选项:
|
||||
|
||||
```
|
||||
curl -x 'http://vivek:myPasswordHere@10.12.249.194:3128' -v -O https://dl.cyberciti.biz/pdfdownloads/b8bf71be9da19d3feeee27a0a6960cb3/569b7f08/cms/631.pdf
|
||||
```
|
||||
|
||||
输出为:
|
||||
|
||||
![Fig.01:curl in action \(click to enlarge\)][2]
|
||||
|
||||
### Unix 上的一个例子
|
||||
|
||||
```
|
||||
$ curl -x http://prox_server_vpn:3128/ -I https://www.cyberciti.biz/faq/howto-nginx-customizing-404-403-error-page/
|
||||
```
|
||||
|
||||
### socks 协议怎么办呢?
|
||||
|
||||
语法也是一样的:
|
||||
|
||||
```
|
||||
curl -x socks5://[user:password@]proxyhost[:port]/ url
|
||||
curl --socks5 192.168.1.254:3099 https://www.cyberciti.biz/
|
||||
```
|
||||
|
||||
### 如何让代理设置永久生效?
|
||||
|
||||
编辑 `~/.curlrc` 文件:
|
||||
|
||||
```
|
||||
$ vi ~/.curlrc
|
||||
```
|
||||
|
||||
添加下面内容:
|
||||
|
||||
```
|
||||
proxy = server1.cyberciti.biz:3128
|
||||
proxy-user = "foo:bar"
|
||||
```
|
||||
|
||||
保存并关闭该文件。另一种方法是在你的 `~/.bashrc` 文件中创建一个别名:
|
||||
|
||||
```
|
||||
## alias for curl command
|
||||
## set proxy-server and port, the syntax is
|
||||
## alias curl="curl -x {your_proxy_host}:{proxy_port}"
|
||||
alias curl = "curl -x server1.cyberciti.biz:3128"
|
||||
```
|
||||
|
||||
记住,代理字符串中可以使用 `protocol://` 前缀来指定不同的代理协议。使用 `socks4://`,`socks4a://`,`socks5:// `或者 `socks5h://` 来指定使用的 SOCKS 版本。若没有指定协议或者使用 `http://` 表示 HTTP 协议。若没有指定端口号则默认为 `1080`。`-x` 选项的值要优先于环境变量设置的值。若不想走代理,而环境变量总设置了代理,那么可以通过设置代理为空值(`""`)来覆盖环境变量的值。[详细信息请参阅 `curl` 的 man 页 ][3]。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.cyberciti.biz/faq/linux-unix-curl-command-with-proxy-username-password-http-options/
|
||||
|
||||
作者:[Vivek Gite][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.cyberciti.biz
|
||||
[1]:https://www.cyberciti.biz/media/new/faq/2016/01/curl-download-output-300x141.jpg
|
||||
[2]:https://www.cyberciti.biz/media/new/faq/2016/01/curl-download-output.jpg
|
||||
[3]:https://curl.haxx.se/docs/manpage.html
|
64
published/20170131 Book review Ours to Hack and to Own.md
Normal file
64
published/20170131 Book review Ours to Hack and to Own.md
Normal file
@ -0,0 +1,64 @@
|
||||
书评:《Ours to Hack and to Own》
|
||||
============================================================
|
||||
|
||||
![书评: Ours to Hack and to Own](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/EDUCATION_colorbooks.png?itok=vNhsYYyC "Book review: Ours to Hack and to Own")
|
||||
|
||||
Image by : opensource.com
|
||||
|
||||
私有制的时代看起来似乎结束了,在这里我将不仅仅讨论那些由我们中的许多人引入到我们的家庭与生活的设备和软件,我也将讨论这些设备与应用依赖的平台与服务。
|
||||
|
||||
尽管我们使用的许多服务是免费的,但我们对它们并没有任何控制权。本质上讲,这些企业确实控制着我们所看到的、听到的以及阅读到的内容。不仅如此,许多企业还在改变工作的本质。他们正使用封闭的平台来助长由全职工作到[零工经济][2]的转变,这种方式提供极少的安全性与确定性。
|
||||
|
||||
这项行动对于网络以及每一个使用与依赖网络的人产生了广泛的影响。仅仅二十多年前的对开放互联网的想象正在逐渐消逝,并迅速地被一块难以穿透的幕帘所取代。
|
||||
|
||||
一种逐渐流行的补救办法就是建立<ruby>[平台合作社][3]<rt>platform cooperatives</rt></ruby>, 即由他们的用户所拥有的电子化平台。正如这本书[《Ours to Hack and to Own》][4]所阐述的,平台合作社背后的观点与开源有许多相同的根源。
|
||||
|
||||
学者 Trebor Scholz 和作家 Nathan Schneider 已经收集了 40 篇论文,探讨平台合作社作为普通人可使用的工具的增长及需求,以提升开放性并对闭源系统的不透明性及各种限制予以还击。
|
||||
|
||||
### 何处适合开源
|
||||
|
||||
任何平台合作社核心及接近核心的部分依赖于开源;不仅开源技术是必要的,构成开源开放性、透明性、协同合作以及共享的准则与理念同样不可或缺。
|
||||
|
||||
在这本书的介绍中,Trebor Scholz 指出:
|
||||
|
||||
> 与斯诺登时代的互联网黑盒子系统相反,这些平台需要使它们的数据流透明来辨别自身。他们需要展示客户与员工的数据在哪里存储,数据出售给了谁以及数据用于何种目的。
|
||||
|
||||
正是对开源如此重要的透明性,促使平台合作社如此吸引人,并在目前大量已有平台之中成为令人耳目一新的变化。
|
||||
|
||||
开源软件在《Ours to Hack and to Own》所分享的平台合作社的构想中必然充当着重要角色。开源软件能够为群体建立助推合作社的技术基础设施提供快速而不算昂贵的途径。
|
||||
|
||||
Mickey Metts 在论文中这样形容, “邂逅你的友邻技术伙伴。" Metts 为一家名为 Agaric 的企业工作,这家企业使用 Drupal 为团体及小型企业建立他们不能自行完成的平台。除此以外, Metts 还鼓励任何想要建立并运营自己的企业的公司或合作社的人接受自由开源软件。为什么呢?因为它是高质量的、并不昂贵的、可定制的,并且你能够与由乐于助人而又热情的人们组成的大型社区产生联系。
|
||||
|
||||
### 不总是开源的,但开源总在
|
||||
|
||||
这本书里不是所有的论文都关注或提及开源的;但是,开源方式的关键元素——合作、社区、开放治理以及电子自由化——总是在其间若隐若现。
|
||||
|
||||
事实上正如《Ours to Hack and to Own》中许多论文所讨论的,建立一个更加开放、基于平常人的经济与社会区块,平台合作社会变得非常重要。用 Douglas Rushkoff 的话讲,那会是类似 Creative Commons 的组织“对共享知识资源的私有化”的补偿。它们也如 Barcelona 的 CTO Francesca Bria 所描述的那样,是“通过确保市民数据安全性、隐私性和权利的系统”来运营他们自己的“分布式通用数据基础架构”的城市。
|
||||
|
||||
### 最后的思考
|
||||
|
||||
如果你在寻找改变互联网以及我们工作的方式的蓝图,《Ours to Hack and to Own》并不是你要寻找的。这本书与其说是用户指南,不如说是一种宣言。如书中所说,《Ours to Hack and to Own》让我们略微了解如果我们将开源方式准则应用于社会及更加广泛的世界我们能够做的事。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
作者简介:
|
||||
|
||||
Scott Nesbitt ——作家、编辑、雇佣兵、 <ruby>虎猫牛仔<rt>Ocelot wrangle</rt></ruby>、丈夫与父亲、博客写手、陶器收藏家。Scott 正是做这样的一些事情。他还是大量写关于开源软件文章与博客的长期开源用户。你可以在 Twitter、Github 上找到他。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/17/1/review-book-ours-to-hack-and-own
|
||||
|
||||
作者:[Scott Nesbitt][a]
|
||||
译者:[darsh8](https://github.com/darsh8)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/scottnesbitt
|
||||
[1]:https://opensource.com/article/17/1/review-book-ours-to-hack-and-own?rate=dgkFEuCLLeutLMH2N_4TmUupAJDjgNvFpqWqYCbQb-8
|
||||
[2]:https://en.wikipedia.org/wiki/Access_economy
|
||||
[3]:https://en.wikipedia.org/wiki/Platform_cooperative
|
||||
[4]:http://www.orbooks.com/catalog/ours-to-hack-and-to-own/
|
||||
[5]:https://opensource.com/user/14925/feed
|
||||
[6]:https://opensource.com/users/scottnesbitt
|
99
published/20170209 INTRODUCING DOCKER SECRETS MANAGEMENT.md
Normal file
99
published/20170209 INTRODUCING DOCKER SECRETS MANAGEMENT.md
Normal file
@ -0,0 +1,99 @@
|
||||
Docker 涉密信息管理介绍
|
||||
====================================
|
||||
|
||||
容器正在改变我们对应用程序和基础设施的看法。无论容器内的代码量是大还是小,容器架构都会引起代码如何与硬件相互作用方式的改变 —— 它从根本上将其从基础设施中抽象出来。对于容器安全来说,在 Docker 中,容器的安全性有三个关键组成部分,它们相互作用构成本质上更安全的应用程序。
|
||||
|
||||
![Docker Security](https://i2.wp.com/blog.docker.com/wp-content/uploads/e12387a1-ab21-4942-8760-5b1677bc656d-1.jpg?w=1140&ssl=1)
|
||||
|
||||
构建更安全的应用程序的一个关键因素是与系统和其他应用程序进行安全通信,这通常需要证书、令牌、密码和其他类型的验证信息凭证 —— 通常称为应用程序<ruby>涉密信息<rt>secrets</rt></ruby>。我们很高兴可以推出 Docker Secrets,这是一个容器原生的解决方案,它是加强容器安全的<ruby>可信赖交付<rt>Trusted Delivery</rt></ruby>组件,用户可以在容器平台上直接集成涉密信息分发功能。
|
||||
|
||||
有了容器,现在应用程序是动态的,可以跨越多种环境移植。这使得现存的涉密信息分发的解决方案略显不足,因为它们都是针对静态环境。不幸的是,这导致了应用程序涉密信息管理不善的增加,在不安全的、土造的方案中(如将涉密信息嵌入到 GitHub 这样的版本控制系统或者同样糟糕的其它方案),这种情况十分常见。
|
||||
|
||||
### Docker 涉密信息管理介绍
|
||||
|
||||
根本上我们认为,如果有一个标准的接口来访问涉密信息,应用程序就更安全了。任何好的解决方案也必须遵循安全性实践,例如在传输的过程中,对涉密信息进行加密;在不用的时候也对涉密数据进行加密;防止涉密信息在应用最终使用时被无意泄露;并严格遵守最低权限原则,即应用程序只能访问所需的涉密信息,不能多也不能不少。
|
||||
|
||||
通过将涉密信息整合到 Docker 编排,我们能够在遵循这些确切的原则下为涉密信息的管理问题提供一种解决方案。
|
||||
|
||||
下图提供了一个高层次视图,并展示了 Docker swarm 模式体系架构是如何将一种新类型的对象 —— 一个涉密信息对象,安全地传递给我们的容器。
|
||||
|
||||
![Docker Secrets Management](https://i0.wp.com/blog.docker.com/wp-content/uploads/b69d2410-9e25-44d8-aa2d-f67b795ff5e3.jpg?w=1140&ssl=1)
|
||||
|
||||
在 Docker 中,涉密信息是任意的数据块,比如密码、SSH 密钥、TLS 凭证,或者任何其他本质上敏感的数据。当你将一个涉密信息加入 swarm 集群(通过执行 `docker secret create` )时,利用在引导新集群时自动创建的[内置证书颁发机构][17],Docker 通过相互认证的 TLS 连接将密钥发送给 swarm 集群管理器。
|
||||
|
||||
```
|
||||
$ echo "This is a secret" | docker secret create my_secret_data -
|
||||
```
|
||||
|
||||
一旦,涉密信息到达某个管理节点,它将被保存到内部的 Raft 存储区中。该存储区使用 NACL 开源加密库中的 Salsa20、Poly1305 加密算法生成的 256 位密钥进行加密,以确保从来不会把任何涉密信息数据写入未加密的磁盘。将涉密信息写入到内部存储,赋予了涉密信息跟其它 swarm 集群数据一样的高可用性。
|
||||
|
||||
当 swarm 集群管理器启动时,包含涉密信息的加密 Raft 日志通过每一个节点独有的数据密钥进行解密。此密钥以及用于与集群其余部分通信的节点 TLS 证书可以使用一个集群级的加密密钥进行加密。该密钥称为“解锁密钥”,也使用 Raft 进行传递,将且会在管理器启动的时候使用。
|
||||
|
||||
当授予新创建或运行的服务权限访问某个涉密信息权限时,其中一个管理器节点(只有管理器可以访问被存储的所有涉密信息)会通过已经建立的 TLS 连接将其分发给正在运行特定服务的节点。这意味着节点自己不能请求涉密信息,并且只有在管理器提供给他们的时候才能访问这些涉密信息 —— 严格地控制请求涉密信息的服务。
|
||||
|
||||
```
|
||||
$ docker service create --name="redis" --secret="my_secret_data" redis:alpine
|
||||
```
|
||||
|
||||
未加密的涉密信息被挂载到一个容器,该容器位于 `/run/secrets/<secret_name>` 的内存文件系统中。
|
||||
|
||||
```
|
||||
$ docker exec $(docker ps --filter name=redis -q) ls -l /run/secrets
|
||||
total 4
|
||||
-r--r--r-- 1 root root 17 Dec 13 22:48 my_secret_data
|
||||
```
|
||||
|
||||
如果一个服务被删除或者被重新安排在其他地方,集群管理器将立即通知所有不再需要访问该涉密信息的节点,这些节点将不再有权访问该应用程序的涉密信息。
|
||||
|
||||
```
|
||||
$ docker service update --secret-rm="my_secret_data" redis
|
||||
|
||||
$ docker exec -it $(docker ps --filter name=redis -q) cat /run/secrets/my_secret_data
|
||||
|
||||
cat: can't open '/run/secrets/my_secret_data': No such file or directory
|
||||
```
|
||||
|
||||
查看 [Docker Secret 文档][18]以获取更多信息和示例,了解如何创建和管理您的涉密信息。同时,特别感谢 [Laurens Van Houtven](https://www.lvh.io/) 与 Docker 安全和核心团队合作使这一特性成为现实。
|
||||
|
||||
### 通过 Docker 更安全地使用应用程序
|
||||
|
||||
Docker 涉密信息旨在让开发人员和 IT 运营团队可以轻松使用,以用于构建和运行更安全的应用程序。它是首个被设计为既能保持涉密信息安全,并且仅在特定的容器需要它来进行必要的涉密信息操作的时候使用。从使用 Docker Compose 定义应用程序和涉密数据,到 IT 管理人员直接在 Docker Datacenter 中部署的 Compose 文件,涉密信息、网络和数据卷都将加密并安全地与应用程序一起传输。
|
||||
|
||||
更多相关学习资源:
|
||||
|
||||
* [1.13 Docker 数据中心具有 Secrets、安全扫描、容量缓存等新特性][7]
|
||||
* [下载 Docker][8] 且开始学习
|
||||
* [在 Docker 数据中心尝试使用 secrets][9]
|
||||
* [阅读文档][10]
|
||||
* 参与 [即将进行的在线研讨会][11]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://blog.docker.com/2017/02/docker-secrets-management/
|
||||
|
||||
作者:[Ying Li][a]
|
||||
译者:[HardworkFish](https://github.com/HardworkFish)
|
||||
校对:[imquanquan](https://github.com/imquanquan), [wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://blog.docker.com/author/yingli/
|
||||
[1]:http://www.linkedin.com/shareArticle?mini=true&url=http://dockr.ly/2k6gnOB&title=Introducing%20Docker%20Secrets%20Management&summary=Containers%20are%20changing%20how%20we%20view%20apps%20and%20infrastructure.%20Whether%20the%20code%20inside%20containers%20is%20big%20or%20small,%20container%20architecture%20introduces%20a%20change%20to%20how%20that%20code%20behaves%20with%20hardware%20-%20it%20fundamentally%20abstracts%20it%20from%20the%20infrastructure.%20Docker%20believes%20that%20there%20are%20three%20key%20components%20to%20container%20security%20and%20...
|
||||
[2]:http://www.reddit.com/submit?url=http://dockr.ly/2k6gnOB&title=Introducing%20Docker%20Secrets%20Management
|
||||
[3]:https://plus.google.com/share?url=http://dockr.ly/2k6gnOB
|
||||
[4]:http://news.ycombinator.com/submitlink?u=http://dockr.ly/2k6gnOB&t=Introducing%20Docker%20Secrets%20Management
|
||||
[5]:https://twitter.com/share?text=Get+safer+apps+for+dev+and+ops+w%2F+new+%23Docker+secrets+management+&via=docker&related=docker&url=http://dockr.ly/2k6gnOB
|
||||
[6]:https://twitter.com/share?text=Get+safer+apps+for+dev+and+ops+w%2F+new+%23Docker+secrets+management+&via=docker&related=docker&url=http://dockr.ly/2k6gnOB
|
||||
[7]:http://dockr.ly/AppSecurity
|
||||
[8]:https://www.docker.com/getdocker
|
||||
[9]:http://www.docker.com/trial
|
||||
[10]:https://docs.docker.com/engine/swarm/secrets/
|
||||
[11]:http://www.docker.com/webinars
|
||||
[12]:https://blog.docker.com/author/yingli/
|
||||
[13]:https://blog.docker.com/tag/container-security/
|
||||
[14]:https://blog.docker.com/tag/docker-security/
|
||||
[15]:https://blog.docker.com/tag/secrets-management/
|
||||
[16]:https://blog.docker.com/tag/security/
|
||||
[17]:https://docs.docker.com/engine/swarm/how-swarm-mode-works/pki/
|
||||
[18]:https://docs.docker.com/engine/swarm/secrets/
|
||||
[19]:https://lvh.io%29/
|
185
published/20170426 Important Docker commands for Beginners.md
Normal file
185
published/20170426 Important Docker commands for Beginners.md
Normal file
@ -0,0 +1,185 @@
|
||||
为小白准备的重要 Docker 命令说明
|
||||
======
|
||||
|
||||
在早先的教程中,我们学过了[在 RHEL CentOS 7 上安装 Docker 并创建 docker 容器][1]。 在本教程中,我们会学习管理 docker 容器的其他命令。
|
||||
|
||||
### Docker 命令语法
|
||||
|
||||
```
|
||||
$ docker [option] [command] [arguments]
|
||||
```
|
||||
|
||||
要列出 docker 支持的所有命令,运行
|
||||
|
||||
```
|
||||
$ docker
|
||||
```
|
||||
|
||||
我们会看到如下结果,
|
||||
|
||||
```
|
||||
attach Attach to a running container
|
||||
build Build an image from a Dockerfile
|
||||
commit Create a new image from a container's changes
|
||||
cp Copy files/folders between a container and the local filesystem
|
||||
create Create a new container
|
||||
diff Inspect changes on a container's filesystem
|
||||
events Get real time events from the server
|
||||
exec Run a command in a running container
|
||||
export Export a container's filesystem as a tar archive
|
||||
history Show the history of an image
|
||||
images List images
|
||||
import Import the contents from a tarball to create a filesystem image
|
||||
info Display system-wide information
|
||||
inspect Return low-level information on a container or image
|
||||
kill Kill a running container
|
||||
load Load an image from a tar archive or STDIN
|
||||
login Log in to a Docker registry
|
||||
logout Log out from a Docker registry
|
||||
logs Fetch the logs of a container
|
||||
network Manage Docker networks
|
||||
pause Pause all processes within a container
|
||||
port List port mappings or a specific mapping for the CONTAINER
|
||||
ps List containers
|
||||
pull Pull an image or a repository from a registry
|
||||
push Push an image or a repository to a registry
|
||||
rename Rename a container
|
||||
restart Restart a container
|
||||
rm Remove one or more containers
|
||||
rmi Remove one or more images
|
||||
run Run a command in a new container
|
||||
save Save one or more images to a tar archive
|
||||
search Search the Docker Hub for images
|
||||
start Start one or more stopped containers
|
||||
stats Display a live stream of container(s) resource usage statistics
|
||||
stop Stop a running container
|
||||
tag Tag an image into a repository
|
||||
top Display the running processes of a container
|
||||
unpause Unpause all processes within a container
|
||||
update Update configuration of one or more containers
|
||||
version Show the Docker version information
|
||||
volume Manage Docker volumes
|
||||
wait Block until a container stops, then print its exit code
|
||||
```
|
||||
|
||||
要进一步查看某个命令支持的选项,运行:
|
||||
|
||||
```
|
||||
$ docker docker-subcommand info
|
||||
```
|
||||
|
||||
就会列出 docker 子命令所支持的选项了。
|
||||
|
||||
### 测试与 Docker Hub 的连接
|
||||
|
||||
默认,所有镜像都是从 Docker Hub 中拉取下来的。我们可以从 Docker Hub 上传或下载操作系统镜像。为了检查我们是否能够正常地通过 Docker Hub 上传/下载镜像,运行
|
||||
|
||||
```
|
||||
$ docker run hello-world
|
||||
```
|
||||
|
||||
结果应该是:
|
||||
|
||||
```
|
||||
Hello from Docker.
|
||||
This message shows that your installation appears to be working correctly.
|
||||
…
|
||||
```
|
||||
|
||||
输出结果表示你可以访问 Docker Hub 而且也能从 Docker Hub 下载 docker 镜像。
|
||||
|
||||
### 搜索镜像
|
||||
|
||||
搜索容器的镜像,运行
|
||||
|
||||
```
|
||||
$ docker search Ubuntu
|
||||
```
|
||||
|
||||
我们应该会得到可用的 Ubuntu 镜像的列表。记住,如果你想要的是官方的镜像,请检查 `official` 这一列上是否为 `[OK]`。
|
||||
|
||||
### 下载镜像
|
||||
|
||||
一旦搜索并找到了我们想要的镜像,我们可以运行下面语句来下载它:
|
||||
|
||||
```
|
||||
$ docker pull Ubuntu
|
||||
```
|
||||
|
||||
要查看所有已下载的镜像,运行:
|
||||
|
||||
```
|
||||
$ docker images
|
||||
```
|
||||
|
||||
### 运行容器
|
||||
|
||||
使用已下载镜像来运行容器,使用下面命令:
|
||||
|
||||
```
|
||||
$ docker run -it Ubuntu
|
||||
```
|
||||
|
||||
这里,使用 `-it` 会打开一个 shell 与容器交互。容器启动并运行后,我们就可以像普通机器那样来使用它了,我们可以在容器中执行任何命令。
|
||||
|
||||
### 显示所有的 docker 容器
|
||||
|
||||
要列出所有 docker 容器,运行:
|
||||
|
||||
```
|
||||
$ docker ps
|
||||
```
|
||||
|
||||
会输出一个容器列表,每个容器都有一个容器 id 标识。
|
||||
|
||||
### 停止 docker 容器
|
||||
|
||||
要停止 docker 容器,运行:
|
||||
|
||||
```
|
||||
$ docker stop container-id
|
||||
```
|
||||
|
||||
### 从容器中退出
|
||||
|
||||
要从容器中退出,执行:
|
||||
|
||||
```
|
||||
$ exit
|
||||
```
|
||||
|
||||
### 保存容器状态
|
||||
|
||||
容器运行并更改后(比如安装了 apache 服务器),我们可以保存容器状态。这会在本地系统上保存新创建镜像。
|
||||
|
||||
运行下面语句来提交并保存容器状态:
|
||||
|
||||
```
|
||||
$ docker commit 85475ef774 repository/image_name
|
||||
```
|
||||
|
||||
这里,`commit` 命令会保存容器状态,`85475ef774`,是容器的容器 id,`repository`,通常为 docker hub 上的用户名 (或者新加的仓库名称)`image_name`,是新镜像的名称。
|
||||
|
||||
我们还可以使用 `-m` 和 `-a` 来添加更多信息。通过 `-m`,我们可以留个信息说 apache 服务器已经安装好了,而 `-a` 可以添加作者名称。
|
||||
|
||||
像这样:
|
||||
|
||||
```
|
||||
docker commit -m "apache server installed"-a "Dan Daniels" 85475ef774 daniels_dan/Cent_container
|
||||
```
|
||||
|
||||
我们的教程至此就结束了,本教程讲解了一下 Docker 中的那些重要的命令,如有疑问,欢迎留言。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://linuxtechlab.com/important-docker-commands-beginners/
|
||||
|
||||
作者:[Shusain][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://linuxtechlab.com/author/shsuain/
|
||||
[1]:http://linuxtechlab.com/create-first-docker-container-beginners-guide/
|
@ -0,0 +1,153 @@
|
||||
哪一种 Ubuntu 官方版本最适合你?
|
||||
============================================================
|
||||
|
||||
![Ubuntu Budgie](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/ubuntu_budgie.jpg?itok=xpo3Ujfw "Ubuntu Budgie")
|
||||
|
||||
*Ubuntu Budgie 只是为数不多的 Ubuntu 官方认可的<ruby>特色版本<rt>flavor</rt></ruby>之一。Jack Wallen(杰克沃伦)将讲述一下它们之间的重要的区别。*
|
||||
|
||||
Ubuntu Linux 有一些官方认可的<ruby>特色版本<rt>flavor</rt></ruby>,还有一些<ruby>衍生版本<rt>derivative distribution</rt></ruby>:
|
||||
|
||||
* [Kubuntu][9] - KDE 桌面版 Ubuntu
|
||||
* [Lubuntu][10] - LXDE 桌面版 Ubuntu
|
||||
* [Mythbuntu][11] - MythTV 版 Ubuntu
|
||||
* [Ubuntu Budgie][12] - Budgie 桌面版 Ubuntu
|
||||
* [Xubuntu][8] - Xfce 桌面版 Ubuntu
|
||||
|
||||
就在不久前(本文写于 2017 年 5 月),官方的 Ubuntu Linux 包括了其自己打造的 Unity 桌面版和第六个被认可的特色版本:Ubuntu GNOME —— Ubuntu 的 GNOME 桌面环境。
|
||||
|
||||
当<ruby>马克·沙特尔沃思<rt>Mark Shuttleworth</rt></ruby>决定要否决 Unity 的时候,这个选择对于 Canonical 来说就很明显了——是为了让 GNOME 成为 Ubuntu Linux 的官方桌面环境。从 Ubuntu 18.04(2018 年 4 月)开始,我们将仅剩下这个官方发行版和四种官方认可的特色版本。(LCTT 译注:从 17.10 就没有 Unity 版本了)
|
||||
|
||||
对于那些已经融入 Linux 社区的人来说,就像一些非常简单的数学问题一样——你知道你喜欢哪个 Linux 桌面,在 Ubuntu、Kubuntu、Lubuntu、Mythbuntu、Ubuntu Budgie 和 Xubuntu 之间做出选择不要太容易了。但那些还没有被灌输 Linux 思想的人可不会认为这是一个如此简单的决定。
|
||||
|
||||
为此,我认为帮助新用户决定选择对他们来说哪个特色版本最好可能是至关重要的。毕竟,从一开始就选择一个不合适的发行版是一种不太理想的体验。
|
||||
|
||||
因此,如果你正考虑选择哪个 Ubuntu 的特色版本,如果你想让你的体验尽可能地不痛苦,请继续往下看。
|
||||
|
||||
### Ubuntu
|
||||
|
||||
我将从 Ubuntu 的官方特色版本开始。我会有点扭曲时间线,跳过 Unity 不谈,直接进入即将到来的基于 GNOME 的发行版(LCTT 译注:本文写作半年后发布的 Ubuntu 17.10 是第一个官方的 GNOME Ubuntu 发行版)。除了 GNOME 是一个极其稳定且易于使用的桌面环境之外,选择官方的特色版本的一个很好的理由是:支持服务。这个 Ubuntu 的官方特色版本是由 Canonical 提供商业支持的。您可以每年花费 $150.00 为 Ubuntu 桌面版购买 [官方支持服务][20]。当然,对于这一级别的支持,最少要购买 50 个桌面的支持服务。而对于个人来说,最好的支持是 [Ubuntu 论坛][21],[Ubuntu 文档][22],或者[社区帮助维基][23]。
|
||||
|
||||
在商业支持之外,选择 Ubuntu 官方特色版本的原因是,如果你想要一个现代的、功能齐全的桌面的话,它是非常可靠和易用的。 GNOME 被设计成完美地适合桌面和笔记本电脑桌面的平台(图 1)。与它的前代的 Unity 不同,GNOME 可以更方便地定制以适合你的需要。如果你不喜欢摆弄桌面,不要担心,GNOME 工作的很好。事实上,GNOME 开箱即用的体验也许是市场上最优秀的桌面之一,甚至可以与 Mac OS X 媲美(或者更好)。如果修补和调整是你的主要的兴趣所在,你会发现 GNOME 在一定程度上是受限制的。 [GNOME 调整工具][24]和[GNOME Shell 扩展][25]只会比你想要的提供的更多。
|
||||
|
||||
![GNOME桌面](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/ubuntu_flavor_a.jpg?itok=Ir6jBKbd "GNOME desktop")
|
||||
|
||||
*图 1:带有 Unity 味道 GNOME 桌面也许就会是我们在 Ubuntu 18.04 上所看到的。*
|
||||
|
||||
### Kubuntu
|
||||
|
||||
<ruby>[K 桌面环境][26]<rt>K Desktop Environment</rt></ruby>(即 KDE)与 GNOME 长期并存,有时被误解为一个较少见的桌面。但随着 KDE Plasma 5 的发布,情况发生了变化。KDE 已经成为一个强大的、高效的、稳定的桌面,它正在一步步地成为最好的桌面系统。但是你为什么要选择 Kubuntu 而不是 Ubuntu 官方版本呢?这个问题的答案很简单——你习惯了 Windows XP / 7 桌面模式。开始菜单、任务栏、系统托盘,等等,KDE 拥有这些乃至更多,所有的这些都会让你觉得你在使用过去和现在的最好的技术。事实上,如果你正在寻找一款最像 Windows 7 的 Ubuntu 官方特色版本,除了它你就找不到更好的了。
|
||||
|
||||
Kubuntu 的优点之一是,你会发现它比你以前使用过的任何 Windows 版本都灵活,而且同样可靠/友好。不要觉得因为 KDE 提供的桌面有点类似于 Windows 7,它就没有现代特色。事实上,Kubuntu 对类 Windows 7 的界面进行了很好的处理,并更新了它以满足更现代的审美(图 2)。
|
||||
|
||||
![Kubuntu](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/ubuntu_flavor_b.jpg?itok=dGpebi4z "Kubuntu")
|
||||
|
||||
*图 2: Kubuntu 在老式用户体验上提供了现代感受。*
|
||||
|
||||
Ubuntu 官方版本并不是提供桌面支持的唯一特色版本。Kubuntu 用户也可以购买[商业支持][27]。注意,它不便宜,一个小时的支持服务将花费你 103.88 美元。
|
||||
|
||||
### Lubuntu
|
||||
|
||||
如果你正在寻找一个易于使用的桌面,要非常快(以便旧硬件感受如新),而且要比你曾经使用的任何桌面都灵活,那么 Lubuntu 就是你想要的。对 Lubuntu 唯一的警告是,你看到更加空荡的桌面,也许你已经习惯了。Lubuntu 使用 [LXDE 桌面][28],并包含一个延续了轻量级主题的应用程序列表。因此,如果你想在桌面上寻找极速快感的体验,Lubuntu 可能是个不错的选择。
|
||||
|
||||
然而,对 Lubuntu 有一个提醒,对于一些用户来说,这可能会影响他们选择它。由于 Lubuntu 的低配,其预先安装的应用程序可能无法胜任任务。例如,取而代之成熟的办公套件的是,您将发现 [AibWord 字处理器][29]和 [Gnumeric 图表][30]工具。别误会,这两个都是很好的工具。然而,如果你正在寻找一款适合商业使用的软件,你会发现它们缺乏友好的支持。另一方面,如果你想要安装更多的以工作为中心的工具(例如 LibreOffice),Lubuntu 包括了新立得软件包管理器可以简化第三方软件的安装。
|
||||
|
||||
和有限的默认软件一起,Lubuntu 提供了一个简单易用的桌面(图 3),任何人都可以马上开始使用,几乎没有学习曲线。
|
||||
|
||||
![Lubuntu](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/ubuntu_flavor_c.jpg?itok=nWsJr39r "Lubuntu")
|
||||
|
||||
*图 3:Lubuntu 软件的贫乏,换来的是速度和简单性。*
|
||||
|
||||
### Mythbuntu
|
||||
|
||||
Mythbuntu 在这里是一种奇怪的鸟,因为它不是真正的桌面变体。相反,Mythbuntu 是 Ubuntu 多媒体工场设计的一个特殊的特色版本。使用 Mythbuntu 需要电视调谐器和电视输出卡。而且,在安装过程中,还需要采取一些额外的步骤(如选择如何设置前端/后端,以及设置您的红外遥控器)。
|
||||
|
||||
如果您碰巧拥有该硬件(以及创建您自己的由 Ubuntu 驱动的娱乐系统的愿望),Mythbuntu 就是您想要的发行版。一旦安装了 Mythbuntu,就会提示您通过设置采集卡、录制设置、视频源和输入连接(图4)。
|
||||
|
||||
![Mythbuntu](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/ubuntu_flavor_d.jpg?itok=Uk16xUIF "Mythbuntu")
|
||||
|
||||
*图 4:准备设置 Mythbuntu。*
|
||||
|
||||
### Ubuntu Budgie
|
||||
|
||||
Ubuntu Budgie 是一个新加入到官方特色版本列表的小成员。它使用 Budgie 桌面,这是一个非常漂亮和现代的 Linux 操作系统,它可以满足任何类型的用户。Ubuntu Budgie 的目标是创建一个优雅简洁的桌面界面。而这个任务已经完成了。如果你正在寻找一个漂亮的桌面,想在非常稳定的 Ubuntu Linux 平台上工作,你只需看看 Ubuntu Budgie 就可以了。
|
||||
|
||||
在 Ubuntu 上添加这个特殊的版本到官方版本列表中是 Canonical 的一个聪明的举动。随着 Unity 的消失,他们需要一个能提供 Unity 的优雅的桌面。Budgie 的定制非常简单,其所包含的软件列表可以让你立即开始工作和上网浏览。
|
||||
|
||||
而且,与许多用户在 Unity 中遇到的学习曲线不同,Ubuntu Budgie 的开发者/设计者们做了一件非常出色的工作,让我们保有 Ubuntu 的熟悉感。点击“开始”按钮,会显示一个相当标准的应用程序菜单。Budgie 还包括一个易于使用的 Dock(图 5),它包含了用于快速访问的应用程序启动器。
|
||||
|
||||
![Budgie](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/ubuntu_flavor_e.jpg?itok=mwlo4xzm "Budgie")
|
||||
|
||||
*图 5:这是一个漂亮的桌面。*
|
||||
|
||||
在 Ubuntu Budgie 中发现的另一个很好的功能是侧边栏可以快速显示和隐藏。这个侧边栏包含了小应用和通知。有了这个功能,你的桌面就会变得非常有用,同时还免除杂乱。
|
||||
|
||||
最后,如果你在寻找一个稍有不同,但又非常现代的桌面——其特色与功能在其他发行版本中找不到 —— 那么 Ubuntu Budgie 就是你想要的。
|
||||
|
||||
### Xubuntu
|
||||
|
||||
另一种很好地提供了低配支持的 Ubuntu 官方特色版本是 [Xubuntu][32]。Xubuntu 和 Lubuntu 的区别在于, Lubuntu 使用 LXDE 桌面,而 Xubuntu 使用[Xfce][33]。差别就是这个轻量级桌面,它比 Lubuntu 更具可配置性,也包括了更适合商务的 LibreOffice 办公套件。
|
||||
|
||||
Xubuntu 对任何人来说都是开箱即用的,无论是否有经验。但是,不要认为看起来熟悉就意味着这个 Ubuntu 特色版本可以让你马上随心所欲。如果你既想要 Ubuntu 传统的开箱即用,也想要经过大量调整成为一个更现代的桌面, 那么 Xubuntu 就是你想要的。
|
||||
|
||||
我一直很喜欢 Xubuntu 的一个非常方便的附加功能(就像之前的 Enlightenment),就是通过在桌面的任何地方右键点击打开“开始”菜单(图 6),这样可以非常有效的提高使用效率。
|
||||
|
||||
![Xubuntu](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/xubuntu.jpg?itok=XL8_hLet)
|
||||
|
||||
*图 6:Xubuntu 可以通过右键点击桌面的任何地方来打开“开始”菜单。*
|
||||
|
||||
### 选择由你
|
||||
|
||||
总有一款 Ubuntu 的特色版本可以满足所需——选择哪一个取决于你。你自己可以问一下这些问题,例如:
|
||||
|
||||
* 你有什么需要?
|
||||
* 你喜欢与哪种类型的桌面交互?
|
||||
* 你的硬件老化了吗?
|
||||
* 你喜欢 Windows XP / 7的感觉吗?
|
||||
* 你想要一个多媒体系统吗?
|
||||
|
||||
你对以上问题的回答将会很好地决定 Ubuntu 的哪一种特色版本适合你。好消息是,任何选择都不能算错。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/learn/intro-to-linux/2017/5/which-official-ubuntu-flavor-best-you
|
||||
|
||||
作者:[JACK WALLEN][a]
|
||||
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/jlwallen
|
||||
[1]:https://www.linux.com/licenses/category/used-permission
|
||||
[2]:https://www.linux.com/licenses/category/used-permission
|
||||
[3]:https://www.linux.com/licenses/category/used-permission
|
||||
[4]:https://www.linux.com/licenses/category/used-permission
|
||||
[5]:https://www.linux.com/licenses/category/used-permission
|
||||
[6]:https://www.linux.com/licenses/category/used-permission
|
||||
[7]:https://www.linux.com/licenses/category/used-permission
|
||||
[8]:http://xubuntu.org/
|
||||
[9]:http://www.kubuntu.org/
|
||||
[10]:http://lubuntu.net/
|
||||
[11]:http://www.mythbuntu.org/
|
||||
[12]:https://ubuntubudgie.org/
|
||||
[13]:https://www.linux.com/files/images/ubuntuflavorajpg
|
||||
[14]:https://www.linux.com/files/images/ubuntuflavorbjpg
|
||||
[15]:https://www.linux.com/files/images/ubuntuflavorcjpg
|
||||
[16]:https://www.linux.com/files/images/ubuntuflavordjpg
|
||||
[17]:https://www.linux.com/files/images/ubuntuflavorejpg
|
||||
[18]:https://www.linux.com/files/images/xubuntujpg
|
||||
[19]:https://www.linux.com/files/images/ubuntubudgiejpg
|
||||
[20]:https://buy.ubuntu.com/collections/ubuntu-advantage-for-desktop
|
||||
[21]:https://ubuntuforums.org/
|
||||
[22]:https://help.ubuntu.com/?_ga=2.155705979.1922322560.1494162076-828730842.1481046109
|
||||
[23]:https://help.ubuntu.com/community/CommunityHelpWiki?_ga=2.155705979.1922322560.1494162076-828730842.1481046109
|
||||
[24]:https://apps.ubuntu.com/cat/applications/gnome-tweak-tool/
|
||||
[25]:https://extensions.gnome.org/
|
||||
[26]:https://www.kde.org/
|
||||
[27]:https://kubuntu.emerge-open.com/buy
|
||||
[28]:http://lxde.org/
|
||||
[29]:https://www.abisource.com/
|
||||
[30]:http://www.gnumeric.org/
|
||||
[31]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
||||
[32]:https://xubuntu.org/
|
||||
[33]:https://www.xfce.org/
|
@ -0,0 +1,112 @@
|
||||
检查系统和硬件信息的命令
|
||||
======
|
||||
|
||||
你们好,Linux 爱好者们,在这篇文章中,我将讨论一些作为系统管理员重要的事。众所周知,作为一名优秀的系统管理员意味着要了解有关 IT 基础架构的所有信息,并掌握有关服务器的所有信息,无论是硬件还是操作系统。所以下面的命令将帮助你了解所有的硬件和系统信息。
|
||||
|
||||
### 1 查看系统信息
|
||||
|
||||
```
|
||||
$ uname -a
|
||||
```
|
||||
|
||||
![uname command][2]
|
||||
|
||||
它会为你提供有关系统的所有信息。它会为你提供系统的内核名、主机名、内核版本、内核发布号、硬件名称。
|
||||
|
||||
### 2 查看硬件信息
|
||||
|
||||
```
|
||||
$ lshw
|
||||
```
|
||||
|
||||
![lshw command][4]
|
||||
|
||||
使用 `lshw` 将在屏幕上显示所有硬件信息。
|
||||
|
||||
### 3 查看块设备(硬盘、闪存驱动器)信息
|
||||
|
||||
```
|
||||
$ lsblk
|
||||
```
|
||||
|
||||
![lsblk command][6]
|
||||
|
||||
`lsblk` 命令在屏幕上打印关于块设备的所有信息。使用 `lsblk -a` 可以显示所有块设备。
|
||||
|
||||
### 4 查看 CPU 信息
|
||||
|
||||
```
|
||||
$ lscpu
|
||||
```
|
||||
|
||||
![lscpu command][8]
|
||||
|
||||
`lscpu` 在屏幕上显示所有 CPU 信息。
|
||||
|
||||
### 5 查看 PCI 信息
|
||||
|
||||
```
|
||||
$ lspci
|
||||
```
|
||||
|
||||
![lspci command][10]
|
||||
|
||||
所有的网络适配器卡、USB 卡、图形卡都被称为 PCI。要查看他们的信息使用 `lspci`。
|
||||
|
||||
`lspci -v` 将提供有关 PCI 卡的详细信息。
|
||||
|
||||
`lspci -t` 会以树形格式显示它们。
|
||||
|
||||
### 6 查看 USB 信息
|
||||
|
||||
```
|
||||
$ lsusb
|
||||
```
|
||||
|
||||
![lsusb command][12]
|
||||
|
||||
要查看有关连接到机器的所有 USB 控制器和设备的信息,我们使用 `lsusb`。
|
||||
|
||||
### 7 查看 SCSI 信息
|
||||
|
||||
```
|
||||
$ lsscsi
|
||||
```
|
||||
|
||||
![lsscsi][14]
|
||||
|
||||
要查看 SCSI 信息输入 `lsscsi`。`lsscsi -s` 会显示分区的大小。
|
||||
|
||||
### 8 查看文件系统信息
|
||||
|
||||
```
|
||||
$ fdisk -l
|
||||
```
|
||||
|
||||
![fdisk command][16]
|
||||
|
||||
使用 `fdisk -l` 将显示有关文件系统的信息。虽然 `fdisk` 的主要功能是修改文件系统,但是也可以创建新分区,删除旧分区(详情在我以后的教程中)。
|
||||
|
||||
就是这些了,我的 Linux 爱好者们。建议你在**[这里][17]**和**[这里][18]**的文章中查看关于另外的 Linux 命令。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://linuxtechlab.com/commands-system-hardware-info/
|
||||
|
||||
作者:[Shusain][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://linuxtechlab.com/author/shsuain/
|
||||
[2]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/uname.jpg?resize=664%2C69
|
||||
[4]:https://i2.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/lshw.jpg?resize=641%2C386
|
||||
[6]:https://i1.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/lsblk.jpg?resize=646%2C162
|
||||
[8]:https://i2.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/lscpu.jpg?resize=643%2C216
|
||||
[10]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/lspci.jpg?resize=644%2C238
|
||||
[12]:https://i2.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/lsusb.jpg?resize=645%2C37
|
||||
[14]:https://i2.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/lsscsi.jpg?resize=639%2C110
|
||||
[16]:https://i2.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/fdisk.jpg?resize=656%2C335
|
||||
[17]:http://linuxtechlab.com/linux-commands-beginners-part-1/
|
||||
[18]:http://linuxtechlab.com/linux-commands-beginners-part-2/
|
@ -1,14 +1,13 @@
|
||||
Reddit 的浏览计数
|
||||
Reddit 如何实现大规模的帖子浏览计数
|
||||
======================
|
||||
|
||||
![](https://redditupvoted.files.wordpress.com/2017/05/content-view-header.png?crop=0px%2C9px%2C1000px%2C483px&resize=1200%2C580)
|
||||
|
||||
|
||||
我们希望更好地将 Reddit 的规模传达给我们的用户。到目前为止,投票得分和评论数量是特定文章活动的主要指标。然而,Reddit 有许多访问者在没有投票或评论的情况下阅读内容。我们希望建立一个能够捕捉到帖子阅读数量的系统。然后将数量展示给内容创建者和版主,以便他们更好地了解特定帖子上的活动。
|
||||
我们希望更好地将 Reddit 的规模传达给我们的用户。到目前为止,投票得分和评论数量是特定的帖子活动的主要指标。然而,Reddit 有许多访问者在没有投票或评论的情况下阅读内容。我们希望建立一个能够捕捉到帖子阅读数量的系统。然后将该数量展示给内容创建者和版主,以便他们更好地了解特定帖子上的活动。
|
||||
|
||||
![](https://redditupvoted.files.wordpress.com/2017/05/cvcs-neeson-fix.png?w=372&h=743&zoom=2)
|
||||
|
||||
在这篇文章中,我们将讨论我们如何伸缩地实现计数。
|
||||
在这篇文章中,我们将讨论我们如何大规模地实现计数。
|
||||
|
||||
### 计数方法
|
||||
|
||||
@ -19,20 +18,20 @@ Reddit 的浏览计数
|
||||
* 显示的数量与实际的误差在百分之几。
|
||||
* 系统必须能够在生产环境运行,并在事件发生后几秒内处理事件。
|
||||
|
||||
满足这四项要求比听起来要复杂得多。为了实时保持准确的计数,我们需要知道某个特定的用户是否曾经访问过这个帖子。要知道这些信息,我们需要存储先前访问过每个帖子的用户组,然后在每次处理新帖子时查看该组。这个解决方案的一个原始实现是将唯一的用户集作为散列表存储在内存中,并且以发布 ID 作为关键字。
|
||||
满足这四项要求比听起来要复杂得多。为了实时保持准确的计数,我们需要知道某个特定的用户是否曾经访问过这个帖子。要知道这些信息,我们需要存储先前访问过每个帖子的用户组,然后在每次处理对该帖子的新访问时查看该组。这个解决方案的一个原始实现是将这个唯一用户的集合作为散列表存储在内存中,并且以帖子 ID 作为键名。
|
||||
|
||||
这种方法适用于较少浏览量的文章,但一旦文章流行,阅读人数迅速增加,这种方法很难扩展。几个热门的帖子有超过一百万的唯一读者!对于这种帖子,对于内存和 CPU 来说影响都很大,因为要存储所有的 ID,并频繁地查找集合,看看是否有人已经访问过。
|
||||
这种方法适用于浏览量较少的文章,但一旦文章流行,阅读人数迅速增加,这种方法很难扩展。有几个热门的帖子有超过一百万的唯一读者!对于这种帖子,对于内存和 CPU 来说影响都很大,因为要存储所有的 ID,并频繁地查找集合,看看是否有人已经访问过。
|
||||
|
||||
由于我们不能提供精确的计数, 我们研究了几个不同的[基数估计][1] 算法。我们考虑了两个非常符合我们期望的选择:
|
||||
由于我们不能提供精确的计数,我们研究了几个不同的[基数估计][1]算法。我们考虑了两个非常符合我们期望的选择:
|
||||
|
||||
1. 线性概率计数方法,非常准确,但要计数的集合越大,则线性地需要更多的内存。
|
||||
2. 基于 [HyperLogLog][2](HLL)的计数方法。HLL 随集合大小次线性增长,但不能提供与线性计数器相同的准确度。
|
||||
2. 基于 [HyperLogLog][2](HLL)的计数方法。HLL 随集合大小<ruby>次线性<rt>sub-linearly</rt></ruby>增长,但不能提供与线性计数器相同的准确度。
|
||||
|
||||
要了解 HLL 真正节省的空间大小,考虑到右侧图片包括顶部的文章。它有超过 100 万的唯一用户。如果我们存储 100 万个唯一用户 ID,并且每个用户 ID 是 8 个字节长,那么我们需要 8 兆内存来计算单个帖子的唯一用户数!相比之下,使用 HLL 进行计数会占用更少的内存。每个实现的内存量是不一样的,但是对于[这个实现][3],我们可以使用仅仅 12 千字节的空间计算超过一百万个 ID,这将是原始空间使用量的 0.15%!
|
||||
要了解 HLL 真正节省的空间大小,看一下这篇文章顶部包括的 r/pics 帖子。它有超过 100 万的唯一用户。如果我们存储 100 万个唯一用户 ID,并且每个用户 ID 是 8 个字节长,那么我们需要 8 兆内存来计算单个帖子的唯一用户数!相比之下,使用 HLL 进行计数会占用更少的内存。每个实现的内存量是不一样的,但是对于[这个实现][3],我们可以使用仅仅 12 千字节的空间计算超过一百万个 ID,这将是原始空间使用量的 0.15%!
|
||||
|
||||
([这篇关于高可伸缩性的文章][5]很好地概述了上述两种算法。)
|
||||
|
||||
许多 HLL 实现使用了上述两种方法的组合,即对于小集合以线性计数开始并且一旦大小达到特定点就切换到 HLL。前者通常被称为 “稀疏” HLL 表达,而后者被称为“密集” HLL 表达。混合的方法是非常有利的,因为它可以提供准确的结果,同时保留适度的内存占用量。这个方法在[Google 的 HyperLogLog++ 论文][6]中有更详细的描述。
|
||||
许多 HLL 实现使用了上述两种方法的组合,即对于小集合以线性计数开始,并且一旦大小达到特定点就切换到 HLL。前者通常被称为 “稀疏” HLL 表达,而后者被称为“密集” HLL 表达。混合的方法是非常有利的,因为它可以提供准确的结果,同时保留适度的内存占用量。这个方法在 [Google 的 HyperLogLog++ 论文][6]中有更详细的描述。
|
||||
|
||||
虽然 HLL 算法是相当标准的,但在我们的实现中我们考虑使用三种变体。请注意,对于内存中的 HLL 实现,我们只关注 Java 和 Scala 实现,因为我们主要在数据工程团队中使用 Java 和 Scala。
|
||||
|
||||
@ -46,7 +45,7 @@ Reddit 的数据管道主要围绕 [Apache Kafka][7]。当用户查看帖子时
|
||||
|
||||
从这里,浏览计数系统有两个按顺序运行的组件。我们的计数架构的第一部分是一个名为 [Nazar][8] 的 Kafka 消费者,它将读取来自 Kafka 的每个事件,并通过我们编制的一组规则来确定是否应该计算一个事件。我们给它起了这个名字是因为 Nazar 是一个保护你免受邪恶的眼形护身符,Nazar 系统是一个“眼睛”,它可以保护我们免受不良因素的影响。Nazar 使用 Redis 保持状态,并跟踪不应计算浏览的潜在原因。我们可能无法统计事件的一个原因是,由于同一用户在短时间内重复浏览的结果。Nazar 接着将改变事件,添加一个布尔标志表明是否应该被计数,然后再发回 Kafka 事件。
|
||||
|
||||
这是这个项目要说的第二部分。我们有第二个叫做 [Abacus][9] 的 Kafka 消费者,它实际上对视浏览进行计数,并使计数在网站和客户端可见。Abacus 读取 Nazar 输出的 Kafka 事件。接着,根据 Nazar 的决定,它将计算或跳过本次浏览。如果事件被标记为计数,那么 Abacus 首先检查 Redis 中是否存在已经存在与事件对应的帖子的 HLL 计数器。如果计数器已经在 Redis 中,那么 Abacus 向 Redis 发出一个 [PFADD][10] 的请求。如果计数器还没有在 Redis 中,那么 Abacus 向 Cassandra 集群发出请求,我们用这个集群来持久化 HLL 计数器和原始计数,并向 Redis 发出一个 [SET][11] 请求来添加过滤器。这种情况通常发生在人们查看已经被 Redis 删除的旧帖的时候。
|
||||
这是这个项目要说的第二部分。我们有第二个叫做 [Abacus][9] 的 Kafka 消费者,它实际上对浏览进行计数,并使计数在网站和客户端可见。Abacus 读取 Nazar 输出的 Kafka 事件。接着,根据 Nazar 的决定,它将计算或跳过本次浏览。如果事件被标记为计数,那么 Abacus 首先检查 Redis 中是否存在已经存在与事件对应的帖子的 HLL 计数器。如果计数器已经在 Redis 中,那么 Abacus 向 Redis 发出一个 [PFADD][10] 的请求。如果计数器还没有在 Redis 中,那么 Abacus 向 Cassandra 集群发出请求,我们用这个集群来持久化 HLL 计数器和原始计数,并向 Redis 发出一个 [SET][11] 请求来添加过滤器。这种情况通常发生在人们查看已经被 Redis 删除的旧帖的时候。
|
||||
|
||||
为了保持对可能从 Redis 删除的旧帖子的维护,Abacus 定期将 Redis 的完整 HLL 过滤器以及每个帖子的计数记录到 Cassandra 集群中。 Cassandra 的写入以 10 秒一组分批写入,以避免超载。下面是一个高层的事件流程图。
|
||||
|
||||
@ -63,9 +62,9 @@ Reddit 的数据管道主要围绕 [Apache Kafka][7]。当用户查看帖子时
|
||||
|
||||
via: https://redditblog.com/2017/05/24/view-counting-at-reddit/
|
||||
|
||||
作者:[Krishnan Chandra ][a]
|
||||
作者:[Krishnan Chandra][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,113 @@
|
||||
使用 fdisk 和 fallocate 命令创建交换分区
|
||||
======
|
||||
|
||||
交换分区在物理内存(RAM)被填满时用来保持内存中的内容。当 RAM 被耗尽,Linux 会将内存中不活动的页移动到交换空间中,从而空出内存给系统使用。虽然如此,但交换空间不应被认为是物理内存的替代品。
|
||||
|
||||
大多数情况下,建议交换内存的大小为物理内存的 1 到 2 倍。也就是说如果你有 8GB 内存, 那么交换空间大小应该介于8-16 GB。
|
||||
|
||||
若系统中没有配置交换分区,当内存耗尽后,系统可能会杀掉正在运行中的进程/应用,从而导致系统崩溃。在本文中,我们将学会如何为 Linux 系统添加交换分区,我们有两个办法:
|
||||
|
||||
- 使用 fdisk 命令
|
||||
- 使用 fallocate 命令
|
||||
|
||||
### 第一个方法(使用 fdisk 命令)
|
||||
|
||||
通常,系统的第一块硬盘会被命名为 `/dev/sda`,而其中的分区会命名为 `/dev/sda1` 、 `/dev/sda2`。 本文我们使用的是一块有两个主分区的硬盘,两个分区分别为 `/dev/sda1`、 `/dev/sda2`,而我们使用 `/dev/sda3` 来做交换分区。
|
||||
|
||||
首先创建一个新分区,
|
||||
|
||||
```
|
||||
$ fdisk /dev/sda
|
||||
```
|
||||
|
||||
按 `n` 来创建新分区。系统会询问你从哪个柱面开始,直接按回车键使用默认值即可。然后系统询问你到哪个柱面结束, 这里我们输入交换分区的大小(比如 1000MB)。这里我们输入 `+1000M`。
|
||||
|
||||
![swap][2]
|
||||
|
||||
现在我们创建了一个大小为 1000MB 的磁盘了。但是我们并没有设置该分区的类型,我们按下 `t` 然后回车,来设置分区类型。
|
||||
|
||||
现在我们要输入分区编号,这里我们输入 `3`,然后输入磁盘分类号,交换分区的分区类型为 `82` (要显示所有可用的分区类型,按下 `l` ) ,然后再按下 `w` 保存磁盘分区表。
|
||||
|
||||
![swap][4]
|
||||
|
||||
再下一步使用 `mkswap` 命令来格式化交换分区:
|
||||
|
||||
```
|
||||
$ mkswap /dev/sda3
|
||||
```
|
||||
|
||||
然后激活新建的交换分区:
|
||||
|
||||
```
|
||||
$ swapon /dev/sda3
|
||||
```
|
||||
|
||||
然而我们的交换分区在重启后并不会自动挂载。要做到永久挂载,我们需要添加内容到 `/etc/fstab` 文件中。打开 `/etc/fstab` 文件并输入下面行:
|
||||
|
||||
```
|
||||
$ vi /etc/fstab
|
||||
|
||||
/dev/sda3 swap swap default 0 0
|
||||
```
|
||||
|
||||
保存并关闭文件。现在每次重启后都能使用我们的交换分区了。
|
||||
|
||||
### 第二种方法(使用 fallocate 命令)
|
||||
|
||||
我推荐用这种方法因为这个是最简单、最快速的创建交换空间的方法了。`fallocate` 是最被低估和使用最少的命令之一了。 `fallocate` 命令用于为文件预分配块/大小。
|
||||
|
||||
使用 `fallocate` 创建交换空间,我们首先在 `/` 目录下创建一个名为 `swap_space` 的文件。然后分配 2GB 到 `swap_space` 文件:
|
||||
|
||||
```
|
||||
$ fallocate -l 2G /swap_space
|
||||
```
|
||||
|
||||
我们运行下面命令来验证文件大小:
|
||||
|
||||
```
|
||||
$ ls -lh /swap_space
|
||||
```
|
||||
|
||||
然后更改文件权限,让 `/swap_space` 更安全:
|
||||
|
||||
```
|
||||
$ chmod 600 /swap_space
|
||||
```
|
||||
|
||||
这样只有 root 可以读写该文件了。我们再来格式化交换分区(LCTT 译注:虽然这个 `swap_space` 是个文件,但是我们把它当成是分区来挂载):
|
||||
|
||||
```
|
||||
$ mkswap /swap_space
|
||||
```
|
||||
|
||||
然后启用交换空间:
|
||||
|
||||
```
|
||||
$ swapon -s
|
||||
```
|
||||
|
||||
每次重启后都要重新挂载磁盘分区。因此为了使之持久化,就像上面一样,我们编辑 `/etc/fstab` 并输入下面行:
|
||||
|
||||
```
|
||||
/swap_space swap swap sw 0 0
|
||||
```
|
||||
|
||||
保存并退出文件。现在我们的交换分区会一直被挂载了。我们重启后可以在终端运行 `free -m` 来检查交换分区是否生效。
|
||||
|
||||
我们的教程至此就结束了,希望本文足够容易理解和学习,如果有任何疑问欢迎提出。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://linuxtechlab.com/create-swap-using-fdisk-fallocate/
|
||||
|
||||
作者:[Shusain][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://linuxtechlab.com/author/shsuain/
|
||||
[1]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=668%2C211
|
||||
[2]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/fidsk.jpg?resize=668%2C211
|
||||
[3]:https://i1.wp.com/linuxtechlab.com/wp-content/plugins/a3-lazy-load/assets/images/lazy_placeholder.gif?resize=620%2C157
|
||||
[4]:https://i0.wp.com/linuxtechlab.com/wp-content/uploads/2017/02/fidsk-swap-select.jpg?resize=620%2C157
|
73
published/20170804 Add speech to your Fedora system.md
Normal file
73
published/20170804 Add speech to your Fedora system.md
Normal file
@ -0,0 +1,73 @@
|
||||
为你的 Fedora 系统增添发音功能
|
||||
======
|
||||
|
||||
![](https://fedoramagazine.org/wp-content/uploads/2017/08/espeak-945x400.png)
|
||||
|
||||
Fedora 工作站默认带有一个小软件,叫做 espeak。它是一个声音合成器 -- 也就是转换文本为声音的软件。
|
||||
|
||||
在当今这个世界,发音设备已经非常普遍了。在智能电话、Amazon Alexa,甚至火车站的公告栏中都有声音合成器。而且,现在合成声音已经跟人类的声音很类似了。我们生活在 80bandaid 的科幻电影里!
|
||||
|
||||
与前面提到的这些工具相比,espeak 的发音听起来有一点原始。但最终 espeak 可以产生不错的发音效果。而且不管你觉得它有没有用,至少它可以给你带来一些乐趣。
|
||||
|
||||
### 运行 espeak
|
||||
|
||||
你可以在命令行为 espeak 设置各种参数。包括:
|
||||
|
||||
* 振幅(`-a`)
|
||||
* 音高调整 (`-p`)
|
||||
* 读句子的速度 (`-s`)
|
||||
* 单词间的停顿时间 (`-g`)
|
||||
|
||||
每个选项都能产生不同的效果,你可以通过调整它们来让发音更加清晰。
|
||||
|
||||
你也可以通过命令行选项来选择不同的变音。比如,`-ven+m3` 表示另一种英式男音,而 `-ven+f1` 表示英式女音。你也可以尝试其他语言的发音。运行下面命令可以查看支持的语言列表:
|
||||
|
||||
```
|
||||
espeak --voices
|
||||
```
|
||||
|
||||
要注意,很多非英语的语言发音现在还处于实验阶段。
|
||||
|
||||
若要创建相应的 WAV 文件而不是真的讲出来,则可以使用 `-w` 选项:
|
||||
|
||||
```
|
||||
espeak -w out.wav "Audio file test"
|
||||
```
|
||||
|
||||
espeak 还能读出文件的内容。
|
||||
|
||||
```
|
||||
espeak -f plaintextfile
|
||||
```
|
||||
|
||||
你也可以通过标准输入传递要发音的文本。举个简单的例子,通过这种方式,你可以创建一个发音盒子,当事件发生时使用声音通知你。你的备份完成了?将下面命令添加到脚本的最后试试效果:
|
||||
|
||||
```
|
||||
echo "Backup completed" | espeak -s 160 -a 100 -g 4
|
||||
```
|
||||
|
||||
假如有日志文件中出现错误了:
|
||||
|
||||
```
|
||||
tail -1F /your/log/file | grep --line-buffered 'ERROR' | espeak
|
||||
```
|
||||
|
||||
或者你也可以创建一个报时钟表,每分钟报一次时:
|
||||
|
||||
```
|
||||
while true; do date +%S | grep '00' && date +%H:%M | espeak; sleep 1; done
|
||||
```
|
||||
|
||||
你会发现,espeak 的使用场景仅仅受你的想象所限制。享受你这会发音的 Fedora 系统吧!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/add-speech-fedora-system/
|
||||
|
||||
作者:[Alessio Ciregia][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://alciregi.id.fedoraproject.org/
|
214
published/20170915 12 ip Command Examples for Linux Users.md
Normal file
214
published/20170915 12 ip Command Examples for Linux Users.md
Normal file
@ -0,0 +1,214 @@
|
||||
12 个 ip 命令范例
|
||||
======
|
||||
|
||||
一年又一年,我们一直在使用 `ifconfig` 命令来执行网络相关的任务,比如检查和配置网卡信息。但是 `ifconfig` 已经不再被维护,并且在最近版本的 Linux 中被废除了! `ifconfig` 命令已经被 `ip` 命令所替代了。
|
||||
|
||||
`ip` 命令跟 `ifconfig` 命令有些类似,但要强力的多,它有许多新功能。`ip` 命令完成很多 `ifconfig` 命令无法完成的任务。
|
||||
|
||||
![IP-command-examples-Linux][2]
|
||||
|
||||
本教程将会讨论 `ip` 命令的 12 中最常用法,让我们开始吧。
|
||||
|
||||
### 案例 1:检查网卡信息
|
||||
|
||||
检查网卡的诸如 IP 地址,子网等网络信息,使用 `ip addr show` 命令:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ ip addr show
|
||||
|
||||
或
|
||||
|
||||
[linuxtechi@localhost]$ ip a s
|
||||
```
|
||||
|
||||
这会显示系统中所有可用网卡的相关网络信息,不过如果你想查看某块网卡的信息,则命令为:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ ip addr show enp0s3
|
||||
```
|
||||
|
||||
这里 `enp0s3` 是网卡的名字。
|
||||
|
||||
![IP-addr-show-commant-output][4]
|
||||
|
||||
### 案例 2:启用/禁用网卡
|
||||
|
||||
使用 `ip` 命令来启用一个被禁用的网卡:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip link set enp0s3 up
|
||||
```
|
||||
|
||||
而要禁用网卡则使用 `down` 触发器:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip link set enp0s3 down
|
||||
```
|
||||
|
||||
### 案例 3:为网卡分配 IP 地址以及其他网络信息
|
||||
|
||||
要为网卡分配 IP 地址,我们使用下面命令:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip addr add 192.168.0.50/255.255.255.0 dev enp0s3
|
||||
```
|
||||
|
||||
也可以使用 `ip` 命令来设置广播地址。默认是没有设置广播地址的,设置广播地址的命令为:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip addr add broadcast 192.168.0.255 dev enp0s3
|
||||
```
|
||||
|
||||
我们也可以使用下面命令来根据 IP 地址设置标准的广播地址:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip addr add 192.168.0.10/24 brd + dev enp0s3
|
||||
```
|
||||
|
||||
如上面例子所示,我们可以使用 `brd` 代替 `broadcast` 来设置广播地址。
|
||||
|
||||
### 案例 4:删除网卡中配置的 IP 地址
|
||||
|
||||
若想从网卡中删掉某个 IP,使用如下 `ip` 命令:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip addr del 192.168.0.10/24 dev enp0s3
|
||||
```
|
||||
|
||||
### 案例 5:为网卡添加别名(假设网卡名为 enp0s3)
|
||||
|
||||
添加别名,即为网卡添加不止一个 IP,执行下面命令:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip addr add 192.168.0.20/24 dev enp0s3 label enp0s3:1
|
||||
```
|
||||
|
||||
![ip-command-add-alias-linux][6]
|
||||
|
||||
### 案例 6:检查路由/默认网关的信息
|
||||
|
||||
查看路由信息会给我们显示数据包到达目的地的路由路径。要查看网络路由信息,执行下面命令:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ ip route show
|
||||
```
|
||||
|
||||
![ip-route-command-output][8]
|
||||
|
||||
在上面输出结果中,我们能够看到所有网卡上数据包的路由信息。我们也可以获取特定 IP 的路由信息,方法是:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip route get 192.168.0.1
|
||||
```
|
||||
|
||||
### 案例 7:添加静态路由
|
||||
|
||||
我们也可以使用 IP 来修改数据包的默认路由。方法是使用 `ip route` 命令:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip route add default via 192.168.0.150/24
|
||||
```
|
||||
|
||||
这样所有的网络数据包通过 `192.168.0.150` 来转发,而不是以前的默认路由了。若要修改某个网卡的默认路由,执行:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip route add 172.16.32.32 via 192.168.0.150/24 dev enp0s3
|
||||
```
|
||||
|
||||
### 案例 8:删除默认路由
|
||||
|
||||
要删除之前设置的默认路由,打开终端然后运行:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip route del 192.168.0.150/24
|
||||
```
|
||||
|
||||
**注意:** 用上面方法修改的默认路由只是临时有效的,在系统重启后所有的改动都会丢失。要永久修改路由,需要修改或创建 `route-enp0s3` 文件。将下面这行加入其中:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo vi /etc/sysconfig/network-scripts/route-enp0s3
|
||||
|
||||
172.16.32.32 via 192.168.0.150/24 dev enp0s3
|
||||
```
|
||||
|
||||
保存并退出该文件。
|
||||
|
||||
若你使用的是基于 Ubuntu 或 debian 的操作系统,则该要修改的文件为 `/etc/network/interfaces`,然后添加 `ip route add 172.16.32.32 via 192.168.0.150/24 dev enp0s3` 这行到文件末尾。
|
||||
|
||||
### 案例 9:检查所有的 ARP 记录
|
||||
|
||||
ARP,是<ruby>地址解析协议<rt>Address Resolution Protocol</rt></ruby>的缩写,用于将 IP 地址转换为物理地址(也就是 MAC 地址)。所有的 IP 和其对应的 MAC 明细都存储在一张表中,这张表叫做 ARP 缓存。
|
||||
|
||||
要查看 ARP 缓存中的记录,即连接到局域网中设备的 MAC 地址,则使用如下 ip 命令:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ ip neigh
|
||||
```
|
||||
|
||||
![ip-neigh-command-linux][10]
|
||||
|
||||
### 案例 10:修改 ARP 记录
|
||||
|
||||
删除 ARP 记录的命令为:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip neigh del 192.168.0.106 dev enp0s3
|
||||
```
|
||||
|
||||
若想往 ARP 缓存中添加新记录,则命令为:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ sudo ip neigh add 192.168.0.150 lladdr 33:1g:75:37:r3:84 dev enp0s3 nud perm
|
||||
```
|
||||
|
||||
这里 `nud` 的意思是 “neghbour state”(网络邻居状态),它的值可以是:
|
||||
|
||||
* `perm` - 永久有效并且只能被管理员删除
|
||||
* `noarp` - 记录有效,但在生命周期过期后就允许被删除了
|
||||
* `stale` - 记录有效,但可能已经过期
|
||||
* `reachable` - 记录有效,但超时后就失效了
|
||||
|
||||
### 案例 11:查看网络统计信息
|
||||
|
||||
通过 `ip` 命令还能查看网络的统计信息,比如所有网卡上传输的字节数和报文数,错误或丢弃的报文数等。使用 `ip -s link` 命令来查看:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ ip -s link
|
||||
```
|
||||
|
||||
![ip-s-command-linux][12]
|
||||
|
||||
### 案例 12:获取帮助
|
||||
|
||||
若你想查看某个上面例子中没有的选项,那么你可以查看帮助。事实上对任何命令你都可以寻求帮助。要列出 `ip` 命令的所有可选项,执行:
|
||||
|
||||
```
|
||||
[linuxtechi@localhost]$ ip help
|
||||
```
|
||||
|
||||
记住,`ip` 命令是一个对 Linux 系统管理来说特别重要的命令,学习并掌握它能够让配置网络变得容易。本教程就此结束了,若有任何建议欢迎在下面留言框中留言。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linuxtechi.com/ip-command-examples-for-linux-users/
|
||||
|
||||
作者:[Pradeep Kumar][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linuxtechi.com/author/pradeep/
|
||||
[1]:https://www.linuxtechi.com/wp-content/plugins/lazy-load/images/1x1.trans.gif
|
||||
[2]:https://www.linuxtechi.com/wp-content/uploads/2017/09/IP-command-examples-Linux.jpg
|
||||
[3]:https://www.linuxtechi.com/wp-content/uploads/2017/09/IP-command-examples-Linux.jpg
|
||||
[4]:https://www.linuxtechi.com/wp-content/uploads/2017/09/IP-addr-show-commant-output.jpg
|
||||
[5]:https://www.linuxtechi.com/wp-content/uploads/2017/09/IP-addr-show-commant-output.jpg
|
||||
[6]:https://www.linuxtechi.com/wp-content/uploads/2017/09/ip-command-add-alias-linux.jpg
|
||||
[7]:https://www.linuxtechi.com/wp-content/uploads/2017/09/ip-command-add-alias-linux.jpg
|
||||
[8]:https://www.linuxtechi.com/wp-content/uploads/2017/09/ip-route-command-output.jpg
|
||||
[9]:https://www.linuxtechi.com/wp-content/uploads/2017/09/ip-route-command-output.jpg
|
||||
[10]:https://www.linuxtechi.com/wp-content/uploads/2017/09/ip-neigh-command-linux.jpg
|
||||
[11]:https://www.linuxtechi.com/wp-content/uploads/2017/09/ip-neigh-command-linux.jpg
|
||||
[12]:https://www.linuxtechi.com/wp-content/uploads/2017/09/ip-s-command-linux.jpg
|
||||
[13]:https://www.linuxtechi.com/wp-content/uploads/2017/09/ip-s-command-linux.jpg
|
@ -0,0 +1,77 @@
|
||||
在 Linux 的终端上伪造一个好莱坞黑客的屏幕
|
||||
=============
|
||||
|
||||
摘要:这是一个简单的小工具,可以把你的 Linux 终端变为好莱坞风格的黑客入侵的实时画面。
|
||||
|
||||
我攻进去了!
|
||||
|
||||
你可能会几乎在所有的好莱坞电影里面会听说过这句话,此时的荧幕正在显示着一个入侵的画面。那可能是一个黑色的终端伴随着 ASCII 码、图标和连续不断变化的十六进制编码以及一个黑客正在击打着键盘,仿佛他/她正在打一段愤怒的论坛回复。
|
||||
|
||||
但是那是好莱坞大片!黑客们想要在几分钟之内破解进入一个网络系统除非他花费了几个月的时间来研究它。不过现在我先把对好莱坞黑客的评论放在一边。
|
||||
|
||||
因为我们将会做相同的事情,我们将会伪装成为一个好莱坞风格的黑客。
|
||||
|
||||
这个小工具运行一个脚本在你的 Linux 终端上,就可以把它变为好莱坞风格的实时入侵终端:
|
||||
|
||||
![在 Linux 上的Hollywood 入侵终端][1]
|
||||
|
||||
看到了吗?就像这样,它甚至在后台播放了一个 Mission Impossible 主题的音乐。此外每次运行这个工具,你都可以获得一个全新且随机的入侵的终端。
|
||||
|
||||
让我们看看如何在 30 秒之内成为一个好莱坞黑客。
|
||||
|
||||
|
||||
### 如何安装 Hollywood 入侵终端在 Linux 之上
|
||||
|
||||
这个工具非常适合叫做 Hollywood 。从根本上说,它运行在 Byobu ——一个基于文本的窗口管理器,而且它会创建随机数量、随机尺寸的分屏,并在每个里面运行一个混乱的文字应用。
|
||||
|
||||
[Byobu][2] 是一个在 Ubuntu 上由 Dustin Kirkland 开发的有趣工具。在其他文章之中还有更多关于它的有趣之处,让我们先专注于安装这个工具。
|
||||
|
||||
Ubuntu 用户可以使用简单的命令安装 Hollywood:
|
||||
|
||||
```
|
||||
sudo apt install hollywood
|
||||
```
|
||||
|
||||
如果上面的命令不能在你的 Ubuntu 或其他例如 Linux Mint、elementary OS、Zorin OS、Linux Lite 等等基于 Ubuntu 的 Linux 发行版上运行,你可以使用下面的 PPA 来安装:
|
||||
|
||||
```
|
||||
sudo apt-add-repository ppa:hollywood/ppa
|
||||
sudo apt-get update
|
||||
sudo apt-get install byobu hollywood
|
||||
```
|
||||
|
||||
你也可以在它的 GitHub 仓库之中获得其源代码: [Hollywood 在 GitHub][3] 。
|
||||
|
||||
一旦安装好,你可以使用下面的命令运行它,不需要使用 sudo :
|
||||
|
||||
```
|
||||
hollywood
|
||||
```
|
||||
|
||||
因为它会先运行 Byosu ,你将不得不使用 `Ctrl+C` 两次并再使用 `exit` 命令来停止显示入侵终端的脚本。
|
||||
|
||||
这里面有一个伪装好莱坞入侵的视频。 https://youtu.be/15-hMt8VZ50
|
||||
|
||||
这是一个让你朋友、家人和同事感到吃惊的有趣小工具,甚至你可以在酒吧里给女孩们留下深刻的印象,尽管我不认为这对你在那方面有任何的帮助,
|
||||
|
||||
并且如果你喜欢 Hollywood 入侵终端,或许你也会喜欢另一个可以[让 Linux 终端产生 Sneaker 电影效果的工具][5]。
|
||||
|
||||
如果你知道更多有趣的工具,可以在下面的评论栏里分享给我们。
|
||||
|
||||
|
||||
------
|
||||
|
||||
via: https://itsfoss.com/hollywood-hacker-screen/
|
||||
|
||||
作者:[Abhishek Prakash][a]
|
||||
译者:[Drshu](https://github.com/Drshu)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/abhishek/
|
||||
[1]: https://4bds6hergc-flywheel.netdna-ssl.com/wp-content/uploads/2017/09/hollywood-hacking-linux-terminal.jpg
|
||||
[2]: http://byobu.co/
|
||||
[3]: https://github.com/dustinkirkland/hollywood
|
||||
[4]: https://www.youtube.com/c/itsfoss?sub_confirmation=1
|
||||
[5]: https://itsfoss.com/sneakers-movie-effect-linux/
|
79
published/20170924 Simulate System Loads.md
Normal file
79
published/20170924 Simulate System Loads.md
Normal file
@ -0,0 +1,79 @@
|
||||
在 Linux 上简单模拟系统负载的方法
|
||||
======
|
||||
|
||||
系统管理员通常需要探索在不同负载对应用性能的影响。这意味着必须要重复地人为创造负载。当然,你可以通过专门的工具来实现,但有时你可能不想也无法安装新工具。
|
||||
|
||||
每个 Linux 发行版中都自带有创建负载的工具。他们不如专门的工具那么灵活,但它们是现成的,而且无需专门学习。
|
||||
|
||||
### CPU
|
||||
|
||||
下面命令会创建 CPU 负荷,方法是通过压缩随机数据并将结果发送到 `/dev/null`:
|
||||
|
||||
```
|
||||
cat /dev/urandom | gzip -9 > /dev/null
|
||||
```
|
||||
|
||||
如果你想要更大的负荷,或者系统有多个核,那么只需要对数据进行压缩和解压就行了,像这样:
|
||||
|
||||
```
|
||||
cat /dev/urandom | gzip -9 | gzip -d | gzip -9 | gzip -d > /dev/null
|
||||
```
|
||||
|
||||
按下 `CTRL+C` 来终止进程。
|
||||
|
||||
### 内存占用
|
||||
|
||||
下面命令会减少可用内存的总量。它是通过在内存中创建文件系统然后往里面写文件来实现的。你可以使用任意多的内存,只需哟往里面写入更多的文件就行了。
|
||||
|
||||
首先,创建一个挂载点,然后将 ramfs 文件系统挂载上去:
|
||||
|
||||
```
|
||||
mkdir z
|
||||
mount -t ramfs ramfs z/
|
||||
```
|
||||
|
||||
第二步,使用 `dd` 在该目录下创建文件。这里我们创建了一个 128M 的文件:
|
||||
|
||||
```
|
||||
dd if=/dev/zero of=z/file bs=1M count=128
|
||||
```
|
||||
|
||||
文件的大小可以通过下面这些操作符来修改:
|
||||
|
||||
- `bs=` 块大小。可以是任何数字后面接上 `B`(表示字节),`K`(表示 KB),`M`( 表示 MB)或者 `G`(表示 GB)。
|
||||
- `count=` 要写多少个块。
|
||||
|
||||
### 磁盘 I/O
|
||||
|
||||
创建磁盘 I/O 的方法是先创建一个文件,然后使用 `for` 循环来不停地拷贝它。
|
||||
|
||||
下面使用命令 `dd` 创建了一个全是零的 1G 大小的文件:
|
||||
|
||||
```
|
||||
dd if=/dev/zero of=loadfile bs=1M count=1024
|
||||
```
|
||||
|
||||
下面命令用 `for` 循环执行 10 次操作。每次都会拷贝 `loadfile` 来覆盖 `loadfile1`:
|
||||
|
||||
```
|
||||
for i in {1..10}; do cp loadfile loadfile1; done
|
||||
```
|
||||
|
||||
通过修改 `{1..10}` 中的第二个参数来调整运行时间的长短。(LCTT 译注:你的 Linux 系统中的默认使用的 `cp` 命令很可能是 `cp -i` 的别名,这种情况下覆写会提示你输入 `y` 来确认,你可以使用 `-f` 参数的 `cp` 命令来覆盖此行为,或者直接用 `/bin/cp` 命令。)
|
||||
|
||||
若你想要一直运行,直到按下 `CTRL+C` 来停止,则运行下面命令:
|
||||
|
||||
```
|
||||
while true; do cp loadfile loadfile1; done
|
||||
```
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://bash-prompt.net/guides/create-system-load/
|
||||
|
||||
作者:[Elliot Cooper][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://bash-prompt.net
|
148
published/20170925 A Commandline Fuzzy Search Tool For Linux.md
Normal file
148
published/20170925 A Commandline Fuzzy Search Tool For Linux.md
Normal file
@ -0,0 +1,148 @@
|
||||
Pick:一款 Linux 上的命令行模糊搜索工具
|
||||
======
|
||||
|
||||
![](https://www.ostechnix.com/wp-content/uploads/2017/09/search-720x340.jpg)
|
||||
|
||||
今天,我们要讲的是一款有趣的命令行工具,名叫 Pick。它允许用户通过 ncurses(3X) 界面来从一系列选项中进行选择,而且还支持模糊搜索的功能。当你想要选择某个名字中包含非英文字符的目录或文件时,这款工具就很有用了。你根本都无需学习如何输入非英文字符。借助 Pick,你可以很方便地进行搜索、选择,然后浏览该文件或进入该目录。你甚至无需输入任何字符来过滤文件/目录。这很适合那些有大量目录和文件的人来用。
|
||||
|
||||
### 安装 Pick
|
||||
|
||||
对 Arch Linux 及其衍生品来说,Pick 放在 [AUR][1] 中。因此 Arch 用户可以使用类似 [Pacaur][2],[Packer][3],以及 [Yaourt][4] 等 AUR 辅助工具来安装它。
|
||||
|
||||
```
|
||||
pacaur -S pick
|
||||
```
|
||||
|
||||
或者,
|
||||
|
||||
```
|
||||
packer -S pick
|
||||
```
|
||||
|
||||
或者,
|
||||
|
||||
```
|
||||
yaourt -S pick
|
||||
```
|
||||
|
||||
Debian,Ubuntu,Linux Mint 用户则可以通过运行下面命令来安装 Pick。
|
||||
|
||||
```
|
||||
sudo apt-get install pick
|
||||
```
|
||||
|
||||
其他的发行版则可以从[这里][5]下载最新的安装包,然后按照下面的步骤来安装。在写本指南时,其最新版为 1.9.0。
|
||||
|
||||
```
|
||||
wget https://github.com/calleerlandsson/pick/releases/download/v1.9.0/pick-1.9.0.tar.gz
|
||||
tar -zxvf pick-1.9.0.tar.gz
|
||||
cd pick-1.9.0/
|
||||
```
|
||||
|
||||
使用下面命令进行配置:
|
||||
|
||||
```
|
||||
./configure
|
||||
```
|
||||
|
||||
最后,构建并安装 Pick:
|
||||
|
||||
```
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
### 用法
|
||||
|
||||
通过将它与其他命令集成能够大幅简化你的工作。我这里会给出一些例子,让你理解它是怎么工作的。
|
||||
|
||||
让们先创建一堆目录。
|
||||
|
||||
```
|
||||
mkdir -p abcd/efgh/ijkl/mnop/qrst/uvwx/yz/
|
||||
```
|
||||
|
||||
现在,你想进入目录 `/ijkl/`。你有两种选择。可以使用 `cd` 命令:
|
||||
|
||||
```
|
||||
cd abcd/efgh/ijkl/
|
||||
```
|
||||
|
||||
或者,创建一个[快捷方式][6] 或者说别名指向这个目录,这样你可以迅速进入该目录。
|
||||
|
||||
但,使用 `pick` 命令则问题变得简单的多。看下面这个例子。
|
||||
|
||||
```
|
||||
cd $(find . -type d | pick)
|
||||
```
|
||||
|
||||
这个命令会列出当前工作目录下的所有目录及其子目录,你可以用上下箭头选择你想进入的目录,然后按下回车就行了。
|
||||
|
||||
像这样:
|
||||
|
||||
![][8]
|
||||
|
||||
而且,它还会根据你输入的内容过滤目录和文件。比如,当我输入 “or” 时会显示如下结果。
|
||||
|
||||
![][9]
|
||||
|
||||
这只是一个例子。你也可以将 `pick` 命令跟其他命令一起混用。
|
||||
|
||||
这是另一个例子。
|
||||
|
||||
```
|
||||
find -type f | pick | xargs less
|
||||
```
|
||||
|
||||
该命令让你选择当前目录中的某个文件并用 `less` 来查看它。
|
||||
|
||||
![][10]
|
||||
|
||||
还想看其他例子?还有呢。下面命令让你选择当前目录下的文件或目录,并将之迁移到其他地方去,比如这里我们迁移到 `/home/sk/ostechnix`。
|
||||
|
||||
```
|
||||
mv "$(find . -maxdepth 1 |pick)" /home/sk/ostechnix/
|
||||
```
|
||||
|
||||
![][11]
|
||||
|
||||
通过上下按钮选择要迁移的文件,然后按下回车就会把它迁移到 `/home/sk/ostechnix/` 目录中的。
|
||||
|
||||
![][12]
|
||||
|
||||
从上面的结果中可以看到,我把一个名叫 `abcd` 的目录移动到 `ostechnix` 目录中了。
|
||||
|
||||
使用方式是无限的。甚至 Vim 编辑器上还有一个叫做 [pick.vim][13] 的插件让你在 Vim 中选择更加方便。
|
||||
|
||||
要查看详细信息,请参阅它的 man 页。
|
||||
|
||||
```
|
||||
man pick
|
||||
```
|
||||
|
||||
我们的讲解至此就结束了。希望这款工具能给你们带来帮助。如果你觉得我们的指南有用的话,请将它分享到您的社交网络上,并向大家推荐我们。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.ostechnix.com/pick-commandline-fuzzy-search-tool-linux/
|
||||
|
||||
作者:[SK][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.ostechnix.com/author/sk/
|
||||
[1]:https://aur.archlinux.org/packages/pick/
|
||||
[2]:https://www.ostechnix.com/install-pacaur-arch-linux/
|
||||
[3]:https://www.ostechnix.com/install-packer-arch-linux-2/
|
||||
[4]:https://www.ostechnix.com/install-yaourt-arch-linux/
|
||||
[5]:https://github.com/calleerlandsson/pick/releases/
|
||||
[6]:https://www.ostechnix.com/create-shortcuts-frequently-used-directories-shell/
|
||||
[7]:data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
|
||||
[8]:http://www.ostechnix.com/wp-content/uploads/2017/09/sk@sk_001-3.png
|
||||
[9]:http://www.ostechnix.com/wp-content/uploads/2017/09/sk@sk_002-1.png
|
||||
[10]:http://www.ostechnix.com/wp-content/uploads/2017/09/sk@sk_004-1.png
|
||||
[11]:http://www.ostechnix.com/wp-content/uploads/2017/09/sk@sk_005.png
|
||||
[12]:http://www.ostechnix.com/wp-content/uploads/2017/09/sk@sk_006-1.png
|
||||
[13]:https://github.com/calleerlandsson/pick.vim/
|
@ -0,0 +1,140 @@
|
||||
6 个例子让初学者掌握 free 命令
|
||||
======
|
||||
|
||||
在 Linux 系统上,有时你可能想从命令行快速地了解系统的已使用和未使用的内存空间。如果你是一个 Linux 新手,有个好消息:有一条系统内置的命令可以显示这些信息:`free`。
|
||||
|
||||
在本文中,我们会讲到 free 命令的基本用法以及它所提供的一些重要的功能。文中提到的所有命令和用法都是在 Ubuntu 16.04LTS 上测试过的。
|
||||
|
||||
### Linux free 命令
|
||||
|
||||
让我们看一下 `free` 命令的语法:
|
||||
|
||||
```
|
||||
free [options]
|
||||
```
|
||||
|
||||
free 命令的 man 手册如是说:
|
||||
|
||||
> `free` 命令显示了系统的可用和已用的物理内存及交换内存的总量,以及内核用到的缓存空间。这些信息是从 `/proc/meminfo` 中得到的。
|
||||
|
||||
接下来我们用问答的方式了解一下 `free` 命令是怎么工作的。
|
||||
|
||||
### Q1. 怎么用 free 命令查看已使用和未使用的内存?
|
||||
|
||||
这很容易,您只需不加任何参数地运行 `free` 这条命令就可以了:
|
||||
|
||||
```
|
||||
free
|
||||
```
|
||||
|
||||
这是 `free` 命令在我的系统上的输出:
|
||||
|
||||
[![view used and available memory using free command][1]][2]
|
||||
|
||||
这些列是什么意思呢?
|
||||
|
||||
[![Free command columns][3]][4]
|
||||
|
||||
- `total` - 安装的内存的总量(等同于 `/proc/meminfo` 中的 `MemTotal` 和 `SwapTotal`)
|
||||
- `used` - 已使用的内存(计算公式为:`used` = `total` - `free` - `buffers` - `cache`)
|
||||
- `free` - 未被使用的内存(等同于 `/proc/meminfo` 中的 `MemFree` 和 `SwapFree`)
|
||||
- `shared` - 通常是临时文件系统使用的内存(等同于 `/proc/meminfo` 中的 `Shmem`;自内核 2.6.32 版本可用,不可用则显示为 `0`)
|
||||
- `buffers` - 内核缓冲区使用的内存(等同于 `/proc/meminfo` 中的 `Buffers`)
|
||||
- `cache` - 页面缓存和 Slab 分配机制使用的内存(等同于 `/proc/meminfo` 中的 `Cached` 和 `Slab`)
|
||||
- `buff/cache` - `buffers` 与 `cache` 之和
|
||||
- `available` - 在不计算交换空间的情况下,预计可以被新启动的应用程序所使用的内存空间。与 `cache` 或者 `free` 部分不同,这一列把页面缓存计算在内,并且不是所有的可回收的 slab 内存都可以真正被回收,因为可能有被占用的部分。(等同于 `/proc/meminfo` 中的 `MemAvailable`;自内核 3.14 版本可用,自内核 2.6.27 版本开始模拟;在其他版本上这个值与 `free` 这一列相同)
|
||||
|
||||
### Q2. 如何更改显示的单位呢?
|
||||
|
||||
如果需要的话,你可以更改内存的显示单位。比如说,想要内存以兆为单位显示,你可以用 `-m` 这个参数:
|
||||
|
||||
```
|
||||
free -m
|
||||
```
|
||||
|
||||
[![free command display metrics change][5]][6]
|
||||
|
||||
同样地,你可以用 `-b` 以字节显示、`-k` 以 KB 显示、`-m` 以 MB 显示、`-g` 以 GB 显示、`--tera` 以 TB 显示。
|
||||
|
||||
### Q3. 怎么显示可读的结果呢?
|
||||
|
||||
`free` 命令提供了 `-h` 这个参数使输出转化为可读的格式。
|
||||
|
||||
```
|
||||
free -h
|
||||
```
|
||||
|
||||
用这个参数,`free` 命令会自己决定用什么单位显示内存的每个数值。例如:
|
||||
|
||||
[![diplsy data fromm free command in human readable form][7]][8]
|
||||
|
||||
### Q4. 怎么让 free 命令以一定的时间间隔持续运行?
|
||||
|
||||
您可以用 `-s` 这个参数让 `free` 命令以一定的时间间隔持续地执行。您需要传递给命令行一个数字参数,做为这个时间间隔的秒数。
|
||||
|
||||
例如,使 `free` 命令每隔 3 秒执行一次:
|
||||
|
||||
```
|
||||
free -s 3
|
||||
```
|
||||
|
||||
如果您需要 `free` 命令只执行几次,您可以用 `-c` 这个参数指定执行的次数:
|
||||
|
||||
```
|
||||
free -s 3 -c 5
|
||||
```
|
||||
|
||||
上面这条命令可以确保 `free` 命令每隔 3 秒执行一次,总共执行 5 次。
|
||||
|
||||
注:这个功能目前在 Ubuntu 系统上还存在 [问题][9],所以并未测试。
|
||||
|
||||
### Q5. 怎么使 free 基于 1000 计算内存,而不是 1024?
|
||||
|
||||
如果您指定 `free` 用 MB 来显示内存(用 `-m` 参数),但又想基于 1000 来计算结果,可以用 `--sj` 这个参数来实现。下图展示了用与不用这个参数的结果:
|
||||
|
||||
[![How to make free use power of 1000 \(not 1024\) while displaying memory figures][10]][11]
|
||||
|
||||
### Q6. 如何使 free 命令显示每一列的总和?
|
||||
|
||||
如果您想要 `free` 命令显示每一列的总和,你可以用 `-t` 这个参数。
|
||||
|
||||
```
|
||||
free -t
|
||||
```
|
||||
|
||||
如下图所示:
|
||||
|
||||
[![How to make free display total of columns][12]][13]
|
||||
|
||||
请注意 `Total` 这一行出现了。
|
||||
|
||||
### 总结
|
||||
|
||||
`free` 命令对于系统管理来讲是个极其有用的工具。它有很多参数可以定制化您的输出,易懂易用。我们在本文中也提到了很多有用的参数。练习完之后,请您移步至 [man 手册][14]了解更多内容。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.howtoforge.com/linux-free-command/
|
||||
|
||||
作者:[Himanshu Arora][a]
|
||||
译者:[jessie-pang](https://github.com/jessie-pang)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.howtoforge.com
|
||||
[1]:https://www.howtoforge.com/images/linux_free_command/free-command-output.png
|
||||
[2]:https://www.howtoforge.com/images/linux_free_command/big/free-command-output.png
|
||||
[3]:https://www.howtoforge.com/images/linux_free_command/free-output-columns.png
|
||||
[4]:https://www.howtoforge.com/images/linux_free_command/big/free-output-columns.png
|
||||
[5]:https://www.howtoforge.com/images/linux_free_command/free-m-option.png
|
||||
[6]:https://www.howtoforge.com/images/linux_free_command/big/free-m-option.png
|
||||
[7]:https://www.howtoforge.com/images/linux_free_command/free-h.png
|
||||
[8]:https://www.howtoforge.com/images/linux_free_command/big/free-h.png
|
||||
[9]:https://bugs.launchpad.net/ubuntu/+source/procps/+bug/1551731
|
||||
[10]:https://www.howtoforge.com/images/linux_free_command/free-si-option.png
|
||||
[11]:https://www.howtoforge.com/images/linux_free_command/big/free-si-option.png
|
||||
[12]:https://www.howtoforge.com/images/linux_free_command/free-t-option.png
|
||||
[13]:https://www.howtoforge.com/images/linux_free_command/big/free-t-option.png
|
||||
[14]:https://linux.die.net/man/1/free
|
81
published/20171011 What is a firewall.md
Normal file
81
published/20171011 What is a firewall.md
Normal file
@ -0,0 +1,81 @@
|
||||
什么是防火墙?
|
||||
=====
|
||||
|
||||
> 流行的防火墙是多数组织主要的边界防御。
|
||||
|
||||
![](https://images.techhive.com/images/article/2017/04/firewall-100716789-large.jpg)
|
||||
|
||||
基于网络的防火墙已经在美国企业无处不在,因为它们证实了抵御日益增长的威胁的防御能力。
|
||||
|
||||
通过网络测试公司 NSS 实验室最近的一项研究发现,高达 80% 的美国大型企业运行着下一代防火墙。研究公司 IDC 评估防火墙和相关的统一威胁管理市场的营业额在 2015 是 76 亿美元,预计到 2020 年底将达到 127 亿美元。
|
||||
|
||||
**如果你想升级,这里是《[当部署下一代防火墙时要考虑什么》][1]**
|
||||
|
||||
### 什么是防火墙?
|
||||
|
||||
防火墙作为一个边界防御工具,其监控流量——要么允许它、要么屏蔽它。 多年来,防火墙的功能不断增强,现在大多数防火墙不仅可以阻止已知的一些威胁、执行高级访问控制列表策略,还可以深入检查流量中的每个数据包,并测试包以确定它们是否安全。大多数防火墙都部署为用于处理流量的网络硬件,和允许终端用户配置和管理系统的软件。越来越多的软件版防火墙部署到高度虚拟化的环境中,以在被隔离的网络或 IaaS 公有云中执行策略。
|
||||
|
||||
随着防火墙技术的进步,在过去十年中创造了新的防火墙部署选择,所以现在对于部署防火墙的最终用户来说,有了更多选择。这些选择包括:
|
||||
|
||||
### 有状态的防火墙
|
||||
|
||||
当防火墙首次创造出来时,它们是无状态的,这意味着流量所通过的硬件当单独地检查被监视的每个网络流量包时,屏蔽或允许是隔离的。从 1990 年代中后期开始,防火墙的第一个主要进展是引入了状态。有状态防火墙在更全面的上下文中检查流量,同时考虑到网络连接的工作状态和特性,以提供更全面的防火墙。例如,维持这个状态的防火墙可以允许某些流量访问某些用户,同时对其他用户阻塞同一流量。
|
||||
|
||||
### 基于代理的防火墙
|
||||
|
||||
这些防火墙充当请求数据的最终用户和数据源之间的网关。在传递给最终用户之前,所有的流量都通过这个代理过滤。这通过掩饰信息的原始请求者的身份来保护客户端不受威胁。
|
||||
|
||||
### Web 应用防火墙(WAF)
|
||||
|
||||
这些防火墙位于特定应用的前面,而不是在更广阔的网络的入口或者出口上。基于代理的防火墙通常被认为是保护终端客户的,而 WAF 则被认为是保护应用服务器的。
|
||||
|
||||
### 防火墙硬件
|
||||
|
||||
防火墙硬件通常是一个简单的服务器,它可以充当路由器来过滤流量和运行防火墙软件。这些设备放置在企业网络的边缘,位于路由器和 Internet 服务提供商(ISP)的连接点之间。通常企业可能在整个数据中心部署十几个物理防火墙。 用户需要根据用户基数的大小和 Internet 连接的速率来确定防火墙需要支持的吞吐量容量。
|
||||
|
||||
### 防火墙软件
|
||||
|
||||
通常,终端用户部署多个防火墙硬件端和一个中央防火墙软件系统来管理该部署。 这个中心系统是配置策略和特性的地方,在那里可以进行分析,并可以对威胁作出响应。
|
||||
|
||||
### 下一代防火墙(NGFW)
|
||||
|
||||
多年来,防火墙增加了多种新的特性,包括深度包检查、入侵检测和防御以及对加密流量的检查。下一代防火墙(NGFW)是指集成了许多先进的功能的防火墙。
|
||||
|
||||
#### 有状态的检测
|
||||
|
||||
阻止已知不需要的流量,这是基本的防火墙功能。
|
||||
|
||||
#### 反病毒
|
||||
|
||||
在网络流量中搜索已知病毒和漏洞,这个功能有助于防火墙接收最新威胁的更新,并不断更新以保护它们。
|
||||
|
||||
#### 入侵防御系统(IPS)
|
||||
|
||||
这类安全产品可以部署为一个独立的产品,但 IPS 功能正逐步融入 NGFW。 虽然基本的防火墙技术可以识别和阻止某些类型的网络流量,但 IPS 使用更细粒度的安全措施,如签名跟踪和异常检测,以防止不必要的威胁进入公司网络。 这一技术的以前版本是入侵检测系统(IDS),其重点是识别威胁而不是遏制它们,已经被 IPS 系统取代了。
|
||||
|
||||
#### 深度包检测(DPI)
|
||||
|
||||
DPI 可作为 IPS 的一部分或与其结合使用,但其仍然成为一个 NGFW 的重要特征,因为它提供细粒度分析流量的能力,可以具体到流量包头和流量数据。DPI 还可以用来监测出站流量,以确保敏感信息不会离开公司网络,这种技术称为数据丢失防御(DLP)。
|
||||
|
||||
#### SSL 检测
|
||||
|
||||
安全套接字层(SSL)检测是一个检测加密流量来测试威胁的方法。随着越来越多的流量进行加密,SSL 检测成为 NGFW 正在实施的 DPI 技术的一个重要组成部分。SSL 检测作为一个缓冲区,它在送到最终目的地之前解码流量以检测它。
|
||||
|
||||
#### 沙盒
|
||||
|
||||
这个是被卷入 NGFW 中的一个较新的特性,它指防火墙接收某些未知的流量或者代码,并在一个测试环境运行,以确定它是否存在问题的能力。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3230457/lan-wan/what-is-a-firewall-perimeter-stateful-inspection-next-generation.html
|
||||
|
||||
作者:[Brandon Butler][a]
|
||||
译者:[zjon](https://github.com/zjon)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.networkworld.com/author/Brandon-Butler/
|
||||
[1]:https://www.networkworld.com/article/3236448/lan-wan/what-to-consider-when-deploying-a-next-generation-firewall.html
|
||||
|
||||
|
79
published/20171031 Migrating to Linux- An Introduction.md
Normal file
79
published/20171031 Migrating to Linux- An Introduction.md
Normal file
@ -0,0 +1,79 @@
|
||||
迁移到 Linux :入门介绍
|
||||
======
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/migrating-to-linux.jpg?itok=sjcGK0SY)
|
||||
|
||||
> 这个新文章系列将帮你从其他操作系统迁移到 Linux。
|
||||
|
||||
运行 Linux 的计算机系统到遍布在每个角落。Linux 运行着从谷歌搜索到“脸书”等等各种互联网服务。Linux 也在很多设备上运行,包括我们的智能手机、电视,甚至汽车。当然,Linux 也可以运行在您的桌面系统上。如果您是 Linux 新手,或者您想在您的桌面计算机上尝试一些不同的东西,这篇文章将简要地介绍其基础知识,并帮助您从另一个系统迁移到 Linux。
|
||||
|
||||
切换到不同的操作系统可能是一个挑战,因为每个操作系统都提供了不同的操作方法。其在一个系统上的<ruby>习惯<rt>second nature</rt></ruby>可能会对另一个系统的使用形成阻挠,因此我们需要到网上或书本上查找怎样操作。
|
||||
|
||||
### Windows 与 Linux 的区别
|
||||
|
||||
(LCTT 译注:本节标题 Vive la différence ,来自于法语,意即“差异万岁”——来自于 wiktionary)
|
||||
|
||||
要开始使用 Linux,您可能会注意到,Linux 的打包方式不同。在其他操作系统中,许多组件被捆绑在一起,只是该软件包的一部分。然而,在 Linux 中,每个组件都被分别调用。举个例子来说,在 Windows 下,图形界面只是操作系统的一部分。而在 Linux 下,您可以从多个图形环境中进行选择,比如 GNOME、KDE Plasma、Cinnamon 和 MATE 等。
|
||||
|
||||
从更高层面上看,一个 Linux 包括以下内容:
|
||||
|
||||
1. 内核
|
||||
2. 驻留在磁盘上的系统程序和文件
|
||||
3. 图形环境
|
||||
4. 包管理器
|
||||
5. 应用程序
|
||||
|
||||
### 内核
|
||||
|
||||
操作系统的核心称为<ruby>内核<rt>kernel</rt></ruby>。内核是引擎罩下的引擎。它允许多个应用程序同时运行,并协调它们对公共服务和设备的访问,从而使所有设备运行顺畅。
|
||||
|
||||
### 系统程序和文件
|
||||
|
||||
系统程序以标准的文件和目录的层次结构位于磁盘上。这些系统程序和文件包括后台运行的服务(称为<ruby>守护进程<rt>deamon</rt></ruby>)、用于各种操作的实用程序、配置文件和日志文件。
|
||||
|
||||
这些系统程序不是在内核中运行,而是执行基本系统操作的程序——例如,设置日期和时间,以及连接网络以便你可以上网。
|
||||
|
||||
这里包含了<ruby>初始化<rt>init</rt></ruby>程序——它是最初运行的程序。该程序负责启动所有后台服务(如 Web 服务器)、启动网络连接和启动图形环境。这个初始化程序将根据需要启动其它系统程序。
|
||||
|
||||
其他系统程序为简单的任务提供便利,比如添加用户和组、更改密码和配置磁盘。
|
||||
|
||||
### 图形环境
|
||||
|
||||
图形环境实际上只是更多的系统程序和文件。图形环境提供了常用的带有菜单的窗口、鼠标指针、对话框、状态和指示器等。
|
||||
|
||||
需要注意的是,您不是必须需要使用原本安装的图形环境。如果你愿意,你可以把它换成其它的。每个图形环境都有不同的特性。有些看起来更像 Apple OS X,有些看起来更像 Windows,有些则是独特的而不试图模仿其他的图形界面。
|
||||
|
||||
### 包管理器
|
||||
|
||||
对于来自不同操作系统的人来说,<ruby>包管理器<rt>package manager</rt></ruby>比较难以掌握,但是现在有一个人们非常熟悉的类似的系统——应用程序商店。软件包系统实际上就是 Linux 的应用程序商店。您可以使用包管理器来选择您想要的应用程序,而不是从一个网站安装这个应用程序,而从另一个网站来安装那个应用程序。然后,包管理器会从预先构建的开源应用程序的中心仓库安装应用程序。
|
||||
|
||||
### 应用程序
|
||||
|
||||
Linux 附带了许多预安装的应用程序。您可以从包管理器获得更多。许多应用程序相当棒,另外一些还需要改进。有时,同一个应用程序在 Windows 或 Mac OS 或 Linux 上运行的版本会不同。
|
||||
|
||||
例如,您可以使用 Firefox 浏览器和 Thunderbird (用于电子邮件)。您可以使用 LibreOffice 作为 Microsoft Office 的替代品,并通过 Valve 的 Steam 程序运行游戏。您甚至可以在 Linux 上使用 WINE 来运行一些 Windows 原生的应用程序。
|
||||
|
||||
### 安装 Linux
|
||||
|
||||
第一步通常是安装 Linux 发行版。你可能听说过 Red Hat、Ubuntu、Fedora、Arch Linux 和 SUSE,等等。这些都是 Linux 的不同发行版。
|
||||
|
||||
如果没有 Linux 发行版,则必须分别安装每个组件。许多组件是由不同人群开发和提供的,因此单独安装每个组件将是一项冗长而乏味的任务。幸运的是,构建发行版的人会为您做这项工作。他们抓取所有的组件,构建它们,确保它们可以在一起工作,然后将它们打包在一个单一的安装套件中。
|
||||
|
||||
各种发行版可能会做出不同的选择、使用不同的组件,但它仍然是 Linux。在一个发行版中开发的应用程序通常在其他发行版上运行的也很好。
|
||||
|
||||
如果你是一个 Linux 初学者,想尝试 Linux,我推荐[安装 Ubuntu][1]。还有其他的发行版也可以尝试: Linux Mint、Fedora、Debian、Zorin OS、Elementary OS 等等。在以后的文章中,我们将介绍 Linux 系统的其他方面,并提供关于如何开始使用 Linux 的更多信息。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/intro-to-linux/2017/10/migrating-linux-introduction
|
||||
|
||||
作者:[John Bonesio][a]
|
||||
译者:[stevenzdg988](https://github.com/stevenzdg988)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/johnbonesio
|
||||
[1]:https://www.ubuntu.com/download/desktop
|
||||
[2]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
57
published/201711/20141028 When Does Your OS Run.md
Normal file
57
published/201711/20141028 When Does Your OS Run.md
Normal file
@ -0,0 +1,57 @@
|
||||
操作系统何时运行?
|
||||
============================================================
|
||||
|
||||
请各位思考以下问题:在你阅读本文的这段时间内,计算机中的操作系统在**运行**吗?又或者仅仅是 Web 浏览器在运行?又或者它们也许均处于空闲状态,等待着你的指示?
|
||||
|
||||
这些问题并不复杂,但它们深入涉及到系统软件工作的本质。为了准确回答这些问题,我们需要透彻理解操作系统的行为模型,包括性能、安全和除错等方面。在该系列文章中,我们将以 Linux 为主举例来帮助你建立操作系统的行为模型,OS X 和 Windows 在必要的时候也会有所涉及。对那些深度探索者,我会在适当的时候给出 Linux 内核源码的链接。
|
||||
|
||||
这里有一个基本认知,就是,在任意给定时刻,某个 CPU 上仅有一个任务处于活动状态。大多数情形下这个任务是某个用户程序,例如你的 Web 浏览器或音乐播放器,但它也可能是一个操作系统线程。可以确信的是,它是**一个任务**,不是两个或更多,也不是零个,对,**永远**是一个。
|
||||
|
||||
这听上去可能会有些问题。比如,你的音乐播放器是否会独占 CPU 而阻止其它任务运行?从而使你不能打开任务管理工具去杀死音乐播放器,甚至让鼠标点击也失效,因为操作系统没有机会去处理这些事件。你可能会愤而喊出,“它究竟在搞什么鬼?”,并引发骚乱。
|
||||
|
||||
此时便轮到**中断**大显身手了。中断就好比,一声巨响或一次拍肩后,神经系统通知大脑去感知外部刺激一般。计算机主板上的[芯片组][1]同样会中断 CPU 运行以传递新的外部事件,例如键盘上的某个键被按下、网络数据包的到达、一次硬盘读取的完成,等等。硬件外设、主板上的中断控制器和 CPU 本身,它们共同协作实现了中断机制。
|
||||
|
||||
中断对于记录我们最珍视的资源——时间——也至关重要。计算机[启动过程][2]中,操作系统内核会设置一个硬件计时器以让其产生周期性**计时中断**,例如每隔 10 毫秒触发一次。每当计时中断到来,内核便会收到通知以更新系统统计信息和盘点如下事项:当前用户程序是否已运行了足够长时间?是否有某个 TCP 定时器超时了?中断给予了内核一个处理这些问题并采取合适措施的机会。这就好像你给自己设置了整天的周期闹铃并把它们用作检查点:我是否应该去做我正在进行的工作?是否存在更紧急的事项?直到你发现 10 年时间已逝去……
|
||||
|
||||
这些内核对 CPU 周期性的劫持被称为<ruby>滴答<rt>tick</rt></ruby>,也就是说,是中断让你的操作系统滴答了一下。不止如此,中断也被用作处理一些软件事件,如整数溢出和页错误,其中未涉及外部硬件。**中断是进入操作系统内核最频繁也是最重要的入口**。对于学习电子工程的人而言,这些并无古怪,它们是操作系统赖以运行的机制。
|
||||
|
||||
说到这里,让我们再来看一些实际情形。下图示意了 Intel Core i5 系统中的一个网卡中断。图片中的部分元素设置了超链,你可以点击它们以获取更为详细的信息,例如每个设备均被链接到了对应的 Linux 驱动源码。
|
||||
|
||||
![](http://duartes.org/gustavo/blog/img/os/hardware-interrupt.png)
|
||||
|
||||
链接如下:
|
||||
|
||||
- network card : https://github.com/torvalds/linux/blob/v3.17/drivers/net/ethernet/intel/e1000e/netdev.c
|
||||
- USB keyboard : https://github.com/torvalds/linux/blob/v3.16/drivers/hid/usbhid/usbkbd.c
|
||||
- I/O APIC : https://github.com/torvalds/linux/blob/v3.16/arch/x86/kernel/apic/io_apic.c
|
||||
- HPET : https://github.com/torvalds/linux/blob/v3.17/arch/x86/kernel/hpet.c
|
||||
|
||||
让我们来仔细研究下。首先,由于系统中存在众多中断源,如果硬件只是通知 CPU “嘿,这里发生了一些事情”然后什么也不做,则不太行得通。这会带来难以忍受的冗长等待。因此,计算机上电时,每个设备都被授予了一根**中断线**,或者称为 IRQ。这些 IRQ 然后被系统中的中断控制器映射成值介于 0 到 255 之间的**中断向量**。等到中断到达 CPU,它便具备了一个完好定义的数值,异于硬件的某些其它诡异行为。
|
||||
|
||||
相应地,CPU 中还存有一个由内核维护的指针,指向一个包含 255 个函数指针的数组,其中每个函数被用来处理某个特定的中断向量。后文中,我们将继续深入探讨这个数组,它也被称作**中断描述符表**(IDT)。
|
||||
|
||||
每当中断到来,CPU 会用中断向量的值去索引中断描述符表,并执行相应处理函数。这相当于,在当前正在执行任务的上下文中,发生了一个特殊函数调用,从而允许操作系统以较小开销快速对外部事件作出反应。考虑下述场景,Web 服务器在发送数据时,CPU 却间接调用了操作系统函数,这听上去要么很炫酷要么令人惊恐。下图展示了 Vim 编辑器运行过程中一个中断到来的情形。
|
||||
|
||||
![](http://duartes.org/gustavo/blog/img/os/vim-interrupted.png)
|
||||
|
||||
此处请留意,中断的到来是如何触发 CPU 到 [Ring 0][3] 内核模式的切换而未有改变当前活跃的任务。这看上去就像,Vim 编辑器直接面向操作系统内核产生了一次神奇的函数调用,但 Vim 还在那里,它的[地址空间][4]原封未动,等待着执行流返回。
|
||||
|
||||
这很令人振奋,不是么?不过让我们暂且告一段落吧,我需要合理控制篇幅。我知道还没有回答完这个开放式问题,甚至还实质上翻开了新的问题,但你至少知道了在你读这个句子的同时**滴答**正在发生。我们将在充实了对操作系统动态行为模型的理解之后再回来寻求问题的答案,对 Web 浏览器情形的理解也会变得清晰。如果你仍有问题,尤其是在这篇文章公诸于众后,请尽管提出。我将会在文章或后续评论中回答它们。下篇文章将于明天在 RSS 和 Twitter 上发布。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://duartes.org/gustavo/blog/post/when-does-your-os-run/
|
||||
|
||||
作者:[gustavo][a]
|
||||
译者:[Cwndmiao](https://github.com/Cwndmiao)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://duartes.org/gustavo/blog/about/
|
||||
[1]:http://duartes.org/gustavo/blog/post/motherboard-chipsets-memory-map
|
||||
[2]:http://duartes.org/gustavo/blog/post/kernel-boot-process
|
||||
[3]:http://duartes.org/gustavo/blog/post/cpu-rings-privilege-and-protection
|
||||
[4]:http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory
|
||||
[5]:http://feeds.feedburner.com/GustavoDuarte
|
||||
[6]:http://twitter.com/food4hackers
|
@ -1,27 +1,27 @@
|
||||
介绍 MOBY 项目:推进软件容器化运动的一个新的开源项目
|
||||
介绍 Moby 项目:推进软件容器化运动的一个新的开源项目
|
||||
============================================================
|
||||
|
||||
![Moby Project](https://i0.wp.com/blog.docker.com/wp-content/uploads/1-2.png?resize=763%2C275&ssl=1)
|
||||
|
||||
自从 Docker 四年前将软件容器推向民主化以来,整个生态系统都围绕着容器化而发展,在这段压缩的时期,它经历了两个不同的增长阶段。在这每一个阶段,生产容器系统的模式已经演变成适应用户群体以及项目的规模和需求和不断增长的贡献者生态系统。
|
||||
自从 Docker 四年前将软件容器推向大众化以来,整个生态系统都围绕着容器化而发展,在这段这么短的时期内,它经历了两个不同的增长阶段。在这每一个阶段,生产容器系统的模式已经随着项目和不断增长的容器生态系统而演变适应用户群体的规模和需求。
|
||||
|
||||
Moby 是一个新的开源项目,旨在推进软件容器化运动,帮助生态系统将容器作为主流。它提供了一个组件库,一个将它们组装到定制的基于容器的系统的框架,以及所有容器爱好者进行实验和交换想法的地方。
|
||||
Moby 是一个新的开源项目,旨在推进软件容器化运动,帮助生态系统将容器作为主流。它提供了一个组件库,一个将它们组装到定制的基于容器的系统的框架,也是所有容器爱好者进行实验和交换想法的地方。
|
||||
|
||||
让我们来回顾一下我们如何走到今天。在 2013-2014 年,开拓者开始使用容器,并在一个单一的开源代码库,Docker 和其他一些项目中进行协作,以帮助工具成熟。
|
||||
|
||||
![Docker Open Source](https://i0.wp.com/blog.docker.com/wp-content/uploads/2-2.png?resize=975%2C548&ssl=1)
|
||||
|
||||
然后在 2015-2016 年,云原生应用中大量采用容器用于生产环境。在这个阶段,用户社区已经发展到支持成千上万个部署,由数百个生态系统项目和成千上万的贡献者支持。正是在这个阶段,Docker 将其生产模式演变为基于开放式组件的方法。这样,它使我们能够增加创新和合作的方面。
|
||||
然后在 2015-2016 年,云原生应用中大量采用容器用于生产环境。在这个阶段,用户社区已经发展到支持成千上万个部署,由数百个生态系统项目和成千上万的贡献者支持。正是在这个阶段,Docker 将其产品模式演变为基于开放式组件的方法。这样,它使我们能够增加创新和合作的方面。
|
||||
|
||||
涌现出来的新独立的 Docker 组件项目帮助刺激了合作伙伴生态系统和用户社区的发展。在此期间,我们从 Docker 代码库中提取并快速创新组件,以便系统制造商可以在构建自己的容器系统时独立重用它们:[runc][7]、[HyperKit][8]、[VPNKit][9]、[SwarmKit][10]、[InfraKit][11]、[containerd][12] 等。
|
||||
涌现出来的新独立的 Docker 组件项目帮助促进了合作伙伴生态系统和用户社区的发展。在此期间,我们从 Docker 代码库中提取并快速创新组件,以便系统制造商可以在构建自己的容器系统时独立重用它们:[runc][7]、[HyperKit][8]、[VPNKit][9]、[SwarmKit][10]、[InfraKit][11]、[containerd][12] 等。
|
||||
|
||||
![Docker Open Components](https://i1.wp.com/blog.docker.com/wp-content/uploads/3-2.png?resize=975%2C548&ssl=1)
|
||||
|
||||
站在容器浪潮的最前沿,我们看到 2017 年出现的一个趋势是容器将成为主流,传播到计算、服务器、数据中心、云、桌面、物联网和移动的各个领域。每个行业和垂直市场、金融、医疗、政府、旅游、制造。以及每一个使用案例,现代网络应用、传统服务器应用、机器学习、工业控制系统、机器人技术。容器生态系统中许多新进入者的共同点是,它们建立专门的系统,针对特定的基础设施、行业或使用案例。
|
||||
站在容器浪潮的最前沿,我们看到 2017 年出现的一个趋势是容器将成为主流,传播到计算、服务器、数据中心、云、桌面、物联网和移动的各个领域。每个行业和垂直市场,金融、医疗、政府、旅游、制造。以及每一个使用案例,现代网络应用、传统服务器应用、机器学习、工业控制系统、机器人技术。容器生态系统中许多新进入者的共同点是,它们建立专门的系统,针对特定的基础设施、行业或使用案例。
|
||||
|
||||
作为一家公司,Docker 使用开源作为我们的创新实验室,而与整个生态系统合作。Docker 的成功取决于容器生态系统的成功:如果生态系统成功,我们就成功了。因此,我们一直在计划下一阶段的容器生态系统增长:什么样的生产模式将帮助我们扩大集容器生态系统,实现容器成为主流的承诺?
|
||||
作为一家公司,Docker 使用开源作为我们的创新实验室,而与整个生态系统合作。Docker 的成功取决于容器生态系统的成功:如果生态系统成功,我们就成功了。因此,我们一直在计划下一阶段的容器生态系统增长:什么样的产品模式将帮助我们扩大容器生态系统,以实现容器成为主流的承诺?
|
||||
|
||||
去年,我们的客户开始在 Linux 以外的许多平台上要求有 Docker:Mac 和 Windows 桌面、Windows Server、云平台(如亚马逊网络服务(AWS)、Microsoft Azure 或 Google 云平台),并且我们专门为这些平台创建了[许多 Docker 版本][13]。为了在一个相对较短的时间与更小的团队,以可扩展的方式构建和发布这些专业版本,而不必重新发明轮子,很明显,我们需要一个新的方法。我们需要我们的团队不仅在组件上进行协作,而且还在组件组合上进行协作,这借用[来自汽车行业的想法][14],其中组件被重用于构建完全不同的汽车。
|
||||
去年,我们的客户开始在 Linux 以外的许多平台上要求有 Docker:Mac 和 Windows 桌面、Windows Server、云平台(如亚马逊网络服务(AWS)、Microsoft Azure 或 Google 云平台),并且我们专门为这些平台创建了[许多 Docker 版本][13]。为了在一个相对较短的时间和更小的团队中,以可扩展的方式构建和发布这些专业版本,而不必重新发明轮子,很明显,我们需要一个新的方式。我们需要我们的团队不仅在组件上进行协作,而且还在组件组合上进行协作,这借用[来自汽车行业的想法][14],其中组件被重用于构建完全不同的汽车。
|
||||
|
||||
![Docker production model](https://i1.wp.com/blog.docker.com/wp-content/uploads/4-2.png?resize=975%2C548&ssl=1)
|
||||
|
||||
@ -29,15 +29,13 @@ Moby 是一个新的开源项目,旨在推进软件容器化运动,帮助生
|
||||
|
||||
![Moby Project](https://i0.wp.com/blog.docker.com/wp-content/uploads/5-2.png?resize=975%2C548&ssl=1)
|
||||
|
||||
为了实现这种新的合作高度,今天我们宣布推出软件容器化运动的新开源项目 Moby。它是提供了数十个组件的“乐高集”,一个将它们组合成定制容器系统的框架,以及所有容器爱好者进行试验和交换意见的场所。可以把 Moby 认为是容器系统的“乐高俱乐部”。
|
||||
为了实现这种新的合作高度,今天(2017 年 4 月 18 日)我们宣布推出软件容器化运动的新开源项目 Moby。它是提供了数十个组件的“乐高组件”,一个将它们组合成定制容器系统的框架,以及所有容器爱好者进行试验和交换意见的场所。可以把 Moby 认为是容器系统的“乐高俱乐部”。
|
||||
|
||||
Moby包括:
|
||||
|
||||
1. 容器化后端组件**库**(例如,底层构建器、日志记录设备、卷管理、网络、镜像管理、containerd、SwarmKit 等)
|
||||
Moby 包括:
|
||||
|
||||
1. 容器化后端组件**库**(例如,低层构建器、日志记录设备、卷管理、网络、镜像管理、containerd、SwarmKit 等)
|
||||
2. 将组件组合到独立容器平台中的**框架**,以及为这些组件构建、测试和部署构件的工具。
|
||||
|
||||
3. 一个名为 **Moby Origin** 的引用组件,它是 Docker 容器平台的开放基础,以及使用 Moby 库或其他项目的各种组件的容器系统示例。
|
||||
3. 一个名为 “Moby Origin” 的引用组件,它是 Docker 容器平台的开放基础,以及使用 Moby 库或其他项目的各种组件的容器系统示例。
|
||||
|
||||
Moby 专为系统构建者而设计,他们想要构建自己的基于容器的系统,而不是可以使用 Docker 或其他容器平台的应用程序开发人员。Moby 的参与者可以从源自 Docker 的组件库中进行选择,或者可以选择将“自己的组件”(BYOC)打包为容器,以便在所有组件之间进行混合和匹配以创建定制的容器系统。
|
||||
|
||||
@ -49,9 +47,9 @@ Docker 将 Moby 作为一个开放的研发实验室来试验、开发新的组
|
||||
|
||||
via: https://blog.docker.com/2017/04/introducing-the-moby-project/
|
||||
|
||||
作者:[Solomon Hykes ][a]
|
||||
作者:[Solomon Hykes][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,67 @@
|
||||
了解用于 Linux 和 Windows 容器的 Docker “容器主机”与“容器操作系统”
|
||||
=================
|
||||
|
||||
让我们来探讨一下“容器主机”和“容器操作系统”之间的关系,以及它们在 Linux 和 Windows 容器之间的区别。
|
||||
|
||||
### 一些定义
|
||||
|
||||
* <ruby>容器主机<rt>Container Host</rt></ruby>:也称为<ruby>主机操作系统<rt>Host OS</rt></ruby>。主机操作系统是 Docker 客户端和 Docker 守护程序在其上运行的操作系统。在 Linux 和非 Hyper-V 容器的情况下,主机操作系统与运行中的 Docker 容器共享内核。对于 Hyper-V,每个容器都有自己的 Hyper-V 内核。
|
||||
* <ruby>容器操作系统<rt>Container OS</rt></ruby>:也被称为<ruby>基础操作系统<rt>Base OS</rt></ruby>。基础操作系统是指包含操作系统如 Ubuntu、CentOS 或 windowsservercore 的镜像。通常情况下,你将在基础操作系统镜像之上构建自己的镜像,以便可以利用该操作系统的部分功能。请注意,Windows 容器需要一个基础操作系统,而 Linux 容器不需要。
|
||||
* <ruby>操作系统内核<rt>Operating System Kernel</rt></ruby>:内核管理诸如内存、文件系统、网络和进程调度等底层功能。
|
||||
|
||||
### 如下的一些图
|
||||
|
||||
![Linux Containers](http://floydhilton.com/images/2017/03/2017-03-31_14_50_13-Radom%20Learnings,%20Online%20Whiteboard%20for%20Visual%20Collaboration.png)
|
||||
|
||||
在上面的例子中:
|
||||
|
||||
* 主机操作系统是 Ubuntu。
|
||||
* Docker 客户端和 Docker 守护进程(一起被称为 Docker 引擎)正在主机操作系统上运行。
|
||||
* 每个容器共享主机操作系统内核。
|
||||
* CentOS 和 BusyBox 是 Linux 基础操作系统镜像。
|
||||
* “No OS” 容器表明你不需要基础操作系统以在 Linux 中运行一个容器。你可以创建一个含有 [scratch][1] 基础镜像的 Docker 文件,然后运行直接使用内核的二进制文件。
|
||||
* 查看[这篇][2]文章来比较基础 OS 的大小。
|
||||
|
||||
![Windows Containers - Non Hyper-V](http://floydhilton.com/images/2017/03/2017-03-31_15_04_03-Radom%20Learnings,%20Online%20Whiteboard%20for%20Visual%20Collaboration.png)
|
||||
|
||||
在上面的例子中:
|
||||
|
||||
* 主机操作系统是 Windows 10 或 Windows Server。
|
||||
* 每个容器共享主机操作系统内核。
|
||||
* 所有 Windows 容器都需要 [nanoserver][3] 或 [windowsservercore][4] 的基础操作系统。
|
||||
|
||||
![Windows Containers - Hyper-V](http://floydhilton.com/images/2017/03/2017-03-31_15_41_31-Radom%20Learnings,%20Online%20Whiteboard%20for%20Visual%20Collaboration.png)
|
||||
|
||||
在上面的例子中:
|
||||
|
||||
* 主机操作系统是 Windows 10 或 Windows Server。
|
||||
* 每个容器都托管在自己的轻量级 Hyper-V 虚拟机中。
|
||||
* 每个容器使用 Hyper-V 虚拟机内的内核,它在容器之间提供额外的分离层。
|
||||
* 所有 Windows 容器都需要 [nanoserver][5] 或 [windowsservercore][6] 的基础操作系统。
|
||||
|
||||
### 几个好的链接
|
||||
|
||||
* [关于 Windows 容器][7]
|
||||
* [深入实现 Windows 容器,包括多用户模式和“写时复制”来节省资源][8]
|
||||
* [Linux 容器如何通过使用“写时复制”来节省资源][9]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://floydhilton.com/docker/2017/03/31/Docker-ContainerHost-vs-ContainerOS-Linux-Windows.html
|
||||
|
||||
作者:[Floyd Hilton][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://floydhilton.com/about/
|
||||
[1]:https://hub.docker.com/_/scratch/
|
||||
[2]:https://www.brianchristner.io/docker-image-base-os-size-comparison/
|
||||
[3]:https://hub.docker.com/r/microsoft/nanoserver/
|
||||
[4]:https://hub.docker.com/r/microsoft/windowsservercore/
|
||||
[5]:https://hub.docker.com/r/microsoft/nanoserver/
|
||||
[6]:https://hub.docker.com/r/microsoft/windowsservercore/
|
||||
[7]:https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/
|
||||
[8]:http://blog.xebia.com/deep-dive-into-windows-server-containers-and-docker-part-2-underlying-implementation-of-windows-server-containers/
|
||||
[9]:https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/#the-copy-on-write-strategy
|
96
published/201711/20171017 Image Processing on Linux.md
Normal file
96
published/201711/20171017 Image Processing on Linux.md
Normal file
@ -0,0 +1,96 @@
|
||||
Linux 上的科学图像处理
|
||||
============================================================
|
||||
|
||||
在显示你的数据和工作方面我发现了几个科学软件,但是我不会涉及太多方面。因此在这篇文章中,我将谈到一款叫 ImageJ 的热门图像处理软件。特别的,我会介绍 [Fiji][4],这是一款绑定了一系列用于科学图像处理插件的 ImageJ 软件。
|
||||
|
||||
Fiji 这个名字是一个循环缩略词,很像 GNU 。代表着 “Fiji Is Just ImageJ”。 ImageJ 是科学研究领域进行图像分析的实用工具 —— 例如你可以用它来辨认航拍风景图中树的种类。 ImageJ 能划分物品种类。它以插件架构制成,海量插件可供选择以提升使用灵活度。
|
||||
|
||||
首先是安装 ImageJ (或 Fiji)。大多数的 ImageJ 发行版都可有该软件包。你愿意的话,可以以这种方式安装它,然后根据你的研究安装所需的独立插件。另一种选择是安装 Fiji 的同时获取最常用的插件。不幸的是,大多数 Linux 发行版的软件中心不会有可用的 Fiji 安装包。幸而,官网上的简单安装文件是可以使用的。这是一个 zip 文件,包含了运行 Fiji 需要的所有文件目录。第一次启动时,你只会看到一个列出了菜单项的工具栏。(图 1)
|
||||
|
||||
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif1.png)
|
||||
|
||||
*图 1. 第一次打开 Fiji 有一个最小化的界面。*
|
||||
|
||||
如果你没有备好图片来练习使用 ImageJ ,Fiji 安装包包含了一些示例图片。点击“File”->“Open Samples”的下拉菜单选项(图 2)。这些示例包含了许多你可能有兴趣做的任务。
|
||||
|
||||
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif2.jpg)
|
||||
|
||||
*图 2. 案例图片可供学习使用 ImageJ。*
|
||||
|
||||
如果你安装了 Fiji,而不是单纯的 ImageJ ,那么大量插件也会被安装。首先要注意的是自动更新器插件。每次打开 ImageJ ,该插件将联网检验 ImageJ 和已安装插件的更新。
|
||||
|
||||
所有已安装的插件都在“插件”菜单项中可选。一旦你安装了很多插件,列表会变得冗杂,所以需要精简你选择的插件。你想手动更新的话,点击“Help”->“Update Fiji” 菜单项强制检测并获取可用更新的列表(图 3)。
|
||||
|
||||
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif3.png)
|
||||
|
||||
*图 3. 强制手动检测可用更新。*
|
||||
|
||||
那么,现在,用 Fiji/ImageJ 可以做什么呢?举一例,统计图片中的物品数。你可以通过点击“File”->“Open Samples”->“Embryos”来载入示例。
|
||||
|
||||
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif4.jpg)
|
||||
|
||||
*图 4. 用 ImageJ 算出图中的物品数。*
|
||||
|
||||
第一步给图片设定比例,这样你可以告诉 ImageJ 如何判别物品。首先,选择在工具栏选择线条按钮。然后选择“Analyze”->“Set Scale”,然后就会设置比例尺包含的像素点个数(图 5)。你可以设置“known distance ”为 100,单元为“um”。
|
||||
|
||||
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif5.png)
|
||||
|
||||
*图 5. 很多图片分析任务需要对图片设定一个范围。*
|
||||
|
||||
接下来的步骤是简化图片内的信息。点击“Image”->“Type”->“8-bit”来减少信息量到 8 比特灰度图片。要分隔独立物体点击“Process”->“Binary”->“Make Binary”以自动设置图片门限。(图 6)。
|
||||
|
||||
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif6.png)
|
||||
|
||||
*图 6. 有些工具可以自动完成像门限一样的任务。*
|
||||
|
||||
图片内的物品计数前,你需要移除像比例尺之类的人工操作。可以用矩形选择工具来选中它并点击“Edit”->“Clear”来完成这项操作。现在你可以分析图片看看这里是啥物体。
|
||||
|
||||
确保图中没有区域被选中,点击“Analyze”->“Analyze Particles”来弹出窗口来选择最小尺寸,这决定了最后的图片会展示什么(图 7)。
|
||||
|
||||
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif7.png)
|
||||
|
||||
*图 7. 你可以通过确定最小尺寸生成一个缩减过的图片。 *
|
||||
|
||||
图 8 在总结窗口展示了一个概览。每个最小点也有独立的细节窗口。
|
||||
|
||||
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif8.png)
|
||||
|
||||
*图 8. 包含了已知最小点总览清单的输出结果。*
|
||||
|
||||
当你有一个分析程序可以工作于给定图片类型,你通常需要将相同的步骤应用到一系列图片当中。这可能数以千计,你当然不会想对每张图片手动重复操作。这时候,你可以集中必要步骤到宏,这样它们可以被应用多次。点击插件->“Macros”->“Record”,弹出一个新的窗口记录你随后的所有命令。所有步骤完成,你可以将之保存为一个宏文件,并且通过点击“Plugins”->“Macros”->“Run”来在其它图片上重复运行。
|
||||
|
||||
如果你有非常特定的工作步骤,你可以简单地打开宏文件并手动编辑它,因为它是一个简单的文本文件。事实上有一套完整的宏语言可供你更加充分地控制图片处理过程。
|
||||
|
||||
然而,如果你有真的有非常多的系列图片需要处理,这也将是冗长乏味的工作。这种情况下,前往“Process”->“Batch”->“Macro”,会弹出一个你可以设置批量处理工作的新窗口(图 9)。
|
||||
|
||||
![](http://www.linuxjournal.com/files/linuxjournal.com/ufiles/imagecache/large-550px-centered/u1000009/12172fijif9.png)
|
||||
|
||||
*图 9. 对批量输入的图片用单一命令运行宏。*
|
||||
|
||||
这个窗口中,你能选择应用哪个宏文件、输入图片所在的源目录和你想写入输出图片的输出目录。也可以设置输出文件格式,及通过文件名筛选输入图片中需要使用的。万事具备之后,点击窗口下方的的“Process”按钮开始批量操作。
|
||||
|
||||
若这是会重复多次的工作,你可以点击窗口底部的“Save”按钮保存批量处理到一个文本文件。点击也在窗口底部的“Open”按钮重新加载相同的工作。这个功能可以使得研究中最冗余部分自动化,这样你就可以在重点放在实际的科学研究中。
|
||||
|
||||
考虑到单单是 ImageJ 主页就有超过 500 个插件和超过 300 种宏可供使用,简短起见,我只能在这篇短文中提出最基本的话题。幸运的是,还有很多专业领域的教程可供使用,项目主页上还有关于 ImageJ 核心的非常棒的文档。如果你觉得这个工具对研究有用,你研究的专业领域也会有很多信息指引你。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
作者简介:
|
||||
|
||||
Joey Bernard 有物理学和计算机科学的相关背景。这对他在新不伦瑞克大学当计算研究顾问的日常工作大有裨益。他也教计算物理和并行程序规划。
|
||||
|
||||
--------------------------------
|
||||
|
||||
via: https://www.linuxjournal.com/content/image-processing-linux
|
||||
|
||||
作者:[Joey Bernard][a]
|
||||
译者:[XYenChi](https://github.com/XYenChi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linuxjournal.com/users/joey-bernard
|
||||
[1]:https://www.linuxjournal.com/tag/science
|
||||
[2]:https://www.linuxjournal.com/tag/statistics
|
||||
[3]:https://www.linuxjournal.com/users/joey-bernard
|
||||
[4]:https://imagej.net/Fiji
|
@ -0,0 +1,98 @@
|
||||
用 coredumpctl 更好地记录 bug
|
||||
===========
|
||||
|
||||
![](https://fedoramagazine.org/wp-content/uploads/2017/11/coredump.png-945x400.jpg)
|
||||
|
||||
一个不幸的事实是,所有的软件都有 bug,一些 bug 会导致系统崩溃。当它出现的时候,它经常会在磁盘上留下一个被称为“<ruby>核心转储<rt>core dump</rt></ruby>”的数据文件。该文件包含有关系统崩溃时的相关数据,可能有助于确定发生崩溃的原因。通常开发者要求提供 “<ruby>回溯<rt>backtrace</rt></ruby>” 形式的数据,以显示导致崩溃的指令流。开发人员可以使用它来修复 bug 以改进系统。如果系统发生了崩溃,以下是如何轻松生成 <ruby>回溯<rt>backtrace</rt></ruby> 的方法。
|
||||
|
||||
### 从使用 coredumpctl 开始
|
||||
|
||||
大多数 Fedora 系统使用[自动错误报告工具(ABRT)][2]来自动捕获崩溃文件并记录 bug。但是,如果你禁用了此服务或删除了该软件包,则此方法可能会有所帮助。
|
||||
|
||||
如果你遇到系统崩溃,请首先确保你运行的是最新的软件。更新通常包含修复程序,这些更新通常含有已经发现的会导致严重错误和崩溃的错误的修复。当你更新后,请尝试重现导致错误的情况。
|
||||
|
||||
如果崩溃仍然发生,或者你已经在运行最新的软件,那么可以使用有用的 `coredumpctl` 工具。此程序可帮助查找和处理崩溃。要查看系统上所有核心转储列表,请运行以下命令:
|
||||
|
||||
```
|
||||
coredumpctl list
|
||||
```
|
||||
|
||||
如果你看到比预期长的列表,请不要感到惊讶。有时系统组件在后台默默地崩溃,并自行恢复。快速查找今天的转储的简单方法是使用 `-since` 选项:
|
||||
|
||||
```
|
||||
coredumpctl list --since=today
|
||||
```
|
||||
|
||||
“PID” 列包含用于标识转储的进程 ID。请注意这个数字,因为你会之后再用到它。或者,如果你不想记住它,使用下面的命令将它赋值给一个变量:
|
||||
|
||||
```
|
||||
MYPID=<PID>
|
||||
```
|
||||
|
||||
要查看关于核心转储的信息,请使用此命令(使用 `$MYPID` 变量或替换 PID 编号):
|
||||
|
||||
```
|
||||
coredumpctl info $MYPID
|
||||
```
|
||||
|
||||
### 安装 debuginfo 包
|
||||
|
||||
在核心转储中的数据以及原始代码中的指令之间调试符号转义。这个符号数据可能相当大。与大多数用户运行在 Fedora 系统上的软件包不同,符号以 “debuginfo” 软件包的形式安装。要确定你必须安装哪些 debuginfo 包,请先运行以下命令:
|
||||
|
||||
```
|
||||
coredumpctl gdb $MYPID
|
||||
```
|
||||
|
||||
这可能会在屏幕上显示大量信息。最后一行可能会告诉你使用 `dnf` 安装更多的 debuginfo 软件包。[用 sudo ][3]运行该命令以安装:
|
||||
|
||||
```
|
||||
sudo dnf debuginfo-install <packages...>
|
||||
```
|
||||
|
||||
然后再次尝试 `coredumpctl gdb $MYPID` 命令。**你可能需要重复执行此操作**,因为其他符号会在回溯中展开。
|
||||
|
||||
### 捕获回溯
|
||||
|
||||
在调试器中运行以下命令以记录信息:
|
||||
|
||||
```
|
||||
set logging file mybacktrace.txt
|
||||
set logging on
|
||||
```
|
||||
|
||||
你可能会发现关闭分页有帮助。对于长的回溯,这可以节省时间。
|
||||
|
||||
```
|
||||
set pagination off
|
||||
```
|
||||
|
||||
现在运行回溯:
|
||||
|
||||
```
|
||||
thread apply all bt full
|
||||
```
|
||||
|
||||
现在你可以输入 `quit` 来退出调试器。`mybacktrace.txt` 包含可附加到 bug 或问题的追踪信息。或者,如果你正在与某人实时合作,则可以将文本上传到 pastebin。无论哪种方式,你现在可以向开发人员提供更多的帮助来解决问题。
|
||||
|
||||
---------------------------------
|
||||
|
||||
作者简介:
|
||||
|
||||
Paul W. Frields
|
||||
|
||||
Paul W. Frields 自 1997 年以来一直是 Linux 用户和爱好者,并于 2003 年在 Fedora 发布不久后加入 Fedora。他是 Fedora 项目委员会的创始成员之一,从事文档、网站发布、宣传、工具链开发和维护软件。他于 2008 年 2 月至 2010 年 7 月加入 Red Hat,担任 Fedora 项目负责人,现任红帽公司工程部经理。他目前和妻子和两个孩子住在弗吉尼亚州。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://fedoramagazine.org/file-better-bugs-coredumpctl/
|
||||
|
||||
作者:[Paul W. Frields][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://fedoramagazine.org/author/pfrields/
|
||||
[1]:https://fedoramagazine.org/file-better-bugs-coredumpctl/
|
||||
[2]:https://github.com/abrt/abrt
|
||||
[3]:https://fedoramagazine.org/howto-use-sudo/
|
102
published/201711/20171116 5 Coolest Linux Terminal Emulators.md
Normal file
102
published/201711/20171116 5 Coolest Linux Terminal Emulators.md
Normal file
@ -0,0 +1,102 @@
|
||||
5 款最酷的 Linux 终端模拟器
|
||||
============================================================
|
||||
|
||||
|
||||
![Cool retro term](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/banner2.png)
|
||||
|
||||
> Carla Schroder 正在看着那些她喜欢的终端模拟器, 包括展示在这儿的 Cool Retro Term。
|
||||
|
||||
虽然,我们可以继续使用老旧的 GNOME 终端、Konsole,以及好笑而孱弱的旧式 xterm。 不过,让我们带着尝试某种新东西的心境,回过头来看看 5 款酷炫并且实用的 Linux 终端。
|
||||
|
||||
### Xiki
|
||||
|
||||
首先我要推荐的第一个终端是 [Xiki][10]。 Xiki 是 Craig Muth 的智慧结晶,他是一个天才程序员,也是一个有趣的人(有趣在此处的意思是幽默,可能还有其它的意思)。 很久以前我在 [遇见 Xiki,Linux 和 Mac OS X 下革命性命令行 Shell][11] 一文中介绍过 Xiki。 Xiki 不仅仅是又一款终端模拟器;它也是一个扩展命令行用途、加快命令行速度的交互式环境。
|
||||
|
||||
视频: https://youtu.be/bUR_eUVcABg
|
||||
|
||||
Xiki 支持鼠标,并且在绝大多数命令行 Shell 上都支持。 它有大量的屏显帮助,而且可以使用鼠标和键盘快速导航。 它体现在速度上的一个简单例子就是增强了 `ls` 命令。 Xiki 可以快速穿过文件系统上的多层目录,而不用持续的重复输入 `ls` 或者 `cd`, 或者利用那些巧妙的正则表达式。
|
||||
|
||||
Xiki 可以与许多文本编辑器相集成, 提供了一个永久的便签, 有一个快速搜索引擎, 同时像他们所说的,还有许许多多的功能。 Xiki 是如此的有特色、如此的不同, 所以学习和了解它的最快的方式可以看 [Craig 的有趣和实用的视频][12]。
|
||||
|
||||
### Cool Retro Term
|
||||
|
||||
我推荐 [Cool Retro Term][13] (如题图显示) 主要因为它的外观,以及它的实用性。 它将我们带回了阴极射线管显示器的时代,这不算很久以前,而我也没有怀旧的意思,我死也不会放弃我的 LCD 屏幕。它基于 [Konsole][14], 因此有着 Konsole 的优秀功能。可以通过 Cool Retro Term 的配置文件菜单来改变它的外观。配置文件包括 Amber、Green、Pixelated、Apple 和 Transparent Green 等等,而且全都包括一个像真的一样的扫描线。并不是全都是有用的,例如 Vintage 配置文件看起来就像一个闪烁着的老旧的球面屏。
|
||||
|
||||
Cool Retro Term 的 GitHub 仓库有着详细的安装指南,且 Ubuntu 用户有 [PPA][15]。
|
||||
|
||||
### Sakura
|
||||
|
||||
你要是想要一个优秀的轻量级、易配置的终端,可以尝试下 [Sakura][16](图 1)。 它依赖少,不像 GNOME 终端 和 Konsole,在 GNOME 和 KDE 中牵扯了很多组件。其大多数选项是可以通过右键菜单配置的,例如选项卡的标签、 颜色、大小、选项卡的默认数量、字体、铃声,以及光标类型。 你可以在你个人的配置文件 `~/.config/sakura/sakura.conf` 里面设置更多的选项,例如绑定快捷键。
|
||||
|
||||
![sakura](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/fig-1_9.png)
|
||||
|
||||
*图 1: Sakura 是一个优秀的、轻量级的、可配置的终端。*
|
||||
|
||||
命令行选项详见 `man sakura`。可以使用这些来从命令行启动 sakura,或者在你的图形启动器上使用它们。 例如,打开 4 个选项卡并设置窗口标题为 “MyWindowTitle”:
|
||||
|
||||
```
|
||||
$ sakura -t MyWindowTitle -n 4
|
||||
```
|
||||
|
||||
### Terminology
|
||||
|
||||
[Terminology][17] 来自 Enlightenment 图形环境的郁葱可爱的世界,它能够被美化成任何你所想要的样子 (图 2)。 它有许多有用的功能:独立的拆分窗口、打开文件和 URL、文件图标、选项卡,林林总总。 它甚至能运行在没有图形界面的 Linux 控制台上。
|
||||
|
||||
![Terminology](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/fig-2_6.png)
|
||||
|
||||
*图 2: Terminology 也能够运行在没有图形界面的 Linux 控制台上。*
|
||||
|
||||
当你打开多个拆分窗口时,每个窗口都能设置不同的背景,并且背景文件可以是任意媒体文件:图像文件、视频或者音乐文件。它带有一堆便于清晰可读的暗色主题和透明主题,它甚至一个 Nyan 猫主题。它没有滚动条,因此需要使用组合键 `Shift+PageUp` 和 `Shift+PageDown` 进行上下导航。
|
||||
|
||||
它有多个控件:一个右键单击菜单,上下文对话框,以及命令行选项。右键单击菜单里包含世界上最小的字体,且 Miniview 可显示一个微观的文件树,但我没有找到可以使它们易于辨读的选项。当你打开多个标签时,可以点击小标签浏览器来打开一个可以上下滚动的选择器。任何东西都是可配置的;通过 `man terminology` 可以查看一系列的命令和选项,包括一批不错的快捷键快捷方式。奇怪的是,帮助里面没有包括以下命令,这是我偶然发现的:
|
||||
|
||||
* tyalpha
|
||||
* tybg
|
||||
* tycat
|
||||
* tyls
|
||||
* typop
|
||||
* tyq
|
||||
|
||||
使用 `tybg [filename]` 命令来设置背景,不带参数的 `tybg` 命令来移除背景。 运行 `typop [filename]` 来打开文件。 `tyls` 命令以图标视图列出文件。 加上 `-h` 选项运行这些命令可以了解它们是干什么的。 即使有可读性的怪癖,Terminology 依然是快速、漂亮和实用的。
|
||||
|
||||
### Tilda
|
||||
|
||||
已经有几个优秀的下拉式终端模拟器,包括 Guake 和 Yakuake。 [Tilda][18] (图 3) 是其中最简单和轻量级的一个。 打开 Tilda 后它会保持打开状态, 你可以通过快捷键来显示和隐藏它。 Tilda 快捷键是默认设置的, 你可以设置自己喜欢的快捷键。 它一直打开着的,随时准备工作,但是直到你需要它的时候才会出现。
|
||||
|
||||
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/fig-3_3.png)
|
||||
|
||||
*图 3: Tilda 是最简单和轻量级的一个终端模拟器。*
|
||||
|
||||
Tilda 选项方面有很好的补充,包括默认的大小、位置、外观、绑定键、搜索条、鼠标动作,以及标签条。 这些都被右键单击菜单控制。
|
||||
|
||||
_学习更多关于 Linux 的知识可以通过 Linux 基金会 和 edX 的免费课程 ["Linux 介绍" ][9]。_
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/learn/intro-to-linux/2017/11/5-coolest-linux-terminal-emulators
|
||||
|
||||
作者:[CARLA SCHRODER][a]
|
||||
译者:[cnobelw](https://github.com/cnobelw)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/cschroder
|
||||
[1]:https://www.linux.com/licenses/category/used-permission
|
||||
[2]:https://www.linux.com/licenses/category/used-permission
|
||||
[3]:https://www.linux.com/licenses/category/used-permission
|
||||
[4]:https://www.linux.com/licenses/category/used-permission
|
||||
[5]:https://www.linux.com/files/images/fig-1png-9
|
||||
[6]:https://www.linux.com/files/images/fig-2png-6
|
||||
[7]:https://www.linux.com/files/images/fig-3png-3
|
||||
[8]:https://www.linux.com/files/images/banner2png
|
||||
[9]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
||||
[10]:http://xiki.org/
|
||||
[11]:https://www.linux.com/learn/meet-xiki-revolutionary-command-shell-linux-and-mac-os-x
|
||||
[12]:http://xiki.org/screencasts/
|
||||
[13]:https://github.com/Swordfish90/cool-retro-term
|
||||
[14]:https://www.linux.com/learn/expert-tips-and-tricks-kate-and-konsole
|
||||
[15]:https://launchpad.net/~bugs-launchpad-net-falkensweb/+archive/ubuntu/cool-retro-term
|
||||
[16]:https://bugs.launchpad.net/sakura
|
||||
[17]:https://www.enlightenment.org/about-terminology
|
||||
[18]:https://github.com/lanoxx/tilda
|
@ -0,0 +1,92 @@
|
||||
如何轻松记住 Linux 命令
|
||||
=================
|
||||
|
||||
![](https://www.maketecheasier.com/assets/uploads/2017/10/rc-feat.jpg)
|
||||
|
||||
Linux 新手往往对命令行心存畏惧。部分原因是因为需要记忆大量的命令,毕竟掌握命令是高效使用命令行的前提。
|
||||
|
||||
不幸的是,学习这些命令并无捷径,然而在你开始学习命令之初,有些工具还是可以帮到你的。
|
||||
|
||||
### history
|
||||
|
||||
![Linux Bash History 命令](https://www.maketecheasier.com/assets/uploads/2017/10/rc-bash-history.jpg)
|
||||
|
||||
首先要介绍的是命令行工具 `history`,它能帮你记住那些你曾经用过的命令。包括应用最广泛的 Bash 在内的大多数 [Linux shell][1],都会创建一个历史文件来包含那些你输入过的命令。如果你用的是 Bash,这个历史文件就是 `/home/<username>/.bash_history`。
|
||||
|
||||
这个历史文件是纯文本格式的,你可以用任意的文本编辑器打开来浏览和搜索。
|
||||
|
||||
### apropos
|
||||
|
||||
确实存在一个可以帮你找到其他命令的命令。这个命令就是 `apropos`,它能帮你找出合适的命令来完成你的搜索。比如,假设你需要知道哪个命令可以列出目录的内容,你可以运行下面命令:
|
||||
|
||||
```shell
|
||||
apropos "list directory"
|
||||
```
|
||||
|
||||
![Linux Apropos](https://www.maketecheasier.com/assets/uploads/2017/10/rc-apropos.jpg)
|
||||
|
||||
这就搜索出结果了,非常直接。给 “directory” 加上复数后再试一下。
|
||||
|
||||
```shell
|
||||
apropos "list directories"
|
||||
```
|
||||
|
||||
这次没用了。`apropos` 所作的其实就是搜索一系列命令的描述。描述不匹配的命令不会纳入结果中。
|
||||
|
||||
还有其他的用法。通过 `-a` 标志,你可以以更灵活的方式来增加搜索关键字。试试这条命令:
|
||||
|
||||
```shell
|
||||
apropos "match pattern"
|
||||
```
|
||||
|
||||
![Linux Apropos -a Flag](https://www.maketecheasier.com/assets/uploads/2017/10/rc-apropos-a.jpg)
|
||||
|
||||
你会觉得应该会有一些匹配的内容出现,比如 [grep][2] 对吗? 然而,实际上并没有匹配出任何结果。再说一次,apropos 只会根据字面内容进行搜索。
|
||||
|
||||
现在让我们试着用 `-a` 标志来把单词分割开来。(LCTT 译注:该选项的意思是“and”,即多个关键字都存在,但是不需要正好是连在一起的字符串。)
|
||||
|
||||
```shell
|
||||
apropos "match" -a "pattern"
|
||||
```
|
||||
|
||||
这一下,你可以看到很多期望的结果了。
|
||||
|
||||
`apropos` 是一个很棒的工具,不过你需要留意它的缺陷。
|
||||
|
||||
### ZSH
|
||||
|
||||
![Linux ZSH Autocomplete](https://www.maketecheasier.com/assets/uploads/2017/10/rc-zsh.jpg)
|
||||
|
||||
ZSH 其实并不是用于记忆命令的工具。它其实是一种 shell。你可以用 [ZSH][3] 来替代 Bash 作为你的命令行 shell。ZSH 包含了自动纠错机制,能在你输入命令的时候给你予提示。开启该功能后,它会提示你相近的选择。在 ZSH 中你可以像往常一样使用命令行,同时你还能享受到极度安全的网络以及其他一些非常好用的特性。充分利用 ZSH 的最简单方法就是使用 [Oh-My-ZSH][4]。
|
||||
|
||||
### 速记表
|
||||
|
||||
最后,也可能是最间的方法就是使用 [速记表][5]。
|
||||
|
||||
有很多在线的速记表,比如[这个][6] 可以帮助你快速查询命令。
|
||||
|
||||
![linux-commandline-cheatsheet](https://www.maketecheasier.com/assets/uploads/2013/10/linux-commandline-cheatsheet.gif)
|
||||
|
||||
为了快速查询,你可以寻找图片格式的速记表,然后将它设置为你的桌面墙纸。
|
||||
|
||||
这并不是记忆命令的最好方法,但是这么做可以帮你节省在线搜索遗忘命令的时间。
|
||||
|
||||
在学习时依赖这些方法,最终你会发现你会越来越少地使用这些工具。没有人能够记住所有的事情,因此偶尔遗忘掉某些东西或者遇到某些没有见过的东西也很正常。这也是这些工具以及因特网存在的意义。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.maketecheasier.com/remember-linux-commands/
|
||||
|
||||
作者:[Nick Congleton][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.maketecheasier.com/author/nickcongleton/
|
||||
[1]: https://www.maketecheasier.com/alternative-linux-shells/
|
||||
[2]: https://www.maketecheasier.com/what-is-grep-and-uses/
|
||||
[3]: https://www.maketecheasier.com/understanding-the-different-shell-in-linux-zsh-shell/
|
||||
[4]: https://github.com/robbyrussell/oh-my-zsh
|
||||
[5]: https://www.maketecheasier.com/premium/cheatsheet/linux-command-line/
|
||||
[6]: https://www.cheatography.com/davechild/cheat-sheets/linux-command-line/
|
@ -0,0 +1,157 @@
|
||||
tmate:秒级分享你的终端会话
|
||||
=================
|
||||
|
||||
不久前,我们写过一篇关于 [teleconsole](https://www.2daygeek.com/teleconsole-share-terminal-session-instantly-to-anyone-in-seconds/) 的介绍,该工具可用于快速分享终端给任何人(任何你信任的人)。今天我们要聊一聊另一款类似的应用,名叫 `tmate`。
|
||||
|
||||
`tmate` 有什么用?它可以让你在需要帮助时向你的朋友们求助。
|
||||
|
||||
### 什么是 tmate?
|
||||
|
||||
[tmate](https://tmate.io/) 的意思是 `teammates`,它是 tmux 的一个分支,并且使用相同的配置信息(例如快捷键配置,配色方案等)。它是一个终端多路复用器,同时具有即时分享终端的能力。它允许在单个屏幕中创建并操控多个终端,同时这些终端还能与其他同事分享。
|
||||
|
||||
你可以分离会话,让作业在后台运行,然后在想要查看状态时重新连接会话。`tmate` 提供了一个即时配对的方案,让你可以与一个或多个队友共享一个终端。
|
||||
|
||||
在屏幕的地步有一个状态栏,显示了当前会话的一些诸如 ssh 命令之类的共享信息。
|
||||
|
||||
### tmate 是怎么工作的?
|
||||
|
||||
- 运行 `tmate` 时,会通过 `libssh` 在后台创建一个连接到 tmate.io (由 tmate 开发者维护的后台服务器)的 ssh 连接。
|
||||
- tmate.io 服务器的 ssh 密钥通过 DH 交换进行校验。
|
||||
- 客户端通过本地 ssh 密钥进行认证。
|
||||
- 连接创建后,本地 tmux 服务器会生成一个 150 位(不可猜测的随机字符)会话令牌。
|
||||
- 队友能通过用户提供的 SSH 会话 ID 连接到 tmate.io。
|
||||
|
||||
### 使用 tmate 的必备条件
|
||||
|
||||
由于 `tmate.io` 服务器需要通过本地 ssh 密钥来认证客户机,因此其中一个必备条件就是生成 SSH 密钥 key。
|
||||
记住,每个系统都要有自己的 SSH 密钥。
|
||||
|
||||
```shell
|
||||
$ ssh-keygen -t rsa
|
||||
Generating public/private rsa key pair.
|
||||
Enter file in which to save the key (/home/magi/.ssh/id_rsa):
|
||||
Enter passphrase (empty for no passphrase):
|
||||
Enter same passphrase again:
|
||||
Your identification has been saved in /home/magi/.ssh/id_rsa.
|
||||
Your public key has been saved in /home/magi/.ssh/id_rsa.pub.
|
||||
The key fingerprint is:
|
||||
SHA256:3ima5FuwKbWyyyNrlR/DeBucoyRfdOtlUmb5D214NC8 magi@magi-VirtualBox
|
||||
The key's randomart image is:
|
||||
+---[RSA 2048]----+
|
||||
| |
|
||||
| |
|
||||
| . |
|
||||
| . . = o |
|
||||
| *ooS= . + o |
|
||||
| . =.@*o.o.+ E .|
|
||||
| =o==B++o = . |
|
||||
| o.+*o+.. . |
|
||||
| ..o+o=. |
|
||||
+----[SHA256]-----+
|
||||
```
|
||||
|
||||
### 如何安装 tmate
|
||||
|
||||
`tmate` 已经包含在某些发行版的官方仓库中,可以通过包管理器来安装。
|
||||
|
||||
对于 Debian/Ubuntu,可以使用 [APT-GET 命令](https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/)或者 [APT 命令](https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/)to 来安装。
|
||||
|
||||
```shell
|
||||
$ sudo apt-get install software-properties-common
|
||||
$ sudo add-apt-repository ppa:tmate.io/archive
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install tmate
|
||||
```
|
||||
|
||||
你也可以从官方仓库中安装 tmate。
|
||||
|
||||
```shell
|
||||
$ sudo apt-get install tmate
|
||||
```
|
||||
|
||||
对于 Fedora,使用 [DNF 命令](https://www.2daygeek.com/dnf-command-examples-manage-packages-fedora-system/) 来安装。
|
||||
|
||||
```shell
|
||||
$ sudo dnf install tmate
|
||||
```
|
||||
|
||||
对于基于 Arch Linux 的系统,使用 []()[Yaourt 命令](https://www.2daygeek.com/install-yaourt-aur-helper-on-arch-linux/)或 []()[Packer 命令](https://www.2daygeek.com/install-packer-aur-helper-on-arch-linux/) 来从 AUR 仓库中安装。
|
||||
|
||||
```shell
|
||||
$ yaourt -S tmate
|
||||
```
|
||||
或
|
||||
|
||||
```shell
|
||||
$ packer -S tmate
|
||||
```
|
||||
|
||||
对于 openSUSE,使用 [Zypper 命令](https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/) 来安装。
|
||||
|
||||
```shell
|
||||
$ sudo zypper in tmate
|
||||
```
|
||||
|
||||
### 如何使用 tmate
|
||||
|
||||
成功安装后,打开终端然后输入下面命令,就会打开一个新的会话,在屏幕底部,你能看到 SSH 会话的 ID。
|
||||
|
||||
```shell
|
||||
$ tmate
|
||||
```
|
||||
|
||||
![](https://www.2daygeek.com/wp-content/uploads/2017/11/tmate-instantly-share-your-terminal-session-to-anyone-in-seconds-1.png)
|
||||
|
||||
要注意的是,SSH 会话 ID 会在几秒后消失,不过不要紧,你可以通过下面命令获取到这些详细信息。
|
||||
|
||||
```shell
|
||||
$ tmate show-messages
|
||||
```
|
||||
|
||||
`tmate` 的 `show-messages` 命令会显示 tmate 的日志信息,其中包含了该 ssh 连接内容。
|
||||
|
||||
![](https://www.2daygeek.com/wp-content/uploads/2017/11/tmate-instantly-share-your-terminal-session-to-anyone-in-seconds-2.png)
|
||||
|
||||
现在,分享你的 SSH 会话 ID 给你的朋友或同事从而允许他们观看终端会话。除了 SSH 会话 ID 以外,你也可以分享 web URL。
|
||||
|
||||
另外你还可以选择分享的是只读会话还是可读写会话。
|
||||
|
||||
### 如何通过 SSH 连接会话
|
||||
|
||||
只需要在终端上运行你从朋友那得到的 SSH 终端 ID 就行了。类似下面这样。
|
||||
|
||||
```shell
|
||||
$ ssh session: ssh 3KuRj95sEZRHkpPtc2y6jcokP@sg2.tmate.io
|
||||
```
|
||||
|
||||
![](https://www.2daygeek.com/wp-content/uploads/2017/11/tmate-instantly-share-your-terminal-session-to-anyone-in-seconds-4.png)
|
||||
|
||||
### 如何通过 Web URL 连接会话
|
||||
|
||||
打开浏览器然后访问朋友给你的 URL 就行了。像下面这样。
|
||||
|
||||
![](https://www.2daygeek.com/wp-content/uploads/2017/11/tmate-instantly-share-your-terminal-session-to-anyone-in-seconds-3.png)
|
||||
|
||||
|
||||
只需要输入 `exit` 就能退出会话了。
|
||||
|
||||
```
|
||||
[Source System Output]
|
||||
[exited]
|
||||
|
||||
[Remote System Output]
|
||||
[server exited]
|
||||
Connection to sg2.tmate.io closed by remote host。
|
||||
Connection to sg2.tmate.io closed。
|
||||
```
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.2daygeek.com/tmate-instantly-share-your-terminal-session-to-anyone-in-seconds/
|
||||
|
||||
作者:[Magesh Maruthamuthu][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -0,0 +1,166 @@
|
||||
通过实例学习 tcpdump 命令
|
||||
======
|
||||
|
||||
`tcpdump` 是一个很常用的网络包分析工具,可以用来显示通过网络传输到本系统的 TCP/IP 以及其他网络的数据包。`tcpdump` 使用 libpcap 库来抓取网络报,这个库在几乎在所有的 Linux/Unix 中都有。
|
||||
|
||||
`tcpdump` 可以从网卡或之前创建的数据包文件中读取内容,也可以将包写入文件中以供后续使用。必须是 root 用户或者使用 sudo 特权来运行 `tcpdump`。
|
||||
|
||||
在本文中,我们将会通过一些实例来演示如何使用 `tcpdump` 命令,但首先让我们来看看在各种 Linux 操作系统中是如何安装 `tcpdump` 的。
|
||||
|
||||
- 推荐阅读:[使用 iftop 命令监控网络带宽 ][1]
|
||||
|
||||
### 安装
|
||||
|
||||
`tcpdump` 默认在几乎所有的 Linux 发行版中都可用,但若你的 Linux 上没有的话,使用下面方法进行安装。
|
||||
|
||||
#### CentOS/RHEL
|
||||
|
||||
使用下面命令在 CentOS 和 RHEL 上安装 `tcpdump`,
|
||||
|
||||
```
|
||||
$ sudo yum install tcpdump*
|
||||
```
|
||||
|
||||
#### Fedora
|
||||
|
||||
使用下面命令在 Fedora 上安装 `tcpdump`:
|
||||
|
||||
```
|
||||
$ dnf install tcpdump
|
||||
```
|
||||
|
||||
#### Ubuntu/Debian/Linux Mint
|
||||
|
||||
在 Ubuntu/Debain/Linux Mint 上使用下面命令安装 `tcpdump`:
|
||||
|
||||
```
|
||||
$ apt-get install tcpdump
|
||||
```
|
||||
|
||||
安装好 `tcpdump` 后,现在来看一些例子。
|
||||
|
||||
### 案例演示
|
||||
|
||||
#### 从所有网卡中捕获数据包
|
||||
|
||||
运行下面命令来从所有网卡中捕获数据包:
|
||||
|
||||
```
|
||||
$ tcpdump -i any
|
||||
```
|
||||
|
||||
#### 从指定网卡中捕获数据包
|
||||
|
||||
要从指定网卡中捕获数据包,运行:
|
||||
|
||||
```
|
||||
$ tcpdump -i eth0
|
||||
```
|
||||
|
||||
#### 将捕获的包写入文件
|
||||
|
||||
使用 `-w` 选项将所有捕获的包写入文件:
|
||||
|
||||
```
|
||||
$ tcpdump -i eth1 -w packets_file
|
||||
```
|
||||
|
||||
#### 读取之前产生的 tcpdump 文件
|
||||
|
||||
使用下面命令从之前创建的 tcpdump 文件中读取内容:
|
||||
|
||||
```
|
||||
$ tcpdump -r packets_file
|
||||
```
|
||||
|
||||
#### 获取更多的包信息,并且以可读的形式显示时间戳
|
||||
|
||||
要获取更多的包信息同时以可读的形式显示时间戳,使用:
|
||||
|
||||
```
|
||||
$ tcpdump -ttttnnvvS
|
||||
```
|
||||
|
||||
#### 查看整个网络的数据包
|
||||
|
||||
要获取整个网络的数据包,在终端执行下面命令:
|
||||
|
||||
```
|
||||
$ tcpdump net 192.168.1.0/24
|
||||
```
|
||||
|
||||
#### 根据 IP 地址查看报文
|
||||
|
||||
要获取指定 IP 的数据包,不管是作为源地址还是目的地址,使用下面命令:
|
||||
|
||||
```
|
||||
$ tcpdump host 192.168.1.100
|
||||
```
|
||||
|
||||
要指定 IP 地址是源地址或是目的地址则使用:
|
||||
|
||||
```
|
||||
$ tcpdump src 192.168.1.100
|
||||
$ tcpdump dst 192.168.1.100
|
||||
```
|
||||
|
||||
#### 查看某个协议或端口号的数据包
|
||||
|
||||
要查看某个协议的数据包,运行下面命令:
|
||||
|
||||
```
|
||||
$ tcpdump ssh
|
||||
```
|
||||
|
||||
要捕获某个端口或一个范围的数据包,使用:
|
||||
|
||||
```
|
||||
$ tcpdump port 22
|
||||
$ tcpdump portrange 22-125
|
||||
```
|
||||
|
||||
我们也可以与 `src` 和 `dst` 选项连用来捕获指定源端口或指定目的端口的报文。
|
||||
|
||||
我们还可以使用“与” (`and`,`&&`)、“或” (`or`,`||` ) 和“非”(`not`,`!`) 来将两个条件组合起来。当我们需要基于某些条件来分析网络报文是非常有用。
|
||||
|
||||
#### 使用“与”
|
||||
|
||||
可以使用 `and` 或者符号 `&&` 来将两个或多个条件组合起来。比如:
|
||||
|
||||
```
|
||||
$ tcpdump src 192.168.1.100 && port 22 -w ssh_packets
|
||||
```
|
||||
|
||||
#### 使用“或”
|
||||
|
||||
“或”会检查是否匹配命令所列条件中的其中一条,像这样:
|
||||
|
||||
```
|
||||
$ tcpdump src 192.168.1.100 or dst 192.168.1.50 && port 22 -w ssh_packets
|
||||
$ tcpdump port 443 or 80 -w http_packets
|
||||
```
|
||||
|
||||
#### 使用“非”
|
||||
|
||||
当我们想表达不匹配某项条件时可以使用“非”,像这样:
|
||||
|
||||
```
|
||||
$ tcpdump -i eth0 src port not 22
|
||||
```
|
||||
|
||||
这会捕获 eth0 上除了 22 号端口的所有通讯。
|
||||
|
||||
我们的教程至此就结束了,在本教程中我们讲解了如何安装并使用 `tcpdump` 来捕获网络数据包。如有任何疑问或建议,欢迎留言。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://linuxtechlab.com/learn-use-tcpdump-command-examples/
|
||||
|
||||
作者:[Shusain][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://linuxtechlab.com/author/shsuain/
|
||||
[1]:http://linuxtechlab.com/monitoring-network-bandwidth-iftop-command/
|
@ -0,0 +1,98 @@
|
||||
如何解决 Linux 中“磁盘空间不足”的问题
|
||||
======
|
||||
|
||||
![](https://www.maketecheasier.com/assets/uploads/2017/10/no-space-feat.jpg)
|
||||
|
||||
明明有很多剩余空间,但 Linux 系统依然提示没有空间剩余。为什么会这样呢?Linux 偶尔会有一些令人沮丧的模糊的错误消息出现,而这就是其中一种。不过这种错误通常都是由某几种因素导致的。
|
||||
|
||||
### 通过 du 和 df 检查磁盘空间
|
||||
|
||||
在开始行动前,最好先检查一下是否磁盘上是否确实还有空间剩余。虽然桌面环境的工具也很不错,但命令行上的工具更直接,要好的多。
|
||||
|
||||
![Linux Filesystem du][1]
|
||||
|
||||
首先让我们看看 `du` 命令。用它来检查问题磁盘所在的挂载点目录。本文假设出问题的分区挂载点为根目录。
|
||||
|
||||
```
|
||||
sudo du -sh /
|
||||
```
|
||||
|
||||
![Linux Filesystem df][2]
|
||||
|
||||
由于它要遍历磁盘中的所有文件,因此需要花费一点时间。现在再让我们试试 `df`。
|
||||
|
||||
```
|
||||
sudo df -h
|
||||
```
|
||||
|
||||
把根目录和在其中挂载的文件系统加在这条命令的后面。比如,若你的有一个独立的磁盘挂载到 `/home`,那么除了根目录之外,你也需要把它加进来。使用空间的总和应该跟你 `du` 命令得到的结果接近。否则的话,就说明可能有已删除文件的文件被进程占用。
|
||||
|
||||
当然,这里主要专注点在于这些命令的结果是否要小于磁盘的大小。如果确实小于磁盘大小,那么很明显有很多地方不对劲。
|
||||
|
||||
**相关**:[使用 Agedu 分析硬盘空间使用状况 ][3]
|
||||
|
||||
### 可能的原因
|
||||
|
||||
这里列出了一些产生这种情况的主要原因。若你发现 `du` 和 `df` 的结果之间有差别,那么可以直接检查第一项原因。否则从第二项原因开始检查。
|
||||
|
||||
#### 已删除文件被进程所占用
|
||||
|
||||
有时,文件可能已经被删掉了,但有进程依然在使用它。在进程运行期间,Linux 不会释放该文件的存储空间。你需要找出这个进程然后重启这个进程。
|
||||
|
||||
![Check processes for deleted files][4]
|
||||
|
||||
使用下面命令来定位进程。
|
||||
|
||||
```
|
||||
sudo lsof / | grep deleted
|
||||
```
|
||||
|
||||
这应该会列出出问题的进程了,然后重启该进程。
|
||||
|
||||
```
|
||||
sudo systemctl restart service_name
|
||||
```
|
||||
|
||||
#### i 节点不够了
|
||||
|
||||
![Linux check filesystem inodes][5]
|
||||
|
||||
文件系统中有一些称为 “<ruby>i 节点<rt>inode</rt></ruby>” 的元数据,其用来保存文件的相关信息。很多文件系统中的 i 节点数量是固定的,因此很可能 i 节点已经耗尽了而文件系统本身还没有用完。你可以使用 `df` 来检查。
|
||||
|
||||
```
|
||||
sudo df -i /
|
||||
```
|
||||
|
||||
比较一下已用的 i 节点和总共的 i 节点数量。如果没有可用的 i 节点了,那么很不幸,你也无法扩充 i 节点。删除一些无用的和过期的文件来释放一些 i 节点吧。
|
||||
|
||||
#### 环块
|
||||
|
||||
最后一个很常见的问题就是坏的文件系统块。除非另有标记,否则操作系统很可能会认为这些块都是可用的,这会导致文件系统损坏或者硬盘坏死。最好是使用带 `-cc` 标志的 `fsck` 搜索并标记出这些块。记住,你不能使用正在使用的文件系统(LCTT 译注:即包含坏块的文件系统)中的 `fsck` 命令。你应该会要用到 live CD。
|
||||
|
||||
```
|
||||
sudo fsck -vcck /dev/sda2
|
||||
```
|
||||
|
||||
很明显,这里需要使用你想检查的磁盘路径取代命令中的磁盘位置。另外,要注意,这恐怕会花上很长一段时间。
|
||||
|
||||
**相关**:[使用 fsck 检查并修复你的文件系统 [Linux]][6]
|
||||
|
||||
希望这些方案能解决你的问题。这种问题在任何情况下都不是那么容易诊断的。但是,在运气好的情况下,你可以把文件系统清理干净并让你的硬盘再次正常工作。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.maketecheasier.com/fix-linux-no-space-left-on-device-error/
|
||||
|
||||
作者:[Nick Congleton][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.maketecheasier.com/author/nickcongleton/
|
||||
[1]:https://www.maketecheasier.com/assets/uploads/2017/10/no-space-du.jpg (Linux Filesystem du)
|
||||
[2]:https://www.maketecheasier.com/assets/uploads/2017/10/no-space-df.jpg (Linux Filesystem df)
|
||||
[3]:https://www.maketecheasier.com/agedu-analyze-hard-disk-space-usage-in-linux/ (Use Agedu to Analyze Hard Disk Space Usage in Linux)
|
||||
[4]:https://www.maketecheasier.com/assets/uploads/2017/10/no-space-process.jpg (Check processes for deleted files)
|
||||
[5]:https://www.maketecheasier.com/assets/uploads/2017/10/no-space-inode.jpg (Linux check filesystem inodes)
|
||||
[6]:https://www.maketecheasier.com/check-repair-filesystem-fsck-linux/ (Check and Repair Your Filesystem With fsck [Linux])
|
@ -0,0 +1,59 @@
|
||||
安全专家的需求正在快速增长
|
||||
============================================================
|
||||
|
||||
![security skills](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/security-skills.png?itok=IrwppCUw "security skills")
|
||||
|
||||
> 来自 Dice 和 Linux 基金会的“开源工作报告”发现,未来对具有安全经验的专业人员的需求很高。
|
||||
|
||||
对安全专业人员的需求是真实的。在 [Dice.com][4] 多达 75,000 个职位中,有 15% 是安全职位。[福布斯][6] 称:“根据网络安全数据工具 [CyberSeek][5],在美国每年有 4 万个信息安全分析师的职位空缺,雇主正在努力填补其他 20 万个与网络安全相关的工作。”我们知道,安全专家的需求正在快速增长,但感兴趣的程度还较低。
|
||||
|
||||
### 安全是要关注的领域
|
||||
|
||||
根据我的经验,很少有大学生对安全工作感兴趣,所以很多人把安全视为商机。入门级技术专家对业务分析师或系统分析师感兴趣,因为他们认为,如果想学习和应用核心 IT 概念,就必须坚持分析师工作或者更接近产品开发的工作。事实并非如此。
|
||||
|
||||
事实上,如果你有兴趣成为商业领导者,那么安全是要关注的领域 —— 作为一名安全专业人员,你必须端到端地了解业务,你必须看大局来给你的公司带来优势。
|
||||
|
||||
### 无所畏惧
|
||||
|
||||
分析师和安全工作并不完全相同。公司出于必要继续合并工程和安全工作。企业正在以前所未有的速度进行基础架构和代码的自动化部署,从而提高了安全作为所有技术专业人士日常生活的一部分的重要性。在我们的 [Linux 基金会的开源工作报告][7]中,42% 的招聘经理表示未来对有安全经验的专业人士的需求很大。
|
||||
|
||||
在安全方面从未有过更激动人心的时刻。如果你随时掌握最新的技术新闻,就会发现大量的事情与安全相关 —— 数据泄露、系统故障和欺诈。安全团队正在不断变化,快节奏的环境中工作。真正的挑战在于在保持甚至改进最终用户体验的同时,积极主动地进行安全性,发现和消除漏洞。
|
||||
|
||||
### 增长即将来临
|
||||
|
||||
在技术的任何方面,安全将继续与云一起成长。企业越来越多地转向云计算,这暴露出比组织里比过去更多的安全漏洞。随着云的成熟,安全变得越来越重要。
|
||||
|
||||
条例也在不断完善 —— 个人身份信息(PII)越来越广泛。许多公司都发现他们必须投资安全来保持合规,避免成为头条新闻。由于面临巨额罚款,声誉受损以及行政工作安全,公司开始越来越多地为安全工具和人员安排越来越多的预算。
|
||||
|
||||
### 培训和支持
|
||||
|
||||
即使你不选择一个专门的安全工作,你也一定会发现自己需要写安全的代码,如果你没有这个技能,你将开始一场艰苦的战斗。如果你的公司提供在工作中学习的话也是可以的,但我建议结合培训、指导和不断的实践。如果你不使用安全技能,你将很快在快速进化的恶意攻击的复杂性中失去它们。
|
||||
|
||||
对于那些寻找安全工作的人来说,我的建议是找到组织中那些在工程、开发或者架构领域最为强大的人员 —— 与他们和其他团队进行交流,做好实际工作,并且确保在心里保持大局。成为你的组织中一个脱颖而出的人,一个可以写安全的代码,同时也可以考虑战略和整体基础设施健康状况的人。
|
||||
|
||||
### 游戏最后
|
||||
|
||||
越来越多的公司正在投资安全性,并试图填补他们的技术团队的开放角色。如果你对管理感兴趣,那么安全是值得关注的地方。执行层领导希望知道他们的公司正在按规则行事,他们的数据是安全的,并且免受破坏和损失。
|
||||
|
||||
明智地实施和有战略思想的安全是受到关注的。安全对高管和消费者之类至关重要 —— 我鼓励任何对安全感兴趣的人进行培训和贡献。
|
||||
|
||||
_现在[下载][2]完整的 2017 年开源工作报告_
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/os-jobs-report/2017/11/security-jobs-are-hot-get-trained-and-get-noticed
|
||||
|
||||
作者:[BEN COLLEN][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/bencollen
|
||||
[1]:https://www.linux.com/licenses/category/used-permission
|
||||
[2]:http://bit.ly/2017OSSjobsreport
|
||||
[3]:https://www.linux.com/files/images/security-skillspng
|
||||
[4]:http://www.dice.com/
|
||||
[5]:http://cyberseek.org/index.html#about
|
||||
[6]:https://www.forbes.com/sites/jeffkauflin/2017/03/16/the-fast-growing-job-with-a-huge-skills-gap-cyber-security/#292f0a675163
|
||||
[7]:http://media.dice.com/report/the-2017-open-source-jobs-report-employers-prioritize-hiring-open-source-professionals-with-latest-skills/
|
87
published/20171120 Adopting Kubernetes step by step.md
Normal file
87
published/20171120 Adopting Kubernetes step by step.md
Normal file
@ -0,0 +1,87 @@
|
||||
一步步采用 Kubernetes
|
||||
============================================================
|
||||
|
||||
### 为什么选择 Docker 和 Kubernetes 呢?
|
||||
|
||||
容器允许我们构建、发布和运行分布式应用。它们使应用程序摆脱了机器限制,可以让我们以一定的方式创建一个复杂的应用程序。
|
||||
|
||||
使用容器编写应用程序可以使开发、QA 更加接近生产环境(如果你努力这样做的话)。通过这样做,可以更快地发布修改,并且可以更快地测试整个系统。
|
||||
|
||||
[Docker][1] 这个容器式平台就是为此为生,可以使软件独立于云提供商。
|
||||
|
||||
但是,即使使用容器,移植应用程序到任何一个云提供商(或私有云)所需的工作量也是不可忽视的。应用程序通常需要自动伸缩组、持久远程磁盘、自动发现等。但是每个云提供商都有不同的机制。如果你想使用这些功能,很快你就会变的依赖于云提供商。
|
||||
|
||||
这正是 [Kubernetes][2] 登场的时候。它是一个容器<ruby>编排<rt>orchestration</rt></ruby>系统,它允许您以一定的标准管理、缩放和部署应用程序的不同部分,并且成为其中的重要工具。它的可移植抽象层兼容主要云的提供商(Google Cloud,Amazon Web Services 和 Microsoft Azure 都支持 Kubernetes)。
|
||||
|
||||
可以这样想象一下应用程序、容器和 Kubernetes。应用程序可以视为一条身边的鲨鱼,它存在于海洋中(在这个例子中,海洋就是您的机器)。海洋中可能还有其他一些宝贵的东西,但是你不希望你的鲨鱼与小丑鱼有什么关系。所以需要把你的鲨鱼(你的应用程序)移动到一个密封的水族馆中(容器)。这很不错,但不是特别的健壮。你的水族馆可能会被打破,或者你想建立一个通道连接到其他鱼类生活的另一个水族馆。也许你想要许多这样的水族馆,以防需要清洁或维护……这正是应用 Kubernetes 集群的作用。
|
||||
|
||||
![](https://cdn-images-1.medium.com/max/1600/1*OVt8cnY1WWOqdLFycCgdFg.jpeg)
|
||||
|
||||
*进化到 Kubernetes*
|
||||
|
||||
主流云提供商对 Kubernetes 提供了支持,从开发环境到生产环境,它使您和您的团队能够更容易地拥有几乎相同的环境。这是因为 Kubernetes 不依赖专有软件、服务或基础设施。
|
||||
|
||||
事实上,您可以在您的机器中使用与生产环境相同的部件启动应用程序,从而缩小了开发和生产环境之间的差距。这使得开发人员更了解应用程序是如何构建在一起的,尽管他们可能只负责应用程序的一部分。这也使得在开发流程中的应用程序更容易的快速完成测试。
|
||||
|
||||
### 如何使用 Kubernetes 工作?
|
||||
|
||||
随着更多的人采用 Kubernetes,新的问题出现了;应该如何针对基于集群环境进行开发?假设有 3 个环境,开发、质量保证和生产, 他们如何适应 Kubernetes?这些环境之间仍然存在着差异,无论是在开发周期(例如:在运行中的应用程序中我的代码的变化上花费时间)还是与数据相关的(例如:我不应该在我的质量保证环境中测试生产数据,因为它里面有敏感信息)。
|
||||
|
||||
那么,我是否应该总是在 Kubernetes 集群中编码、构建映像、重新部署服务,在我编写代码时重新创建部署和服务?或者,我是否不应该尽力让我的开发环境也成为一个 Kubernetes 集群(或一组集群)呢?还是,我应该以混合方式工作?
|
||||
|
||||
![](https://cdn-images-1.medium.com/max/1600/1*MXokxD8Ktte4_vWvTas9uw.jpeg)
|
||||
|
||||
*用本地集群进行开发*
|
||||
|
||||
如果继续我们之前的比喻,上图两边的洞表示当使其保持在一个开发集群中的同时修改应用程序的一种方式。这通常通过[卷][4]来实现
|
||||
|
||||
### Kubernetes 系列
|
||||
|
||||
本 Kubernetes 系列资源是开源的,可以在这里找到: [https://github.com/red-gate/ks][5] 。
|
||||
|
||||
我们写这个系列作为以不同的方式构建软件的练习。我们试图约束自己在所有环境中都使用 Kubernetes,以便我们可以探索这些技术对数据和数据库的开发和管理造成影响。
|
||||
|
||||
这个系列从使用 Kubernetes 创建基本的 React 应用程序开始,并逐渐演变为能够覆盖我们更多开发需求的系列。最后,我们将覆盖所有应用程序的开发需求,并且理解在数据库生命周期中如何最好地迎合容器和集群。
|
||||
|
||||
以下是这个系列的前 5 部分:
|
||||
|
||||
1. ks1:使用 Kubernetes 构建一个 React 应用程序
|
||||
2. ks2:使用 minikube 检测 React 代码的更改
|
||||
3. ks3:添加一个提供 API 的 Python Web 服务器
|
||||
4. ks4:使 minikube 检测 Python 代码的更改
|
||||
5. ks5:创建一个测试环境
|
||||
|
||||
本系列的第二部分将添加一个数据库,并尝试找出最好的方式来开发我们的应用程序。
|
||||
|
||||
通过在各种环境中运行 Kubernetes,我们被迫在解决新问题的同时也尽量保持开发周期。我们不断尝试 Kubernetes,并越来越习惯它。通过这样做,开发团队都可以对生产环境负责,这并不困难,因为所有环境(从开发到生产)都以相同的方式进行管理。
|
||||
|
||||
### 下一步是什么?
|
||||
|
||||
我们将通过整合数据库和练习来继续这个系列,以找到使用 Kubernetes 获得数据库生命周期的最佳体验方法。
|
||||
|
||||
这个 Kubernetes 系列是由 Redgate 研发部门 Foundry 提供。我们正在努力使数据和容器的管理变得更加容易,所以如果您正在处理数据和容器,我们希望听到您的意见,请直接联系我们的开发团队。 [_foundry@red-gate.com_][6]
|
||||
|
||||
* * *
|
||||
|
||||
我们正在招聘。您是否有兴趣开发产品、创建[未来技术][7] 并采取类似创业的方法(没有风险)?看看我们的[软件工程师 - 未来技术][8]的角色吧,并阅读更多关于在 [英国剑桥][9]的 Redgate 工作的信息。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://medium.com/ingeniouslysimple/adopting-kubernetes-step-by-step-f93093c13dfe
|
||||
|
||||
作者:[santiago arias][a]
|
||||
译者:[aiwhj](https://github.com/aiwhj)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://medium.com/@santiaago?source=post_header_lockup
|
||||
[1]:https://www.docker.com/what-docker
|
||||
[2]:https://kubernetes.io/
|
||||
[3]:https://www.google.co.uk/search?biw=723&bih=753&tbm=isch&sa=1&ei=p-YCWpbtN8atkwWc8ZyQAQ&q=nemo+fish&oq=nemo+fish&gs_l=psy-ab.3..0i67k1l2j0l2j0i67k1j0l5.5128.9271.0.9566.9.9.0.0.0.0.81.532.9.9.0....0...1.1.64.psy-ab..0.9.526...0i7i30k1j0i7i10i30k1j0i13k1j0i10k1.0.FbAf9xXxTEM
|
||||
[4]:https://kubernetes.io/docs/concepts/storage/volumes/
|
||||
[5]:https://github.com/red-gate/ks
|
||||
[6]:mailto:foundry@red-gate.com
|
||||
[7]:https://www.red-gate.com/foundry/
|
||||
[8]:https://www.red-gate.com/our-company/careers/current-opportunities/software-engineer-future-technologies
|
||||
[9]:https://www.red-gate.com/our-company/careers/living-in-cambridge
|
@ -0,0 +1,82 @@
|
||||
直接保存文件至 Google Drive 并用十倍的速度下载回来
|
||||
=============
|
||||
|
||||
![][image-1]
|
||||
|
||||
最近我不得不给我的手机下载更新包,但是当我开始下载的时候,我发现安装包过于庞大。大约有 1.5 GB。
|
||||
|
||||
![使用 Chrome 下载 MIUI 更新][image-2]
|
||||
|
||||
考虑到这个下载速度至少需要花费 1 至 1.5 小时来下载,并且说实话我并没有这么多时间。现在我下载速度可能会很慢,但是我的 ISP 有 Google Peering (Google 对等操作)。这意味着我可以在所有的 Google 产品中获得一个惊人的速度,例如Google Drive, YouTube 和 PlayStore。
|
||||
|
||||
所以我找到一个网络服务叫做 [savetodrive][2]。这个网站可以从网页上直接保存文件到你的 Google Drive 文件夹之中。之后你就可以从你的 Google Drive 上面下载它,这样的下载速度会快很多。
|
||||
|
||||
现在让我们来看看如何操作。
|
||||
|
||||
### 第一步
|
||||
|
||||
获得文件的下载链接,将它复制到你的剪贴板。
|
||||
|
||||
### 第二步
|
||||
|
||||
前往链接 [savetodrive][2] 并且点击相应位置以验证身份。
|
||||
|
||||
![savetodrive 将文件保存到 Google Drive ][image-3]
|
||||
|
||||
这将会请求获得使用你 Google Drive 的权限,点击 “Allow”。
|
||||
|
||||
![请求获得 Google Drive 的使用权限][image-4]
|
||||
|
||||
### 第三步
|
||||
|
||||
你将会再一次看到下面的页面,此时仅仅需要输入下载链接在链接框中,并且点击 “Upload”。
|
||||
|
||||
![savetodrive 直接给 Google Drive 上传文件][image-5]
|
||||
|
||||
你将会开始看到上传进度条,可以看到上传速度达到了 48 Mbps,所以上传我这个 1.5 GB 的文件需要 30 至 35 秒。一旦这里完成了,进入你的 Google Drive 你就可以看到刚才上传的文件。
|
||||
|
||||
![Google Drive savetodrive][image-6]
|
||||
|
||||
这里的文件中,文件名开头是 *miui* 的就是我刚才上传的,现在我可以用一个很快的速度下载下来。
|
||||
|
||||
![如何从浏览器上下载 MIUI 更新][image-7]
|
||||
|
||||
可以看到我的下载速度大概是 5 Mbps ,所以我下载这个文件只需要 5 到 6 分钟。
|
||||
|
||||
所以就是这样的,我经常用这样的方法下载文件,最令人惊讶的是,这个服务是完全免费的。
|
||||
|
||||
----
|
||||
|
||||
|
||||
|
||||
via: http://www.theitstuff.com/save-files-directly-google-drive-download-10-times-faster
|
||||
|
||||
作者:[Rishabh Kandari](http://www.theitstuff.com/author/reevkandari)
|
||||
译者:[Drshu][10]
|
||||
校对:[wxy][11]
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
|
||||
|
||||
[1]: http://www.theitstuff.com/wp-content/uploads/2017/11/Save-Files-Directly-To-Google-Drive-And-Download-10-Times-Faster.jpg
|
||||
[2]: https://savetodrive.net/
|
||||
[3]: http://www.savetodrive.net
|
||||
[4]: http://www.theitstuff.com/wp-content/uploads/2017/10/3-1.png
|
||||
[5]: http://www.theitstuff.com/wp-content/uploads/2017/10/authenticate-google-account.jpg
|
||||
[6]: http://www.theitstuff.com/wp-content/uploads/2017/10/6-2.png
|
||||
[7]: http://www.theitstuff.com/wp-content/uploads/2017/10/7-2-e1508772046583.png
|
||||
[8]: http://www.theitstuff.com/wp-content/uploads/2017/10/8-e1508772110385.png
|
||||
[9]: http://www.theitstuff.com/author/reevkandari
|
||||
[10]: https://github.com/Drshu
|
||||
[11]: https://github.com/wxy
|
||||
[12]: https://github.com/LCTT/TranslateProject
|
||||
[13]: https://linux.cn/
|
||||
|
||||
[image-1]: http://www.theitstuff.com/wp-content/uploads/2017/11/Save-Files-Directly-To-Google-Drive-And-Download-10-Times-Faster.jpg
|
||||
[image-2]: http://www.theitstuff.com/wp-content/uploads/2017/10/1-2-e1508771706462.png
|
||||
[image-3]: http://www.theitstuff.com/wp-content/uploads/2017/10/3-1.png
|
||||
[image-4]: http://www.theitstuff.com/wp-content/uploads/2017/10/authenticate-google-account.jpg
|
||||
[image-5]: http://www.theitstuff.com/wp-content/uploads/2017/10/6-2.png
|
||||
[image-6]: http://www.theitstuff.com/wp-content/uploads/2017/10/7-2-e1508772046583.png
|
||||
[image-7]: http://www.theitstuff.com/wp-content/uploads/2017/10/8-e1508772110385.png
|
@ -0,0 +1,113 @@
|
||||
迁移到 Linux:磁盘、文件、和文件系统
|
||||
============================================================
|
||||
|
||||
![Migrating to LInux ](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/butterflies-807551_1920.jpg?itok=pxTxwvFO "Migrating to LInux ")
|
||||
|
||||
> 在你的主要桌面计算机上安装和使用 Linux 将帮你快速熟悉你需要的工具和方法。
|
||||
|
||||
这是我们的迁移到 Linux 系列文章的第二篇。如果你错过了第一篇,[你可以在这里找到它][4]。就如之前提到过的,为什么要迁移到 Linux 的有几个原因。你可以在你的工作中为 Linux 开发和使用代码,或者,你可能只是想去尝试一下新事物。
|
||||
|
||||
不论是什么原因,在你主要使用的桌面计算机上拥有一个 Linux,将帮助你快速熟悉你需要的工具和方法。在这篇文章中,我将介绍 Linux 的文件、文件系统和磁盘。
|
||||
|
||||
### 我的 C:\ 在哪里?
|
||||
|
||||
如果你是一个 Mac 用户,Linux 对你来说应该非常熟悉,Mac 使用的文件、文件系统、和磁盘与 Linux 是非常接近的。另一方面,如果你的使用经验主要是 Windows,访问 Linux 下的磁盘可能看上去有点困惑。一般,Windows 给每个磁盘分配一个盘符(像 C:\)。而 Linux 并不是这样。而在你的 Linux 系统中它是一个单一的文件和目录的层次结构。
|
||||
|
||||
让我们看一个示例。假设你的计算机使用了一个主硬盘、一个有 `Books` 和 `Videos` 目录的 CD-ROM 、和一个有 `Transfer` 目录的 U 盘,在你的 WIndows 下,你应该看到的是下面的样子:
|
||||
|
||||
```
|
||||
C:\ [硬盘]
|
||||
├ System
|
||||
├ System32
|
||||
├ Program Files
|
||||
├ Program Files (x86)
|
||||
└ <更多目录>
|
||||
|
||||
D:\ [CD-ROM]
|
||||
├ Books
|
||||
└ Videos
|
||||
|
||||
E:\ [U 盘]
|
||||
└ Transfer
|
||||
```
|
||||
|
||||
而一个典型的 Linux 系统却是这样:
|
||||
|
||||
```
|
||||
/ (最顶级的目录,称为根目录) [硬盘]
|
||||
├ bin
|
||||
├ etc
|
||||
├ lib
|
||||
├ sbin
|
||||
├ usr
|
||||
├ <更多目录>
|
||||
└ media
|
||||
└ <你的用户名>
|
||||
├ cdrom [CD-ROM]
|
||||
│ ├ Books
|
||||
│ └ Videos
|
||||
└ Kingme_USB [U 盘]
|
||||
└ Transfer
|
||||
```
|
||||
|
||||
如果你使用一个图形化环境,通常,Linux 中的文件管理器将出现看起来像驱动器的图标的 CD-ROM 和 USB 便携式驱动器,因此,你根本就无需知道介质所在的目录。
|
||||
|
||||
### 文件系统
|
||||
|
||||
Linux 称这些东西为文件系统。文件系统是在介质(比如,硬盘)上保持跟踪所有的文件和目录的一组结构。如果没有用于存储数据的文件系统,我们所有的信息就会混乱,我们就不知道哪个块属于哪个文件。你可能听到过一些类似 ext4、XFS 和 Btrfs 之类的名字,这些都是 Linux 文件系统。
|
||||
|
||||
每种保存有文件和目录的介质都有一个文件系统在上面。不同的介质类型可能使用了为它优化过的特定的文件系统。比如,CD-ROM 使用 ISO9660 或者 UDF 文件系统类型。USB 便携式驱动器一般使用 FAT32,以便于它们可以很容易去与其它计算机系统共享。
|
||||
|
||||
Windows 也使用文件系统。不过,我们不会过多的讨论它。例如,当你插入一个 CD-ROM,Windows 将读取 ISO9660 文件系统结构,分配一个盘符给它,然后,在盘符(比如,D:\)下显示文件和目录。当然,如果你深究细节,从技术角度说,Windows 是分配一个盘符给一个文件系统,而不是整个驱动器。
|
||||
|
||||
使用同样的例子,Linux 也读取 ISO9660 文件系统结构,但它不分配盘符,它附加文件系统到一个目录(这个过程被称为<ruby>挂载<rt>mount</rt></ruby>)。Linux 将随后在所挂载的目录(比如是, `/media/<your user name>/cdrom` )下显示 CD-ROM 上的文件和目录。
|
||||
|
||||
因此,在 Linux 上回答 “我的 C:\ 在哪里?” 这个问题,答案是,这里没有 C:\,它们工作方式不一样。
|
||||
|
||||
### 文件
|
||||
|
||||
Windows 将文件和目录(也被称为文件夹)存储在它的文件系统中。但是,Linux 也让你将其它的东西放到文件系统中。这些其它类型的东西是文件系统的原生的对象,并且,它们和普通文件实际上是不同的。除普通文件和目录之外,Linux 还允许你去创建和使用<ruby>硬链接<rt>hard link</rt></ruby>、<ruby>符号链接<rt>symbolic link</rt></ruby>、<ruby>命名管道<rt>named pipe</rt></ruby>、<ruby>设备节点<rt>device node</rt></ruby>、和<ruby>套接字<rt>socket</rt></ruby>。在这里,我们不展开讨论所有的文件系统对象的类型,但是,这里有几种经常使用到的需要知道。
|
||||
|
||||
硬链接用于为文件创建一个或者多个别名。指向磁盘上同样内容的每个别名的名字是不同的。如果在一个文件名下编辑文件,这个改变也同时出现在其它的文件名上。例如,你有一个 `MyResume_2017.doc`,它还有一个被称为 `JaneDoeResume.doc` 的硬链接。(注意,硬链接是从命令行下,使用 `ln` 的命令去创建的)。你可以找到并编辑 `MyResume_2017.doc`,然后,然后找到 `JaneDoeResume.doc`,你发现它保持了跟踪 —— 它包含了你所有的更新。
|
||||
|
||||
符号链接有点像 Windows 中的快捷方式。文件系统的入口包含一个到其它文件或者目录的路径。在很多方面,它们的工作方式和硬链接很相似,它们可以创建一个到其它文件的别名。但是,符号链接也可以像文件一样给目录创建一个别名,并且,符号链接可以指向到不同介质上的不同文件系统,而硬链接做不到这些。(注意,你可以使用带 `-s` 选项的 `ln` 命令去创建一个符号链接)
|
||||
|
||||
### 权限
|
||||
|
||||
Windows 和 Linux 另一个很大的区别是涉及到文件系统对象(文件、目录、及其它)的权限。Windows 在文件和目录上实现了一套非常复杂的权限。例如,用户和用户组可以有权限去读取、写入、运行、修改等等。用户和用户组可以授权访问除例外以外的目录中的所有内容,也可以不允许访问除例外的目录中的所有内容。
|
||||
|
||||
然而,大多数使用 Windows 的人并不会去使用特定的权限;因此,当他们发现在 Linux 上是强制使用一套默认权限时,他们感到非常惊讶!Linux 通过使用 SELinux 或者 AppArmor 可以强制执行一套更复杂的权限。但是,大多数 Linux 安装版都只是使用了内置的默认权限。
|
||||
|
||||
在默认的权限中,文件系统中的每个条目都有一套为它的文件所有者、文件所在的组、和其它人的设置的权限。这些权限允许他们:读取、写入和运行。给它们的权限是有层次继承的。首先,它检查这个(登入的)用户是否为该文件所有者和拥有的权限。如果不是,然后检查这个用户是否在文件所在的组中和该组拥有的权限。如果不是,然后它再检查其它人拥有的权限。这里设置了其它人的权限。但是,这里设置的三套权限大多数情况下都会使用其中的一套。
|
||||
|
||||
如果你使用命令行,你输入 `ls -l`,你可以看到如下所表示的权限:
|
||||
|
||||
```
|
||||
rwxrw-r-- 1 stan dndgrp 25 Oct 33rd 25:01 rolldice.sh
|
||||
```
|
||||
|
||||
最前面的字母,`rwxrw-r--`,展示了权限。在这个例子中,所有者(stan)可以读取、写入和运行这个文件(前面的三个字母,`rwx`);dndgrp 组的成员可以读取和写入这个文件,但是不能运行(第二组的三个字母,`rw-`);其它人仅可以读取这个文件(最后的三个字母,`r--`)。
|
||||
|
||||
(注意,在 Windows 中去生成一个可运行的脚本,你生成的文件要有一个特定的扩展名,比如 `.bat`,而在 Linux 中,扩展名在操作系统中没有任何意义。而是需要去设置这个文件可运行的权限)
|
||||
|
||||
如果你收到一个 “permission denied” 错误,可能是你去尝试运行了一个要求管理员权限的程序或者命令,或者你去尝试访问一个你的帐户没有访问权限的文件。如果你尝试去做一些要求管理员权限的事,你必须切换登入到一个被称为 `root` 的用户帐户。或者通过在命令行使用一个被称为 `sudo` 的辅助程序。它可以临时允许你以 `root` 权限运行。当然,`sudo` 工具,也会要求你输入密码,以确保你真的有权限。
|
||||
|
||||
### 硬盘文件系统
|
||||
|
||||
Windows 主要使用一个被称为 NTFS 的硬盘文件系统。在 Linux 上,你也可以选一个你希望去使用的硬盘文件系统。不同的文件系统类型呈现不同的特性和不同的性能特征。现在主流的原生 Linux 的文件系统是 Ext4。但是,在安装 Linux 的时候,你也有丰富的文件系统类型可供选择,比如,Ext3(Ext4 的前任)、XFS、Btrfs、UBIFS(用于嵌入式系统)等等。如果你不确定要使用哪一个,Ext4 是一个很好的选择。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/intro-to-linux/2017/11/migrating-linux-disks-files-and-filesystems
|
||||
|
||||
作者:[JOHN BONESIO][a]
|
||||
译者:[qhwdw](https://github.com/qhwdw)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/johnbonesio
|
||||
[1]:https://www.linux.com/licenses/category/creative-commons-zero
|
||||
[2]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
||||
[3]:https://www.linux.com/files/images/butterflies-8075511920jpg
|
||||
[4]:https://linux.cn/article-9212-1.html
|
132
published/20171128 A generic introduction to Gitlab CI.md
Normal file
132
published/20171128 A generic introduction to Gitlab CI.md
Normal file
@ -0,0 +1,132 @@
|
||||
Gitlab CI 常规介绍
|
||||
======
|
||||
|
||||
在 [fleetster][1], 我们搭建了自己的 [Gitlab][2] 实例,而且我们大量使用了 [Gitlab CI][3]。我们的设计师和测试人员也都在用它,也很喜欢用它,它的那些高级功能特别棒。
|
||||
|
||||
Gitlab CI 是一个功能非常强大的持续集成系统,有很多不同的功能,而且每次发布都会增加新的功能。它的技术文档也很丰富,但是对那些要在已经配置好的 Gitlab 上使用它的用户来说,它缺乏一个一般性介绍。设计师或者测试人员是无需知道如何通过 Kubernetes 来实现自动伸缩,也无需知道“镜像”和“服务”之间的不同的。
|
||||
|
||||
但是,他仍然需要知道什么是“管道”,知道如何查看部署到一个“环境”中的分支。因此,在本文中,我会尽可能覆盖更多的功能,重点放在最终用户应该如何使用它们上;在过去的几个月里,我向我们团队中的某些人包括开发者讲解了这些功能:不是所有人都知道<ruby>持续集成<rt>Continuous Integration</rt></ruby>(CI)是个什么东西,也不是所有人都用过 Gitlab CI。
|
||||
|
||||
如果你想了解为什么持续集成那么重要,我建议阅读一下 [这篇文章][4],至于为什么要选择 Gitlab CI 呢,你可以去看看 [Gitlab.com][3] 上的说明。
|
||||
|
||||
### 简介
|
||||
|
||||
开发者保存更改代码的动作叫做一次<ruby>提交<rt>commit</rt></ruby>。然后他可以将这次提交<ruby>推送<rt>push</rt></ruby>到 Gitlab 上,这样可以其他开发者就可以<ruby>复查<rt>review</rt></ruby>这些代码了。
|
||||
|
||||
Gitlab CI 配置好后,Gitlab 也能对这个提交做出一些处理。该处理的工作由一个<ruby>运行器<rt>runner</rt></ruby>来执行的。所谓运行器基本上就是一台服务器(也可以是其他的东西,比如你的 PC 机,但我们可以简单称其为服务器)。这台服务器执行 `.gitlab-ci.yml` 文件中指令,并将执行结果返回给 Gitlab 本身,然后在 Gitlab 的图形化界面上显示出来。
|
||||
|
||||
开发者完成一项新功能的开发或完成一个 bug 的修复后(这些动作通常包含了多次的提交),就可以发起一个<ruby>合并请求<rt>merge request</rt></ruby>,团队其他成员则可以在这个合并请求中对代码及其实现进行<ruby>评论<rt>comment</rt></ruby>。
|
||||
|
||||
我们随后会看到,由于 Gitlab CI 提供的两大特性,<ruby>环境<rt>environment</rt></ruby> 与 <ruby>制品<rt>artifact</rt></ruby>,使得设计者和测试人员也能(而且真的需要)参与到这个过程中来,提供反馈以及改进意见。
|
||||
|
||||
### <ruby>管道<rt>pipeline</rt></ruby>
|
||||
|
||||
每个推送到 Gitlab 的提交都会产生一个与该提交关联的<ruby>管道<rt>pipeline</rt></ruby>。若一次推送包含了多个提交,则管道与最后那个提交相关联。管道就是一个分成不同<ruby>阶段<rt>stage</rt></ruby>的<ruby>作业<rt>job</rt></ruby>的集合。
|
||||
|
||||
同一阶段的所有作业会并发执行(在有足够运行器的前提下),而下一阶段则只会在上一阶段所有作业都运行并返回成功后才会开始。
|
||||
|
||||
只要有一个作业失败了,整个管道就失败了。不过我们后面会看到,这其中有一个例外:若某个作业被标注成了手工运行,那么即使失败了也不会让整个管道失败。
|
||||
|
||||
阶段则只是对批量的作业的一个逻辑上的划分,若前一个阶段执行失败了,则后一个执行也没什么意义了。比如我们可能有一个<ruby>构建<rt>build</rt></ruby>阶段和一个<ruby>部署<rt>deploy</rt></ruby>阶段,在构建阶段运行所有用于构建应用的作业,而在部署阶段,会部署构建出来的应用程序。而部署一个构建失败的东西是没有什么意义的,不是吗?
|
||||
|
||||
同一阶段的作业之间不能有依赖关系,但它们可以依赖于前一阶段的作业运行结果。
|
||||
|
||||
让我们来看一下 Gitlab 是如何展示阶段与阶段状态的相关信息的。
|
||||
|
||||
![pipeline-overview][5]
|
||||
|
||||
![pipeline-status][6]
|
||||
|
||||
### <ruby>作业<rt>job</rt></ruby>
|
||||
|
||||
作业就是运行器要执行的指令集合。你可以实时地看到作业的输出结果,这样开发者就能知道作业为什么失败了。
|
||||
|
||||
作业可以是自动执行的,也就是当推送提交后自动开始执行,也可以手工执行。手工作业必须由某个人手工触发。手工作业也有其独特的作用,比如,实现自动化部署,但只有在有人手工授权的情况下才能开始部署。这是限制哪些人可以运行作业的一种方式,这样只有信赖的人才能进行部署,以继续前面的实例。
|
||||
|
||||
作业也可以建构出<ruby>制品<rt>artifacts</rt></ruby>来以供用户下载,比如可以构建出一个 APK 让你来下载,然后在你的设备中进行测试; 通过这种方式,设计者和测试人员都可以下载应用并进行测试,而无需开发人员的帮助。
|
||||
|
||||
除了生成制品外,作业也可以部署`环境`,通常这个环境可以通过 URL 访问,让用户来测试对应的提交。
|
||||
|
||||
做作业状态与阶段状态是一样的:实际上,阶段的状态就是继承自作业的。
|
||||
|
||||
![running-job][7]
|
||||
|
||||
### <ruby>制品<rt>Artifacts</rt></ruby>
|
||||
|
||||
如前所述,作业能够生成制品供用户下载来测试。这个制品可以是任何东西,比如 Windows 上的应用程序,PC 生成的图片,甚至 Android 上的 APK。
|
||||
|
||||
那么,假设你是个设计师,被分配了一个合并请求:你需要验证新设计的实现!
|
||||
|
||||
要该怎么做呢?
|
||||
|
||||
你需要打开该合并请求,下载这个制品,如下图所示。
|
||||
|
||||
每个管道从所有作业中搜集所有的制品,而且一个作业中可以有多个制品。当你点击下载按钮时,会有一个下拉框让你选择下载哪个制品。检查之后你就可以评论这个合并请求了。
|
||||
|
||||
你也可以从没有合并请求的管道中下载制品 ;-)
|
||||
|
||||
我之所以关注合并请求是因为通常这正是测试人员、设计师和相关人员开始工作的地方。
|
||||
|
||||
但是这并不意味着合并请求和管道就是绑死在一起的:虽然它们结合的很好,但两者之间并没有什么关系。
|
||||
|
||||
![download-artifacts][8]
|
||||
|
||||
### <ruby>环境<rt>environment</rt></ruby>
|
||||
|
||||
类似的,作业可以将某些东西部署到外部服务器上去,以便你可以通过合并请求本身访问这些内容。
|
||||
|
||||
如你所见,<ruby>环境<rt>environment</rt></ruby>有一个名字和一个链接。只需点击链接你就能够转至你的应用的部署版本上去了(当前,前提是配置是正确的)。
|
||||
|
||||
Gitlab 还有其他一些很酷的环境相关的特性,比如 <ruby>[监控][9]<rt>monitoring</rt></ruby>,你可以通过点击环境的名字来查看。
|
||||
|
||||
![environment][10]
|
||||
|
||||
### 总结
|
||||
|
||||
这是对 Gitlab CI 中某些功能的一个简单介绍:它非常强大,使用得当的话,可以让整个团队使用一个工具完成从计划到部署的工具。由于每个月都会推出很多新功能,因此请时刻关注 [Gitlab 博客][11]。
|
||||
|
||||
若想知道如何对它进行设置或想了解它的高级功能,请参阅它的[文档][12]。
|
||||
|
||||
在 fleetster,我们不仅用它来跑测试,而且用它来自动生成各种版本的软件,并自动发布到测试环境中去。我们也自动化了其他工作(构建应用并将之发布到 Play Store 中等其它工作)。
|
||||
|
||||
说起来,**你是否想和我以及其他很多超棒的人一起在一个年轻而又富有活力的办公室中工作呢?** 看看 fleetster 的这些[招聘职位][13] 吧!
|
||||
|
||||
赞美 Gitlab 团队 (和其他在空闲时间提供帮助的人),他们的工作太棒了!
|
||||
|
||||
若对本文有任何问题或回馈,请给我发邮件:[riccardo@rpadovani.com][14] 或者[发推给我][15]:-) 你可以建议我增加内容,或者以更清晰的方式重写内容(英文不是我的母语)。
|
||||
|
||||
|
||||
那么,再见吧,
|
||||
|
||||
R.
|
||||
|
||||
P.S:如果你觉得本文有用,而且希望我们写出其他文章的话,请问您是否愿意帮我[买杯啤酒给我][17] 让我进入 [鲍尔默峰值][16]?
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://rpadovani.com/introduction-gitlab-ci
|
||||
|
||||
作者:[Riccardo][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://rpadovani.com
|
||||
[1]:https://www.fleetster.net
|
||||
[2]:https://gitlab.com/
|
||||
[3]:https://about.gitlab.com/gitlab-ci/
|
||||
[4]:https://about.gitlab.com/2015/02/03/7-reasons-why-you-should-be-using-ci/
|
||||
[5]:https://img.rpadovani.com/posts/pipeline-overview.png
|
||||
[6]:https://img.rpadovani.com/posts/pipeline-status.png
|
||||
[7]:https://img.rpadovani.com/posts/running-job.png
|
||||
[8]:https://img.rpadovani.com/posts/download-artifacts.png
|
||||
[9]:https://gitlab.com/help/ci/environments.md
|
||||
[10]:https://img.rpadovani.com/posts/environment.png
|
||||
[11]:https://about.gitlab.com/
|
||||
[12]:https://docs.gitlab.com/ee/ci/README.html
|
||||
[13]:https://www.fleetster.net/fleetster-team.html
|
||||
[14]:mailto:riccardo@rpadovani.com
|
||||
[15]:https://twitter.com/rpadovani93
|
||||
[16]:https://www.xkcd.com/323/
|
||||
[17]:https://rpadovani.com/donations
|
179
published/201712/19951001 Writing man Pages Using groff.md
Normal file
179
published/201712/19951001 Writing man Pages Using groff.md
Normal file
@ -0,0 +1,179 @@
|
||||
使用 groff 编写 man 手册页
|
||||
===================
|
||||
|
||||
`groff` 是大多数 Unix 系统上所提供的流行的文本格式化工具 nroff/troff 的 GNU 版本。它一般用于编写手册页,即命令、编程接口等的在线文档。在本文中,我们将给你展示如何使用 `groff` 编写你自己的 man 手册页。
|
||||
|
||||
在 Unix 系统上最初有两个文本处理系统:troff 和 nroff,它们是由贝尔实验室为初始的 Unix 所开发的(事实上,开发 Unix 系统的部分原因就是为了支持这样的一个文本处理系统)。这个文本处理器的第一个版本被称作 roff(意为 “runoff”——径流);稍后出现了 troff,在那时用于为特定的<ruby>排字机<rt>Typesetter</rt></ruby>生成输出。nroff 是更晚一些的版本,它成为了各种 Unix 系统的标准文本处理器。groff 是 nroff 和 troff 的 GNU 实现,用在 Linux 系统上。它包括了几个扩展功能和一些打印设备的驱动程序。
|
||||
|
||||
`groff` 能够生成文档、文章和书籍,很多时候它就像是其它的文本格式化系统(如 TeX)的血管一样。然而,`groff`(以及原来的 nroff)有一个固有的功能是 TeX 及其变体所缺乏的:生成普通 ASCII 输出。其它的系统在生成打印的文档方面做得很好,而 `groff` 却能够生成可以在线浏览的普通 ASCII(甚至可以在最简单的打印机上直接以普通文本打印)。如果要生成在线浏览的文档以及打印的表单,`groff` 也许是你所需要的(虽然也有替代品,如 Texinfo、Lametex 等等)。
|
||||
|
||||
`groff` 还有一个好处是它比 TeX 小很多;它所需要的支持文件和可执行程序甚至比最小化的 TeX 版本都少。
|
||||
|
||||
`groff` 一个特定的用途是用于格式化 Unix 的 man 手册页。如果你是一个 Unix 程序员,你肯定需要编写和生成各种 man 手册页。在本文中,我们将通过编写一个简短的 man 手册页来介绍 `groff` 的使用。
|
||||
|
||||
像 TeX 一样,`groff` 使用特定的文本格式化语言来描述如何处理文本。这种语言比 TeX 之类的系统更加神秘一些,但是更加简洁。此外,`groff` 在基本的格式化器之上提供了几个宏软件包;这些宏软件包是为一些特定类型的文档所定制的。举个例子, mgs 宏对于写作文章或论文很适合,而 man 宏可用于 man 手册页。
|
||||
|
||||
### 编写 man 手册页
|
||||
|
||||
用 `groff` 编写 man 手册页十分简单。要让你的 man 手册页看起来和其它的一样,你需要从源头上遵循几个惯例,如下所示。在这个例子中,我们将为一个虚构的命令 `coffee` 编写 man 手册页,它用于以各种方式控制你的联网咖啡机。
|
||||
|
||||
使用任意文本编辑器,输入如下代码,并保存为 `coffee.man`。不要输入每行的行号,它们仅用于本文中的说明。
|
||||
|
||||
```
|
||||
.TH COFFEE 1 "23 March 94"
|
||||
.SH NAME
|
||||
coffee \- Control remote coffee machine
|
||||
.SH SYNOPSIS
|
||||
\fBcoffee\fP [ -h | -b ] [ -t \fItype\fP ]
|
||||
\fIamount\fP
|
||||
.SH DESCRIPTION
|
||||
\fBcoffee\fP queues a request to the remote
|
||||
coffee machine at the device \fB/dev/cf0\fR.
|
||||
The required \fIamount\fP argument specifies
|
||||
the number of cups, generally between 0 and
|
||||
12 on ISO standard coffee machines.
|
||||
.SS Options
|
||||
.TP
|
||||
\fB-h\fP
|
||||
Brew hot coffee. Cold is the default.
|
||||
.TP
|
||||
\fB-b\fP
|
||||
Burn coffee. Especially useful when executing
|
||||
\fBcoffee\fP on behalf of your boss.
|
||||
.TP
|
||||
\fB-t \fItype\fR
|
||||
Specify the type of coffee to brew, where
|
||||
\fItype\fP is one of \fBcolumbian\fP,
|
||||
\fBregular\fP, or \fBdecaf\fP.
|
||||
.SH FILES
|
||||
.TP
|
||||
\fC/dev/cf0\fR
|
||||
The remote coffee machine device
|
||||
.SH "SEE ALSO"
|
||||
milk(5), sugar(5)
|
||||
.SH BUGS
|
||||
May require human intervention if coffee
|
||||
supply is exhausted.
|
||||
```
|
||||
|
||||
*清单 1:示例 man 手册页源文件*
|
||||
|
||||
不要让这些晦涩的代码吓坏了你。字符串序列 `\fB`、`\fI` 和 `\fR` 分别用来改变字体为粗体、斜体和正体(罗马字体)。`\fP` 设置字体为前一个选择的字体。
|
||||
|
||||
其它的 `groff` <ruby>请求<rt>request</rt></ruby>以点(`.`)开头出现在行首。第 1 行中,我们看到的 `.TH` 请求用于设置该 man 手册页的标题为 `COFFEE`、man 的部分为 `1`、以及该 man 手册页的最新版本的日期。(说明,man 手册的第 1 部分用于用户命令、第 2 部分用于系统调用等等。使用 `man man` 命令了解各个部分)。
|
||||
|
||||
在第 2 行,`.SH` 请求用于标记一个<ruby>节<rt>section</rt></ruby>的开始,并给该节名称为 `NAME`。注意,大部分的 Unix man 手册页依次使用 `NAME`、 `SYNOPSIS`、`DESCRIPTION`、`FILES`、`SEE ALSO`、`NOTES`、`AUTHOR` 和 `BUGS` 等节,个别情况下也需要一些额外的可选节。这只是编写 man 手册页的惯例,并不强制所有软件都如此。
|
||||
|
||||
第 3 行给出命令的名称,并在一个横线(`-`)后给出简短描述。在 `NAME` 节使用这个格式以便你的 man 手册页可以加到 whatis 数据库中——它可以用于 `man -k` 或 `apropos` 命令。
|
||||
|
||||
第 4-6 行我们给出了 `coffee` 命令格式的大纲。注意,斜体 `\fI...\fP` 用于表示命令行的参数,可选参数用方括号扩起来。
|
||||
|
||||
第 7-12 行给出了该命令的摘要介绍。粗体通常用于表示程序或文件的名称。
|
||||
|
||||
在 13 行,使用 `.SS` 开始了一个名为 `Options` 的子节。
|
||||
|
||||
接着第 14-25 行是选项列表,会使用参数列表样式表示。参数列表中的每一项以 `.TP` 请求来标记;`.TP` 后的行是参数,再之后是该项的文本。例如,第 14-16 行:
|
||||
|
||||
```
|
||||
.TP
|
||||
\fB-h\P
|
||||
Brew hot coffee. Cold is the default.
|
||||
```
|
||||
|
||||
将会显示如下:
|
||||
|
||||
```
|
||||
-h Brew hot coffee. Cold is the default.
|
||||
```
|
||||
|
||||
第 26-29 行创建该 man 手册页的 `FILES` 节,它用于描述该命令可能使用的文件。可以使用 `.TP` 请求来表示文件列表。
|
||||
|
||||
第 30-31 行,给出了 `SEE ALSO` 节,它提供了其它可以参考的 man 手册页。注意,第 30 行的 `.SH` 请求中 `"SEE ALSO"` 使用括号扩起来,这是因为 `.SH` 使用第一个空格来分隔该节的标题。任何超过一个单词的标题都需要使用引号扩起来成为一个单一参数。
|
||||
|
||||
最后,第 32-34 行,是 `BUGS` 节。
|
||||
|
||||
### 格式化和安装 man 手册页
|
||||
|
||||
为了在你的屏幕上查看这个手册页格式化的样式,你可以使用如下命令:
|
||||
|
||||
|
||||
```
|
||||
$ groff -Tascii -man coffee.man | more
|
||||
```
|
||||
|
||||
`-Tascii` 选项告诉 `groff` 生成普通 ASCII 输出;`-man` 告诉 `groff` 使用 man 手册页宏集合。如果一切正常,这个 man 手册页显示应该如下。
|
||||
|
||||
```
|
||||
COFFEE(1) COFFEE(1)
|
||||
NAME
|
||||
coffee - Control remote coffee machine
|
||||
SYNOPSIS
|
||||
coffee [ -h | -b ] [ -t type ] amount
|
||||
DESCRIPTION
|
||||
coffee queues a request to the remote coffee machine at
|
||||
the device /dev/cf0\. The required amount argument speci-
|
||||
fies the number of cups, generally between 0 and 12 on ISO
|
||||
standard coffee machines.
|
||||
Options
|
||||
-h Brew hot coffee. Cold is the default.
|
||||
-b Burn coffee. Especially useful when executing cof-
|
||||
fee on behalf of your boss.
|
||||
-t type
|
||||
Specify the type of coffee to brew, where type is
|
||||
one of columbian, regular, or decaf.
|
||||
FILES
|
||||
/dev/cf0
|
||||
The remote coffee machine device
|
||||
SEE ALSO
|
||||
milk(5), sugar(5)
|
||||
BUGS
|
||||
May require human intervention if coffee supply is
|
||||
exhausted.
|
||||
```
|
||||
|
||||
*格式化的 man 手册页*
|
||||
|
||||
如之前提到过的,`groff` 能够生成其它类型的输出。使用 `-Tps` 选项替代 `-Tascii` 将会生成 PostScript 输出,你可以将其保存为文件,用 GhostView 查看,或用一个 PostScript 打印机打印出来。`-Tdvi` 会生成设备无关的 .dvi 输出,类似于 TeX 的输出。
|
||||
|
||||
如果你希望让别人在你的系统上也可以查看这个 man 手册页,你需要安装这个 groff 源文件到其它用户的 `%MANPATH` 目录里面。标准的 man 手册页放在 `/usr/man`。第一部分的 man 手册页应该放在 `/usr/man/man1` 下,因此,使用命令:
|
||||
|
||||
```
|
||||
$ cp coffee.man /usr/man/man1/coffee.1
|
||||
```
|
||||
|
||||
这将安装该 man 手册页到 `/usr/man` 中供所有人使用(注意使用 `.1` 扩展名而不是 `.man`)。当接下来执行 `man coffee` 命令时,该 man 手册页会被自动重新格式化,并且可查看的文本会被保存到 `/usr/man/cat1/coffee.1.Z` 中。
|
||||
|
||||
如果你不能直接复制 man 手册页的源文件到 `/usr/man`(比如说你不是系统管理员),你可创建你自己的 man 手册页目录树,并将其加入到你的 `%MANPATH`。`%MANPATH` 环境变量的格式同 `%PATH` 一样,举个例子,要添加目录 `/home/mdw/man` 到 `%MANPATH` ,只需要:
|
||||
|
||||
```
|
||||
$ export MANPATH=/home/mdw/man:$MANPATH
|
||||
```
|
||||
|
||||
`groff` 和 man 手册页宏还有许多其它的选项和格式化命令。找到它们的最好办法是查看 `/usr/lib/groff` 中的文件; `tmac` 目录包含了宏文件,自身通常会包含其所提供的命令的文档。要让 `groff` 使用特定的宏集合,只需要使用 `-m macro` (或 `-macro`) 选项。例如,要使用 mgs 宏,使用命令:
|
||||
|
||||
```
|
||||
groff -Tascii -mgs files...
|
||||
```
|
||||
|
||||
`groff` 的 man 手册页对这个选项描述了更多细节。
|
||||
|
||||
不幸的是,随同 `groff` 提供的宏集合没有完善的文档。第 7 部分的 man 手册页提供了一些,例如,`man 7 groff_mm` 会给你 mm 宏集合的信息。然而,该文档通常只覆盖了在 `groff` 实现中不同和新功能,而假设你已经了解过原来的 nroff/troff 宏集合(称作 DWB:the Documentor's Work Bench)。最佳的信息来源或许是一本覆盖了那些经典宏集合细节的书。要了解更多的编写 man 手册页的信息,你可以看看 man 手册页源文件(`/usr/man` 中),并通过它们来比较源文件的输出。
|
||||
|
||||
这篇文章是《Running Linux》 中的一章,由 Matt Welsh 和 Lar Kaufman 著,奥莱理出版(ISBN 1-56592-100-3)。在本书中,还包括了 Linux 下使用的各种文本格式化系统的教程。这期的《Linux Journal》中的内容及《Running Linux》应该可以给你提供在 Linux 上使用各种文本工具的良好开端。
|
||||
|
||||
### 祝好,撰写快乐!
|
||||
|
||||
Matt Welsh ([mdw@cs.cornell.edu][1])是康奈尔大学的一名学生和系统程序员,在机器人和视觉实验室从事于时时机器视觉研究。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.linuxjournal.com/article/1158
|
||||
|
||||
作者:[Matt Welsh][a]
|
||||
译者:[wxy](https://github.com/wxy)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.linuxjournal.com/user/800006
|
||||
[1]:mailto:mdw@cs.cornell.edu
|
@ -0,0 +1,76 @@
|
||||
修复 Linux / Unix / OS X / BSD 系统控制台上的显示乱码
|
||||
======
|
||||
|
||||
有时我的探索会在屏幕上输出一些奇怪的东西。比如,有一次我不小心用 `cat` 命令查看了一下二进制文件的内容 —— `cat /sbin/*`。这种情况下你将无法再访问终端里的 bash/ksh/zsh 了。大量的奇怪字符充斥了你的终端。这些字符会隐藏你输入的内容和要显示的字符,取而代之的是一些奇怪的符号。要清理掉这些屏幕上的垃圾可以使用以下方法。本文就将向你描述在 Linux/ 类 Unix 系统中如何真正清理终端屏幕或者重置终端。
|
||||
|
||||
### clear 命令
|
||||
|
||||
`clear` 命令会清理掉屏幕内容,连带它的回滚缓存区一起也会被清理掉。(LCTT 译注:这种情况下你输入的字符回显也是乱码,不必担心,正确输入后回车即可生效。)
|
||||
|
||||
```
|
||||
$ clear
|
||||
```
|
||||
|
||||
你也可以按下 `CTRL+L` 来清理屏幕。然而,`clear` 命令并不会清理掉终端屏幕(LCTT 译注:这句话比较难理解,应该是指的运行 `clear` 命令并不是真正的把以前显示的内容删掉,你还是可以通过向上翻页看到之前显示的内容)。使用下面的方法才可以真正地清空终端,使你的终端恢复正常。
|
||||
|
||||
### 使用 reset 命令修复显示
|
||||
|
||||
下面图片中,控制台的屏幕上充满了垃圾信息:
|
||||
|
||||
[![Fig.01:Bash fix the display][1]][2]
|
||||
|
||||
要修复正常显示,只需要输入 `reset` 命令。它会为你再初始化一次终端:
|
||||
|
||||
```
|
||||
$ reset
|
||||
```
|
||||
|
||||
或者:
|
||||
|
||||
```
|
||||
$ tput reset
|
||||
```
|
||||
|
||||
如果 `reset` 命令还不行,那么输入下面命令来让绘画回复到正常状态:
|
||||
|
||||
```
|
||||
$ stty sane
|
||||
```
|
||||
|
||||
按下 `CTRL + L` 来清理屏幕(或者输入 `clear` 命令):
|
||||
|
||||
```
|
||||
$ clear
|
||||
```
|
||||
|
||||
### 使用 ANSI 转义序列来真正地清空 bash 终端
|
||||
|
||||
另一种选择是输入下面的 ANSI 转义序列:
|
||||
|
||||
```
|
||||
clear
|
||||
echo -e "\033c"
|
||||
```
|
||||
|
||||
下面是这两个命令的输出示例:
|
||||
|
||||
[![Animated gif 01:Fix Unix Console Gibberish Command Demo][3]][4]
|
||||
|
||||
更多信息请阅读 `stty` 和 `reset` 的 man 页: stty(1),reset(1),bash(1)。
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.cyberciti.biz/tips/bash-fix-the-display.html
|
||||
|
||||
作者:[Vivek Gite][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.cyberciti.biz
|
||||
[1]:https://www.cyberciti.biz/media/new/tips/2006/08/bash-fix-terminal.png
|
||||
[2]:https://www.cyberciti.biz/media/uploads/tips/2006/08/bash-fix-terminal.png
|
||||
[3]:https://www.cyberciti.biz/media/new/tips/2006/08/unix-linux-console-gibberish.gif
|
||||
[4]:https://www.cyberciti.biz/tips/bash-fix-the-display.html/unix-linux-console-gibberish
|
@ -0,0 +1,87 @@
|
||||
# [因为这个我要点名批评 Hacker News ][14]
|
||||
|
||||
|
||||
> “实现高速缓存会花费 30 个小时,你有额外的 30 个小时吗?
|
||||
不,你没有。我实际上并不知道它会花多少时间,可能它会花五分钟,你有五分钟吗?不,你还是没有。为什么?因为我在撒谎。它会消耗远超五分钟的时间。这一切把问题简单化的假设都只不过是程序员单方面的乐观主义。”
|
||||
>
|
||||
> — 出自 [Owen Astrachan][1] 教授于 2004 年 2 月 23 日在 [CPS 108][2] 上的讲座
|
||||
|
||||
[指责开源软件总是离奇难用已经不是一个新论点了][5];这样的论点之前就被很多比我更为雄辩的人提及过,甚至是出自一些人非常推崇开源软件的人士口中。那么为什么我要在这里老调重弹呢?
|
||||
|
||||
在周一的 Hacker News 期刊上,一段文章把我逗乐了。文章谈到,一些人认为 [编写代码实现和一个跟 StackOverflow 一样的系统可以简单到爆][6],并自信的 [声称他们可以在 7 月 4 号的周末就写出一版和 StackOverflow 原版一模一样的程序][7],以此来证明这一切是多么容易。另一些人则插话说,[现有的][8][那些仿制产品][9] 就已经是一个很好的例证了。
|
||||
|
||||
秉承着自由讨论的精神,我们来假设一个场景。你在思考了一阵之后认为你可以用 ASP.NET MVC 来编写一套你自己的 StackOverflow 。我呢,在被一块儿摇晃着的怀表催眠之后,脑袋又挨了别人一顿棒槌,然后像个二哈一样一页一页的把 StackOverflow 的源码递给你,让你照原样重新拿键盘逐字逐句的在你的环境下把那些代码再敲一遍,做成你的 StackOverflow。假设你可以像我一样打字飞快,一分钟能敲 100 个词 ([也就是大约每秒敲八个字母][10]),但是却可以牛叉到我无法企及的打字零错误率。从 StackOverflow 的大小共计 2.3MB 的源码来估计(包括 .CS、 .SQL、 .CSS、 .JS 和 .aspx 文件),就单单是照着源代码这么飞速敲一遍而且一气呵成中间一个字母都不错,你也要差不多用掉至少 80 个小时的时间。
|
||||
|
||||
或者你打算从零开始编码实现你自己的 StackOverflow,虽然我知道你肯定是不会那样做的。我们假设你从设计程序,到敲代码,再到最终完成调试只需要区区十倍于抄袭 StackOverflow 源代码的时间。即使在这样的假设条件下,你也要耗费几周的时间昼夜不停得狂写代码。不知道你是否愿意,但是至少我可以欣然承认,如果只给我照抄 StackOverflow 源代码用时的十倍时间来让我自己写 StackOverflow,我可是打死也做不到。
|
||||
|
||||
_好的_,我知道你在听到这些假设的时候已经开始觉得泄气了。*你在想,如果不是全部实现,而只是实现 StackOverflow __大部分__ 的功能呢?这总归会容易很多了吧。*
|
||||
|
||||
好的,问题是什么是 “大部分” 功能?如果只去实现提问和回答问题的功能?这个部分应该很简单吧。其实不然,因为实现问和答的功能还要求你必须做出一个对问题及其答案的投票系统,来显示大家对某个答案是赞同还是反对。因为只有这样你才能保证提问者可以得到这个问题的唯一的可信答案。当然,你还不能让人们赞同或者反对他们自己给出的答案,所以你还要去实现这种禁止自投自票的机制。除此之外,你需要去确保用户在一定的时间内不能赞同或反对其他用户太多次,以此来防止有人用机器人程序作弊乱投票。你很可能还需要去实现一个垃圾评论过滤器,即使这个过滤器很基础很简陋,你也要考虑如何去设计它。而且你恐怕还需要去支持用户图标(头像)的功能。并且你将不得不寻找一个自己真正信任的并且与 Markdown 结合很好的干净的 HTML 库(当然,假设你确实想要复用 StackOverflow 的 [那个超棒的编辑器][11] )。你还需要为所有控件购买或者设计一些小图标、小部件,此外你至少需要实现一个基本的管理界面,以便那些喜欢捣鼓的用户可以调整和改动他们的个性化设置。并且你需要实现类似于 Karma 的声望累积系统,以便用户可以随着不断地使用来稳步提升他们的话语权和解锁更多的功能以及可操作性。
|
||||
|
||||
但是如果你实现了以上_所有_功能,可以说你_就已经_把要做的都做完了。
|
||||
|
||||
除非……除非你还要做全文检索功能。尤其是在“边问边搜”(动态检索)的特性中,支持全文检索是必不可少的。此外,录入和显示用户的基本信息,实现对问题答案的评论功能,以及实现一个显示热点提问的页面,以及热点问题和帖子随着时间推移沉下去的这些功能,都将是不可或缺的。另外你肯定还需要去实现回答奖励系统,并支持每个用户用多个不同的 OpenID 账户去登录,然后将这些相关的登录事件通过邮件发送出去来通知用户,并添加一个标签或徽章系统,接着允许管理员通过一个不错的图形界面来配置这些标签和<ruby>徽章<rt>Badge</rt></ruby>。你需要去显示用户的 Karma 历史,以及他们的历史点赞和差评。而且整个页面还需要很流畅的展开和拉伸,因为这个系统的页面随时都可能被 Slashdot、Reddit 或是 StackOverflow 这些动作影响到。
|
||||
|
||||
在这之后!你会以为你基本已经大功告成了!
|
||||
|
||||
……为了产品的完整性,在上面所述的工作都完成之后,你又奋不顾身的去实现了升级功能,界面语言的国际化,Karma 值上限,以及让网站更专业的 CSS 设计、AJAX,还有那些看起来理所当然做起来却让人吐血的功能和特性。如果你不是真的动手来尝试做一个和 StackOverflow 一模一样的系统,你肯定不会意识到在整个程序设计实施的过程中,你会踩到无数的鬼才会知道的大坑。
|
||||
|
||||
那么请你告诉我:如果你要做一个让人满意的类似产品出来,上述的哪一个功能是你可以省略掉的呢?哪些是“大部分”网站都具备的功能,哪些又不是呢?
|
||||
|
||||
正因为这些很容易被忽视的问题,开发者才会以为做一个 StackOverflow 的仿制版产品会很简单。也同样是因为这些被忽视了的因素,开源软件才一直让人用起来很痛苦。很多软件开发人员在看到 StackOverflow 的时候,他们并不能察觉到 StackOverflow 产品的全貌。他们会简单的把 Stackoverflow 的实现抽象成下面一段逻辑和代码:
|
||||
|
||||
```
|
||||
create table QUESTION (ID identity primary key,
|
||||
TITLE varchar(255), --- 为什么我知道你认为是 255
|
||||
BODY text,
|
||||
UPVOTES integer not null default 0,
|
||||
DOWNVOTES integer not null default 0,
|
||||
USER integer references USER(ID));
|
||||
create table RESPONSE (ID identity primary key,
|
||||
BODY text,
|
||||
UPVOTES integer not null default 0,
|
||||
DOWNVOTES integer not null default 0,
|
||||
QUESTION integer references QUESTION(ID))
|
||||
```
|
||||
|
||||
如果你让这些开发者去实现 StackOverflow,进入他脑海中的就是上面的两个 SQL 表和一个用以呈现表格数据的 HTML 文件。他们甚至会忽略数据的格式问题,进而单纯的以为他们可以在一个周末的时间里就把 StackOverflow 做出来。一些稍微老练的开发者可能会意识到他们还要去实现登录和注销功能、评论功能、投票系统,但是仍然会自信的认为这不过也就是利用一个周末就能完成了;因为这些功能也不过意味着在后端多了几张 SQL 表和 HTML 文件。如果借助于 Django 之类的构架和工具,他们甚至可以直接拿来主义地不花一分钱就实现用户登录和评论的功能。
|
||||
|
||||
但这种简单的实现却_远远不能_体现出 StackOverflow 的精髓。无论你对 StackOverflow 的感觉如何,大多数使用者似乎都同意 StackOverflow 的用户体验从头到尾都很流畅。使用 StackOverflow 的过程就是在跟一个精心打磨过的产品在愉快地交互。即使我没有深入了解过 StackOverflow ,我也能猜测出这个产品的成功和它的数据库的 Schema 没有多大关系 —— 实际上在有幸研读过 StackOverflow 的源码之后,我得以印证了自己的想法,StackOverflow 的成功确实和它的数据库设计关系甚小。真正让它成为一个极其易用的网站的原因,是它背后_大量的_精雕细琢的设计和实施。多数的开发人员在谈及仿制和克隆一款产品的难度时,真的_很少会去考虑到产品背后的打磨和雕琢工作_,因为他们认为_这些打磨和雕琢都是偶然的,甚至是无足轻重的。_
|
||||
|
||||
这就是为什么用开源工具去克隆和山寨 StackOverflow 其实是很容易失败的。即使这些开源开发者只是想去实现 StackOverflow 的主要的“规范和标准特性”,而非全面的高级特性,他们也会在实现的过程中遭遇种种关键和核心的问题,让他们阴沟翻船,半途而废。拿徽章功能来说,如果你要针对普通终端用户来设计徽章, 则要么需要实现一个用户可用来个性化设置徽章的 GUI,要么则取巧的设计出一个比较通用的徽章,供所有的安装版本来使用。而开源设计的实际情况是,开发者会有很多的抱怨和牢骚,认为给徽章这种东西设计一个功能全面的 GUI 是根本不可能的。而且他们会固执地把任何标准徽章的提案踢回去,踢出第一宇宙速度,击穿地壳甩到地球的另一端。最终这些开发者还是会搞出一个类似于 Roundup 的 bug tracker 程序都在使用的流程和方案:即实现一个通用的机制,提供以 Python 或 PHP 为基础的一些系统 API, 以便那些可以自如使用 Python 或 PHP 的人可以轻松的通过这些编程接口来定制化他们自己的徽章。而且老实说,PHP 和 Python 可是比任何可能的 GUI 接口都要好用和强大得多,为什么还要考虑 GUI 的方案呢?(出自开源开发者的想法)
|
||||
|
||||
同样的,开源开发者会认为那些系统设置和管理员界面也一样可以省略掉。在他们看来,假如你是一个管理员,有 SQL 服务器的权限,那么你就理所当然的具备那些系统管理员该有的知识和技能。那么你其实可以使用 Djang-admin 或者任何类似的工具来轻松的对 StackOverflow 做很多设置和改造工作。毕竟如果你是一个 mods (懂如何 mod 的人)那么你肯定知道网站是怎么工作的,懂得如何利用专业工具去设置和改造一个网站。对啊!这不就得了! 毋庸置疑,在开源开发者重做他们自己的 StackOverflow 的时候,他们也不会把任何 StackOverflow 在接口上面的失败设计纠正过来。即使是原版 StackOverflow 里面最愚蠢最失败的那个设计(即要求用户必须拥有一个 OpenID 并知道如何使用它)在某个将来最终被 StackOverflow 删除和修正掉了, 我相信正在复制 StackOverflow 模式的那些开源克隆产品也还是会不假思索的把这个 OpenID 的功能仿制出来。这就好比是 GNOME 和 KDE 多年以来一直在做的事情,他们并没有把精力放在如何在设计之初就避免 Windows 的那些显而易见的毛病和问题,相反的却是在亦步亦趋的重复着 Windows 的设计,想办法用开源的方式做出一个比拟 Windows 功能的系统。
|
||||
|
||||
开发者可能不会关心一个应用的上述设计细节,但是终端用户一定会。尤其是当他们在尝试去选择要使用哪个应用的时候,这些终端用户更会重视这些接口设计是否易用。就好像一家好的软件公司希望通过确保其产品在出货之前就有一流的质量,以降低售后维护支持的成本一样,懂行的消费者也会在他们购买这些产品之前就确保产品好用,以防在使用的时候不知所措,然后无奈的打电话给售后来解决问题。开源产品就失败在这里,而且相当之失败。一般来讲,付费软件则在这方面做得好很多。
|
||||
|
||||
这不是说开源软件没有自己的立足之地,这个博客就运行在 Apache、[Django][12]、[PostgreSQL][13] 和 Linux 搭建的开源系统之上。但是让我来告诉你吧,配置这些堆栈可不是谁都可以做的。老版本的 PostgreSQL 需要手工配置 Vacuuming 来确保数据库的自动清理,而即使是最新版本的 Ubuntu 和 FreeBSD 也仍然要求用户去手工配置他们的第一个数据库集群。
|
||||
|
||||
相比之下,MS SQL (微软的 SQL 数据库) 则不需要你手工配置以上的任何一样东西。至于 Apache …… 我的天,Apache 简直复杂到让我根本来不及去尝试给一个新用户讲解我们如何可以通过一个一次性的安装过程就能把虚拟机、MovableType,几个 Diango apps 和 WordPress 配置在一起并流畅地使用。单单是给那些技术背景还不错但并非软件开发者的用户解释清楚 Apache 的那些针对多进程和多线程的设置参数就已经够我喝一壶的了。相比之下,微软的 IIS 7 或者是使用了 OS X 服务器的那个几乎闭源的 GUI 管理器的 Apache ,在配置的时候就要简单上不止一个数量级了。Django 确实是一个好的开源产品,但它也 _只是_ 一个基础构架,而并非是一个可以直接面向终端普通用户的商业产品。而开源真正的强项就 _恰恰在_ 这种基础构架的开发和创新上,这也正是驱使开发者为开源做贡献的最本真的动力。
|
||||
|
||||
所以我的结论是,如果下次你再看到一个你喜欢的应用程序,请好好细心地揣摩一下这款产品,揣摩一下所有的那些针对用户的体贴入微的设计细节。而不是武断的认为你可以轻轻松松的在一周之内就用开源工具做一个和这个应用一摸一样的产品出来。那些认为制作和实现一个应用程序如此简单的人,十之八九都是因为忽略了软件开发的最终产品是要交给用户去用的。
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
via: https://bitquabit.com/post/one-which-i-call-out-hacker-news/
|
||||
|
||||
作者:[Benjamin Pollack][a]
|
||||
译者:[hopefully2333](https://github.com/hopefully2333),[yunfengHe](https://github.com/yunfengHe)
|
||||
校对:[yunfengHe](https://github.com/yunfengHe),[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://bitquabit.com/meta/about/
|
||||
[1]:http://www.cs.duke.edu/~ola/
|
||||
[2]:http://www.cs.duke.edu/courses/cps108/spring04/
|
||||
[3]:https://bitquabit.com/categories/programming
|
||||
[4]:https://bitquabit.com/categories/technology
|
||||
[5]:http://blog.bitquabit.com/2009/06/30/one-which-i-say-open-source-software-sucks/
|
||||
[6]:http://news.ycombinator.com/item?id=678501
|
||||
[7]:http://news.ycombinator.com/item?id=678704
|
||||
[8]:http://code.google.com/p/cnprog/
|
||||
[9]:http://code.google.com/p/soclone/
|
||||
[10]:http://en.wikipedia.org/wiki/Words_per_minute
|
||||
[11]:http://github.com/derobins/wmd/tree/master
|
||||
[12]:http://www.djangoproject.com/
|
||||
[13]:http://www.postgresql.org/
|
||||
[14]:https://bitquabit.com/post/one-which-i-call-out-hacker-news/
|
@ -0,0 +1,206 @@
|
||||
动态连接的诀窍:使用 LD_PRELOAD 去欺骗、注入特性和研究程序
|
||||
=============
|
||||
|
||||
**本文假设你具备基本的 C 技能**
|
||||
|
||||
Linux 完全在你的控制之中。虽然从每个人的角度来看似乎并不总是这样,但是高级用户喜欢去控制它。我将向你展示一个基本的诀窍,在很大程度上你可以去影响大多数程序的行为,它并不仅是好玩,在有时候也很有用。
|
||||
|
||||
### 一个让我们产生兴趣的示例
|
||||
|
||||
让我们以一个简单的示例开始。先乐趣,后科学。
|
||||
|
||||
|
||||
*random_num.c:*
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
int main(){
|
||||
srand(time(NULL));
|
||||
int i = 10;
|
||||
while(i--) printf("%d\n",rand()%100);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
我相信,它足够简单吧。我不使用任何参数来编译它,如下所示:
|
||||
|
||||
```
|
||||
gcc random_num.c -o random_num
|
||||
```
|
||||
|
||||
我希望它输出的结果是明确的:从 0-99 中选择的十个随机数字,希望每次你运行这个程序时它的输出都不相同。
|
||||
|
||||
现在,让我们假装真的不知道这个可执行程序的出处。甚至将它的源文件删除,或者把它移动到别的地方 —— 我们已不再需要它了。我们将对这个程序的行为进行重大的修改,而你并不需要接触到它的源代码,也不需要重新编译它。
|
||||
|
||||
因此,让我们来创建另外一个简单的 C 文件:
|
||||
|
||||
*unrandom.c:*
|
||||
|
||||
```
|
||||
int rand(){
|
||||
return 42; //the most random number in the universe
|
||||
}
|
||||
```
|
||||
|
||||
我们将编译它进入一个共享库中。
|
||||
|
||||
```
|
||||
gcc -shared -fPIC unrandom.c -o unrandom.so
|
||||
```
|
||||
|
||||
因此,现在我们已经有了一个可以输出一些随机数的应用程序,和一个定制的库,它使用一个常数值 `42` 实现了一个 `rand()` 函数。现在 …… 就像运行 `random_num` 一样,然后再观察结果:
|
||||
|
||||
```
|
||||
LD_PRELOAD=$PWD/unrandom.so ./random_nums
|
||||
```
|
||||
|
||||
如果你想偷懒或者不想自动亲自动手(或者不知什么原因猜不出发生了什么),我来告诉你 —— 它输出了十次常数 42。
|
||||
|
||||
如果先这样执行
|
||||
|
||||
```
|
||||
export LD_PRELOAD=$PWD/unrandom.so
|
||||
```
|
||||
|
||||
然后再以正常方式运行这个程序,这个结果也许会更让你吃惊:一个未被改变过的应用程序在一个正常的运行方式中,看上去受到了我们做的一个极小的库的影响 ……
|
||||
|
||||
**等等,什么?刚刚发生了什么?**
|
||||
|
||||
是的,你说对了,我们的程序生成随机数失败了,因为它并没有使用 “真正的” `rand()`,而是使用了我们提供的的那个 —— 它每次都返回 `42`。
|
||||
|
||||
**但是,我们*告诉过*它去使用真实的那个。我们编程让它去使用真实的那个。另外,在创建那个程序的时候,假冒的 `rand()` 甚至并不存在!**
|
||||
|
||||
这句话并不完全正确。我们只能告诉它去使用 `rand()`,但是我们不能去选择哪个 `rand()` 是我们希望我们的程序去使用的。
|
||||
|
||||
当我们的程序启动后,(为程序提供所需要的函数的)某些库被加载。我们可以使用 `ldd` 去学习它是怎么工作的:
|
||||
|
||||
```
|
||||
$ ldd random_nums
|
||||
linux-vdso.so.1 => (0x00007fff4bdfe000)
|
||||
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f48c03ec000)
|
||||
/lib64/ld-linux-x86-64.so.2 (0x00007f48c07e3000)
|
||||
```
|
||||
|
||||
正如你看到的输出那样,它列出了被程序 `random_nums` 所需要的库的列表。这个列表是构建进可执行程序中的,并且它是在编译时决定的。在你的机器上的具体的输出可能与示例有所不同,但是,一个 `libc.so` 肯定是有的 —— 这个文件提供了核心的 C 函数。它包含了 “真正的” `rand()`。
|
||||
|
||||
我使用下列的命令可以得到一个全部的函数列表,我们看一看 libc 提供了哪些函数:
|
||||
|
||||
```
|
||||
nm -D /lib/libc.so.6
|
||||
```
|
||||
|
||||
这个 `nm` 命令列出了在一个二进制文件中找到的符号。`-D` 标志告诉它去查找动态符号,因为 `libc.so.6` 是一个动态库。这个输出是很长的,但它确实在列出的很多标准函数中包括了 `rand()`。
|
||||
|
||||
现在,在我们设置了环境变量 `LD_PRELOAD` 后发生了什么?这个变量 **为一个程序强制加载一些库**。在我们的案例中,它为 `random_num` 加载了 `unrandom.so`,尽管程序本身并没有这样去要求它。下列的命令可以看得出来:
|
||||
|
||||
```
|
||||
$ LD_PRELOAD=$PWD/unrandom.so ldd random_nums
|
||||
linux-vdso.so.1 => (0x00007fff369dc000)
|
||||
/some/path/to/unrandom.so (0x00007f262b439000)
|
||||
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f262b044000)
|
||||
/lib64/ld-linux-x86-64.so.2 (0x00007f262b63d000)
|
||||
```
|
||||
|
||||
注意,它列出了我们当前的库。实际上这就是代码为什么得以运行的原因:`random_num` 调用了 `rand()`,但是,如果 `unrandom.so` 被加载,它调用的是我们所提供的实现了 `rand()` 的库。很清楚吧,不是吗?
|
||||
|
||||
### 更清楚地了解
|
||||
|
||||
这还不够。我可以用相似的方式注入一些代码到一个应用程序中,并且用这种方式它能够像个正常的函数一样工作。如果我们使用一个简单的 `return 0` 去实现 `open()` 你就明白了。我们看到这个应用程序就像发生了故障一样。这是 **显而易见的**, 真实地去调用原始的 `open()`:
|
||||
|
||||
*inspect_open.c:*
|
||||
|
||||
```
|
||||
int open(const char *pathname, int flags){
|
||||
/* Some evil injected code goes here. */
|
||||
return open(pathname,flags); // Here we call the "real" open function, that is provided to us by libc.so
|
||||
}
|
||||
```
|
||||
|
||||
嗯,不对。这将不会去调用 “原始的” `open(...)`。显然,这是一个无休止的递归调用。
|
||||
|
||||
怎么去访问这个 “真正的” `open()` 函数呢?它需要去使用程序接口进行动态链接。它比听起来更简单。我们来看一个完整的示例,然后,我将详细解释到底发生了什么:
|
||||
|
||||
*inspect_open.c:*
|
||||
|
||||
```
|
||||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef int (*orig_open_f_type)(const char *pathname, int flags);
|
||||
|
||||
int open(const char *pathname, int flags, ...)
|
||||
{
|
||||
/* Some evil injected code goes here. */
|
||||
|
||||
orig_open_f_type orig_open;
|
||||
orig_open = (orig_open_f_type)dlsym(RTLD_NEXT,"open");
|
||||
return orig_open(pathname,flags);
|
||||
}
|
||||
```
|
||||
|
||||
`dlfcn.h` 是我们后面用到的 `dlsym` 函数所需要的。那个奇怪的 `#define` 是命令编译器去允许一些非标准的东西,我们需要它来启用 `dlfcn.h` 中的 `RTLD_NEXT`。那个 `typedef` 只是创建了一个函数指针类型的别名,它的参数等同于原始的 `open` —— 它现在的别名是 `orig_open_f_type`,我们将在后面用到它。
|
||||
|
||||
我们定制的 `open(...)` 的主体是由一些代码构成。它的最后部分创建了一个新的函数指针 `orig_open`,它指向原始的 `open(...)` 函数。为了得到那个函数的地址,我们请求 `dlsym` 在动态库堆栈上为我们查找下一个 `open()` 函数。最后,我们调用了那个函数(传递了与我们的假冒 `open()` 一样的参数),并且返回它的返回值。
|
||||
|
||||
我使用下面的内容作为我的 “邪恶的注入代码”:
|
||||
|
||||
*inspect_open.c (片段):*
|
||||
|
||||
```
|
||||
printf("The victim used open(...) to access '%s'!!!\n",pathname); //remember to include stdio.h!
|
||||
```
|
||||
|
||||
要编译它,我需要稍微调整一下编译参数:
|
||||
|
||||
```
|
||||
gcc -shared -fPIC inspect_open.c -o inspect_open.so -ldl
|
||||
```
|
||||
|
||||
我增加了 `-ldl`,因此,它将这个共享库链接到 `libdl` —— 它提供了 `dlsym` 函数。(不,我还没有创建一个假冒版的 `dlsym` ,虽然这样更有趣)
|
||||
|
||||
因此,结果是什么呢?一个实现了 `open(...)` 函数的共享库,除了它有 _输出_ 文件路径的意外作用以外,其它的表现和真正的 `open(...)` 函数 **一模一样**。:-)
|
||||
|
||||
如果这个强大的诀窍还没有说服你,是时候去尝试下面的这个示例了:
|
||||
|
||||
```
|
||||
LD_PRELOAD=$PWD/inspect_open.so gnome-calculator
|
||||
```
|
||||
|
||||
我鼓励你去看看自己实验的结果,但是简单来说,它实时列出了这个应用程序可以访问到的每个文件。
|
||||
|
||||
我相信它并不难想像为什么这可以用于去调试或者研究未知的应用程序。请注意,这个特定诀窍并不完整,因为 `open()` 并不是唯一一个打开文件的函数 …… 例如,在标准库中也有一个 `open64()`,并且为了完整地研究,你也需要为它去创建一个假冒的。
|
||||
|
||||
### 可能的用法
|
||||
|
||||
如果你一直跟着我享受上面的过程,让我推荐一个使用这个诀窍能做什么的一大堆创意。记住,你可以在不损害原始应用程序的同时做任何你想做的事情!
|
||||
|
||||
1. ~~获得 root 权限~~。你想多了!你不会通过这种方法绕过安全机制的。(一个专业的解释是:如果 ruid != euid,库不会通过这种方法预加载的。)
|
||||
2. 欺骗游戏:**取消随机化**。这是我演示的第一个示例。对于一个完整的工作案例,你将需要去实现一个定制的 `random()` 、`rand_r()`、`random_r()`,也有一些应用程序是从 `/dev/urandom` 之类的读取,你可以通过使用一个修改过的文件路径来运行原始的 `open()` 来把它们重定向到 `/dev/null`。而且,一些应用程序可能有它们自己的随机数生成算法,这种情况下你似乎是没有办法的(除非,按下面的第 10 点去操作)。但是对于一个新手来说,它看起来很容易上手。
|
||||
3. 欺骗游戏:**让子弹飞一会** 。实现所有的与时间有关的标准函数,让假冒的时间变慢两倍,或者十倍。如果你为时间测量和与时间相关的 `sleep` 或其它函数正确地计算了新的值,那么受影响的应用程序将认为时间变慢了(你想的话,也可以变快),并且,你可以体验可怕的 “子弹时间” 的动作。或者 **甚至更进一步**,你的共享库也可以成为一个 DBus 客户端,因此你可以使用它进行实时的通讯。绑定一些快捷方式到定制的命令,并且在你的假冒的时间函数上使用一些额外的计算,让你可以有能力按你的意愿去启用和禁用慢进或快进任何时间。
|
||||
4. 研究应用程序:**列出访问的文件**。它是我演示的第二个示例,但是这也可以进一步去深化,通过记录和监视所有应用程序的文件 I/O。
|
||||
5. 研究应用程序:**监视因特网访问**。你可以使用 Wireshark 或者类似软件达到这一目的,但是,使用这个诀窍你可以真实地控制基于 web 的应用程序发送了什么,不仅是看看,而是也能影响到交换的数据。这里有很多的可能性,从检测间谍软件到欺骗多用户游戏,或者分析和逆向工程使用闭源协议的应用程序。
|
||||
6. 研究应用程序:**检查 GTK 结构** 。为什么只局限于标准库?让我们在所有的 GTK 调用中注入一些代码,因此我们就可以知道一个应用程序使用了哪些组件,并且,知道它们的构成。然后这可以渲染出一个图像或者甚至是一个 gtkbuilder 文件!如果你想去学习一些应用程序是怎么管理其界面的,这个方法超级有用!
|
||||
7. **在沙盒中运行不安全的应用程序**。如果你不信任一些应用程序,并且你可能担心它会做一些如 `rm -rf /` 或者一些其它不希望的文件活动,你可以通过修改传递到文件相关的函数(不仅是 `open` ,也包括删除目录等)的参数,来重定向所有的文件 I/O 操作到诸如 `/tmp` 这样地方。还有更难的诀窍,如 chroot,但是它也给你提供更多的控制。它可以更安全地完全 “封装”,但除非你真的知道你在做什么,不要以这种方式真的运行任何恶意软件。
|
||||
8. **实现特性** 。[zlibc][1] 是明确以这种方法运行的一个真实的库;它可以在访问文件时解压文件,因此,任何应用程序都可以在无需实现解压功能的情况下访问压缩数据。
|
||||
9. **修复 bug**。另一个现实中的示例是:不久前(我不确定现在是否仍然如此)Skype(它是闭源的软件)从某些网络摄像头中捕获视频有问题。因为 Skype 并不是自由软件,源文件不能被修改,这就可以通过使用预加载一个解决了这个问题的库的方式来修复这个 bug。
|
||||
10. 手工方式 **访问应用程序拥有的内存**。请注意,你可以通过这种方式去访问所有应用程序的数据。如果你有类似的软件,如 CheatEngine/scanmem/GameConqueror 这可能并不会让人惊讶,但是,它们都要求 root 权限才能工作,而 `LD_PRELOAD` 则不需要。事实上,通过一些巧妙的诀窍,你注入的代码可以访问所有的应用程序内存,从本质上看,是因为它是通过应用程序自身得以运行的。你可以修改这个应用程序能修改的任何东西。你可以想像一下,它允许你做许多的底层的侵入…… ,但是,关于这个主题,我将在某个时候写一篇关于它的文章。
|
||||
|
||||
这里仅是一些我想到的创意。我希望你能找到更多,如果你做到了 —— 通过下面的评论区共享出来吧!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/
|
||||
|
||||
作者:[Rafał Cieślak][a]
|
||||
译者:[qhwdw](https://github.com/qhwdw)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://rafalcieslak.wordpress.com/
|
||||
[1]:http://www.zlibc.linux.lu/index.html
|
||||
|
||||
|
@ -0,0 +1,219 @@
|
||||
逻辑卷管理(LVM) Linux 用户指南
|
||||
============================================================
|
||||
|
||||
![Logical Volume Management (LVM)](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/rh_003499_01_other11x_cc.png?itok=I_kCDYj0 "Logical Volume Management (LVM)")
|
||||
|
||||
Image by : opensource.com
|
||||
|
||||
管理磁盘空间对系统管理员来说是一件重要的日常工作。一旦磁盘空间耗尽就需要进行一系列耗时而又复杂的任务,以提升磁盘分区中可用的磁盘空间。它也需要系统离线才能处理。通常这种任务会涉及到安装一个新的硬盘、引导至恢复模式或者单用户模式、在新硬盘上创建一个分区和一个文件系统、挂载到临时挂载点去从一个太小的文件系统中移动数据到较大的新位置、修改 `/etc/fstab` 文件的内容来反映出新分区的正确设备名、以及重新引导来重新挂载新的文件系统到正确的挂载点。
|
||||
|
||||
我想告诉你的是,当 LVM (逻辑卷管理)首次出现在 Fedora Linux 中时,我是非常抗拒它的。我最初的反应是,我并不需要在我和我的设备之间有这种额外的抽象层。结果是我错了,逻辑卷管理是非常有用的。
|
||||
|
||||
LVM 让磁盘空间管理非常灵活。它提供的功能诸如在文件系统已挂载和活动时,很可靠地增加磁盘空间到一个逻辑卷和它的文件系统中,并且,它也允许你将多个物理磁盘和分区融合进一个可以分割成逻辑卷(LV)的单个卷组(VG)中。
|
||||
|
||||
卷管理也允许你去减少分配给一个逻辑卷的磁盘空间数量,但是,这里有两个要求,第一,卷必须是未挂载的。第二,在卷空间调整之前,文件系统本身的空间大小必须先被减少。
|
||||
|
||||
有一个重要的提示是,文件系统本身必须允许重新调整大小的操作。当重新提升文件系统大小的时候,EXT2、3 和 4 文件系统都允许离线(未挂载状态)或者在线(挂载状态)重新调整大小。你应该去认真了解你打算去调整的文件系统的详细情况,去验证它们是否可以完全调整大小,尤其是否可以在线调整大小。
|
||||
|
||||
### 即时扩展一个文件系统
|
||||
|
||||
在我安装一个新的发行版到我的生产用机器中之前,我总是喜欢在一个 VirtualBox 虚拟机中运行这个新的发行版一段时间,以确保它没有任何的致命的问题存在。在几年前的一个早晨,我在我的主要使用的工作站上的虚拟机中安装了一个新发行的 Fedora 版本。我认为我有足够的磁盘空间分配给安装虚拟机的主文件系统。但是,我错了,大约在安装到三分之一时,我耗尽了我的文件系统的空间。幸运的是,VirtualBox 检测到了磁盘空间不足的状态,并且暂停了虚拟机,然后显示了一个明确指出问题所在的错误信息。
|
||||
|
||||
请注意,这个问题并不是虚拟机磁盘太小造成的,而是由于宿主机上空间不足,导致虚拟机上的虚拟磁盘在宿主机上的逻辑卷中没有足够的空间去扩展。
|
||||
|
||||
因为许多现在的发行版都缺省使用了逻辑卷管理,并且在我的卷组中有一些可用的空余空间,我可以分配额外的磁盘空间到适当的逻辑卷,然后即时扩展宿主机的文件系统。这意味着我不需要去重新格式化整个硬盘,以及重新安装操作系统或者甚至是重启机器。我不过是分配了一些可用空间到适当的逻辑卷中,并且重新调整了文件系统的大小 —— 所有的这些操作都在文件系统在线并且运行着程序的状态下进行的,虚拟机也一直使用着宿主机文件系统。在调整完逻辑卷和文件系统的大小之后,我恢复了虚拟机的运行,并且继续进行安装过程,就像什么问题都没有发生过一样。
|
||||
|
||||
虽然这种问题你可能从来也没有遇到过,但是,许多人都遇到过重要程序在运行过程中发生磁盘空间不足的问题。而且,虽然许多程序,尤其是 Windows 程序,并不像 VirtualBox 一样写的很好,且富有弹性,Linux 逻辑卷管理可以使它在不丢失数据的情况下去恢复,也不需要去进行耗时的安装过程。
|
||||
|
||||
### LVM 结构
|
||||
|
||||
逻辑卷管理的磁盘环境结构如下面的图 1 所示。逻辑卷管理允许多个单独的硬盘和/或磁盘分区组合成一个单个的卷组(VG)。卷组然后可以再划分为逻辑卷(LV)或者被用于分配成一个大的单一的卷。普通的文件系统,如 EXT3 或者 EXT4,可以创建在一个逻辑卷上。
|
||||
|
||||
在图 1 中,两个完整的物理硬盘和一个第三块硬盘的一个分区组合成一个单个的卷组。在这个卷组中创建了两个逻辑卷和文件系统,比如,可以在每个逻辑卷上创建一个 EXT3 或者 EXT4 的文件系统。
|
||||
|
||||
![lvm.png](https://opensource.com/sites/default/files/resize/images/life-uploads/lvm-520x222.png)
|
||||
|
||||
_图 1: LVM 允许组合分区和整个硬盘到卷组中_
|
||||
|
||||
在一个主机上增加磁盘空间是非常简单的,在我的经历中,这种事情是很少的。下面列出了基本的步骤。你也可以创建一个完整的新卷组或者增加新的空间到一个已存在的逻辑卷中,或者创建一个新的逻辑卷。
|
||||
|
||||
### 增加一个新的逻辑卷
|
||||
|
||||
有时候需要在主机上增加一个新的逻辑卷。例如,在被提示包含我的 VirtualBox 虚拟机的虚拟磁盘的 `/home` 文件系统被填满时,我决定去创建一个新的逻辑卷,以存储包含虚拟磁盘在内的虚拟机数据。这将在我的 `/home` 文件系统中释放大量的空间,并且也允许我去独立地管理虚拟机的磁盘空间。
|
||||
|
||||
增加一个新的逻辑卷的基本步骤如下:
|
||||
|
||||
1. 如有需要,安装一个新硬盘。
|
||||
2. 可选: 在硬盘上创建一个分区。
|
||||
3. 在硬盘上创建一个完整的物理卷(PV)或者一个分区。
|
||||
4. 分配新的物理卷到一个已存在的卷组(VG)中,或者创建一个新的卷组。
|
||||
5. 从卷空间中创建一个新的逻辑卷(LV)。
|
||||
6. 在新的逻辑卷中创建一个文件系统。
|
||||
7. 在 `/etc/fstab` 中增加适当的条目以挂载文件系统。
|
||||
8. 挂载文件系统。
|
||||
|
||||
为了更详细的介绍,接下来将使用一个示例作为一个实验去教授关于 Linux 文件系统的知识。
|
||||
|
||||
#### 示例
|
||||
|
||||
这个示例展示了怎么用命令行去扩展一个已存在的卷组,并给它增加更多的空间,在那个空间上创建一个新的逻辑卷,然后在逻辑卷上创建一个文件系统。这个过程一直在运行着和已挂载的文件系统上执行。
|
||||
|
||||
警告:仅 EXT3 和 EXT4 文件系统可以在运行和挂载状态下调整大小。许多其它的文件系统,包括 BTRFS 和 ZFS 是不能这样做的。
|
||||
|
||||
##### 安装硬盘
|
||||
|
||||
如果在系统中现有硬盘上的卷组中没有足够的空间可以增加,那么可能需要去增加一块新的硬盘,然后创建空间增加到逻辑卷中。首先,安装物理硬盘,然后,接着执行后面的步骤。
|
||||
|
||||
##### 从硬盘上创建物理卷
|
||||
|
||||
首先需要去创建一个新的物理卷(PV)。使用下面的命令,它假设新硬盘已经分配为 `/dev/hdd`。
|
||||
|
||||
```
|
||||
pvcreate /dev/hdd
|
||||
```
|
||||
|
||||
在新硬盘上创建一个任意分区并不是必需的。创建的物理卷将被逻辑卷管理器识别为一个新安装的未处理的磁盘或者一个类型为 83 的 Linux 分区。如果你想去使用整个硬盘,创建一个分区并没有什么特别的好处,而且元数据所用的磁盘空间也能用做 PV 的一部分使用。
|
||||
|
||||
##### 扩展已存在的卷组
|
||||
|
||||
在这个示例中,我将扩展一个已存在的卷组,而不是创建一个新的;你可以选择其它的方式。在物理磁盘已经创建之后,扩展已存在的卷组(VG)去包含新 PV 的空间。在这个示例中,已存在的卷组命名为:MyVG01。
|
||||
|
||||
```
|
||||
vgextend /dev/MyVG01 /dev/hdd
|
||||
```
|
||||
|
||||
##### 创建一个逻辑卷
|
||||
|
||||
首先,在卷组中从已存在的空余空间中创建逻辑卷。下面的命令创建了一个 50 GB 大小的 LV。这个卷组的名字为 MyVG01,然后,逻辑卷的名字为 Stuff。
|
||||
|
||||
```
|
||||
lvcreate -L +50G --name Stuff MyVG01
|
||||
```
|
||||
|
||||
##### 创建文件系统
|
||||
|
||||
创建逻辑卷并不会创建文件系统。这个任务必须被单独执行。下面的命令在新创建的逻辑卷中创建了一个 EXT4 文件系统。
|
||||
|
||||
```
|
||||
mkfs -t ext4 /dev/MyVG01/Stuff
|
||||
```
|
||||
|
||||
##### 增加一个文件系统卷标
|
||||
|
||||
增加一个文件系统卷标,更易于在文件系统以后出现问题时识别它。
|
||||
|
||||
```
|
||||
e2label /dev/MyVG01/Stuff Stuff
|
||||
```
|
||||
|
||||
##### 挂载文件系统
|
||||
|
||||
在这个时候,你可以创建一个挂载点,并在 `/etc/fstab` 文件系统中添加合适的条目,以挂载文件系统。
|
||||
|
||||
你也可以去检查并校验创建的卷是否正确。你可以使用 `df`、`lvs` 和 `vgs` 命令去做这些工作。
|
||||
|
||||
### 在 LVM 文件系统中调整逻辑卷大小
|
||||
|
||||
从 Unix 的第一个版本开始,对文件系统的扩展需求就一直伴随,Linux 也不例外。随着有了逻辑卷管理(LVM),现在更加容易了。
|
||||
|
||||
1. 如有需要,安装一个新硬盘。
|
||||
2. 可选: 在硬盘上创建一个分区。
|
||||
3. 在硬盘上创建一个完整的物理卷(PV)或者一个分区。
|
||||
4. 分配新的物理卷到一个已存在的卷组(VG)中,或者创建一个新的卷组。
|
||||
5. 从卷空间中创建一个新的逻辑卷(LV),或者用卷组中部分或全部空间扩展已有的逻辑卷。
|
||||
6. 如果创建了新的逻辑卷,那么在上面创建一个文件系统。如果对已有的逻辑卷增加空间,使用 `resize2fs` 命令来增大文件系统来填满逻辑卷。
|
||||
7. 在 `/etc/fstab` 中增加适当的条目以挂载文件系统。
|
||||
8. 挂载文件系统。
|
||||
|
||||
|
||||
#### 示例
|
||||
|
||||
这个示例展示了怎么用命令行去扩展一个已存在的卷组。它会给 `/Staff` 文件系统增加大约 50GB 的空间。这将生成一个可用于挂载的文件系统,在 Linux 2.6 内核(及更高)上可即时使用 EXT3 和 EXT4 文件系统。我不推荐你用于任何关键系统,但是这是可行的,我已经成功了好多次;即使是在根(`/`)文件系统上。是否使用自己把握风险。
|
||||
|
||||
警告:仅 EXT3 和 EXT4 文件系统可以在运行和挂载状态下调整大小。许多其它的文件系统,包括 BTRFS 和 ZFS 是不能这样做的。
|
||||
|
||||
##### 安装硬盘
|
||||
|
||||
如果在系统中现有硬盘上的卷组中没有足够的空间可以增加,那么可能需要去增加一块新的硬盘,然后创建空间增加到逻辑卷中。首先,安装物理硬盘,然后,接着执行后面的步骤。
|
||||
|
||||
##### 从硬盘上创建物理卷
|
||||
|
||||
首先需要去创建一个新的物理卷(PV)。使用下面的命令,它假设新硬盘已经分配为 `/dev/hdd`。
|
||||
|
||||
```
|
||||
pvcreate /dev/hdd
|
||||
```
|
||||
|
||||
在新硬盘上创建一个任意分区并不是必需的。创建的物理卷将被逻辑卷管理器识别为一个新安装的未处理的磁盘或者一个类型为 83 的 Linux 分区。如果你想去使用整个硬盘,创建一个分区并没有什么特别的好处,而且元数据所用的磁盘空间也能用做 PV 的一部分使用。
|
||||
|
||||
##### 增加物理卷到已存在的卷组
|
||||
|
||||
在这个示例中,我将使用一个新的物理卷来扩展一个已存在的卷组。在物理卷已经创建之后,扩展已存在的卷组(VG)去包含新 PV 的空间。在这个示例中,已存在的卷组命名为:MyVG01。
|
||||
|
||||
```
|
||||
vgextend /dev/MyVG01 /dev/hdd
|
||||
```
|
||||
|
||||
##### 扩展逻辑卷
|
||||
|
||||
首先,在卷组中从已存在的空余空间中创建逻辑卷。下面的命令创建了一个 50 GB 大小的 LV。这个卷组的名字为 MyVG01,然后,逻辑卷的名字为 Stuff。
|
||||
|
||||
```
|
||||
lvcreate -L +50G --name Stuff MyVG01
|
||||
```
|
||||
|
||||
##### 扩展文件系统
|
||||
|
||||
如果你使用了 `-r` 选项,扩展逻辑卷也将扩展器文件系统。如果你不使用 `-r` 选项,该操作不行单独执行。下面的命令在新调整大小的逻辑卷中调整了文件系统大小。
|
||||
|
||||
```
|
||||
resize2fs /dev/MyVG01/Stuff
|
||||
```
|
||||
|
||||
你也可以去检查并校验调整大小的卷是否正确。你可以使用 `df`、`lvs` 和 `vgs` 命令去做这些工作。
|
||||
|
||||
### 提示
|
||||
|
||||
过去几年来,我学习了怎么去做让逻辑卷管理更加容易的一些知识,希望这些提示对你有价值。
|
||||
|
||||
* 除非你有一个明确的原因去使用其它的文件系统外,推荐使用可扩展的文件系统。除了 EXT2、3、和 4 外,并不是所有的文件系统都支持调整大小。EXT 文件系统不但速度快,而且它很高效。在任何情况下,如果默认的参数不能满足你的需要,它们(指的是文件系统参数)可以通过一位知识丰富的系统管理员来调优它。
|
||||
* 使用有意义的卷和卷组名字。
|
||||
* 使用 EXT 文件系统标签
|
||||
|
||||
我知道,像我一样,大多数的系统管理员都抗拒逻辑卷管理。我希望这篇文章能够鼓励你至少去尝试一个 LVM。如果你能那样做,我很高兴;因为,自从我使用它之后,我的硬盘管理任务变得如此的简单。
|
||||
|
||||
|
||||
### 关于作者
|
||||
|
||||
[![](https://opensource.com/sites/default/files/styles/profile_pictures/public/david-crop.jpg?itok=oePpOpyV)][10]
|
||||
|
||||
David Both 是一位 Linux 和开源软件的倡导者,住在 Raleigh, North Carolina。他在 IT 行业工作了 40 多年,在 IBM 工作了 20 多年。在 IBM 期间,他在 1981 年为最初的 IBM PC 编写了第一个培训课程。他曾教授红帽的 RHCE 课程,并在 MCI Worldcom、Cisco和 North Carolina 工作。他已经使用 Linux 和开源软件工作了将近 20 年。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/business/16/9/linux-users-guide-lvm
|
||||
|
||||
作者:[David Both](a)
|
||||
译者:[qhwdw](https://github.com/qhwdw)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/dboth
|
||||
[1]:https://opensource.com/resources/what-is-linux?intcmp=70160000000h1jYAAQ&utm_source=intcallout&utm_campaign=linuxcontent
|
||||
[2]:https://opensource.com/resources/what-are-linux-containers?intcmp=70160000000h1jYAAQ&utm_source=intcallout&utm_campaign=linuxcontent
|
||||
[3]:https://developers.redhat.com/promotions/linux-cheatsheet/?intcmp=70160000000h1jYAAQ&utm_source=intcallout&utm_campaign=linuxcontent
|
||||
[4]:https://developers.redhat.com/cheat-sheet/advanced-linux-commands-cheatsheet?intcmp=70160000000h1jYAAQ&utm_source=intcallout&utm_campaign=linuxcontent
|
||||
[5]:https://opensource.com/tags/linux?intcmp=70160000000h1jYAAQ&utm_source=intcallout&utm_campaign=linuxcontent
|
||||
[6]:https://opensource.com/business/16/9/linux-users-guide-lvm?rate=79vf1js7A7rlp-I96YFneopUQqsa2SuB-g-og7eiF1U
|
||||
[7]:https://opensource.com/users/dboth
|
||||
[8]:https://opensource.com/users/dboth
|
||||
[9]:https://opensource.com/user/14106/feed
|
||||
[10]:https://opensource.com/users/dboth
|
||||
[11]:https://opensource.com/users/dboth
|
||||
[12]:https://opensource.com/users/dboth
|
||||
[13]:https://opensource.com/business/16/9/linux-users-guide-lvm#comments
|
||||
[14]:https://opensource.com/tags/business
|
||||
[15]:https://opensource.com/tags/linux
|
||||
[16]:https://opensource.com/tags/how-tos-and-tutorials
|
||||
[17]:https://opensource.com/tags/sysadmin
|
331
published/201712/20161216 Kprobes Event Tracing on ARMv8.md
Normal file
331
published/201712/20161216 Kprobes Event Tracing on ARMv8.md
Normal file
@ -0,0 +1,331 @@
|
||||
ARMv8 上的 kprobes 事件跟踪
|
||||
==============
|
||||
|
||||
![core-dump](http://www.linaro.org/wp-content/uploads/2016/02/core-dump.png)
|
||||
|
||||
### 介绍
|
||||
|
||||
kprobes 是一种内核功能,它允许通过在执行(或模拟)断点指令之前和之后,设置调用开发者提供例程的任意断点来检测内核。可参见 kprobes 文档^注1 获取更多信息。基本的 kprobes 功能可使用 `CONFIG_KPROBEES` 来选择。在 arm64 的 v4.8 内核发行版中, kprobes 支持被添加到主线。
|
||||
|
||||
在这篇文章中,我们将介绍 kprobes 在 arm64 上的使用,通过在命令行中使用 debugfs 事件追踪接口来收集动态追踪事件。这个功能在一些架构(包括 arm32)上可用已经有段时间,现在在 arm64 上也能使用了。这个功能可以无需编写任何代码就能使用 kprobes。
|
||||
|
||||
### 探针类型
|
||||
|
||||
kprobes 子系统提供了三种不同类型的动态探针,如下所述。
|
||||
|
||||
#### kprobes
|
||||
|
||||
基本探针是 kprobes 插入的一个软件断点,用以替代你正在探测的指令,当探测点被命中时,它为最终的单步执行(或模拟)保存下原始指令。
|
||||
|
||||
#### kretprobes
|
||||
|
||||
kretprobes 是 kprobes 的一部分,它允许拦截返回函数,而不必在返回点设置一个探针(或者可能有多个探针)。对于支持的架构(包括 ARMv8),只要选择 kprobes,就可以选择此功能。
|
||||
|
||||
#### jprobes
|
||||
|
||||
jprobes 允许通过提供一个具有相同<ruby>调用签名<rt>call signature</rt></ruby>的中间函数来拦截对一个函数的调用,这里中间函数将被首先调用。jprobes 只是一个编程接口,它不能通过 debugfs 事件追踪子系统来使用。因此,我们将不会在这里进一步讨论 jprobes。如果你想使用 jprobes,请参考 kprobes 文档。
|
||||
|
||||
### 调用 kprobes
|
||||
|
||||
kprobes 提供一系列能从内核代码中调用的 API 来设置探测点和当探测点被命中时调用的注册函数。在不往内核中添加代码的情况下,kprobes 也是可用的,这是通过写入特定事件追踪的 debugfs 文件来实现的,需要在文件中设置探针地址和信息,以便在探针被命中时记录到追踪日志中。后者是本文将要讨论的重点。最后 kprobes 可以通过 perl 命令来使用。
|
||||
|
||||
#### kprobes API
|
||||
|
||||
内核开发人员可以在内核中编写函数(通常在专用的调试模块中完成)来设置探测点,并且在探测指令执行前和执行后立即执行任何所需操作。这在 kprobes.txt 中有很好的解释。
|
||||
|
||||
#### 事件追踪
|
||||
|
||||
事件追踪子系统有自己的自己的文档^注2 ,对于了解一般追踪事件的背景可能值得一读。事件追踪子系统是<ruby>追踪点<rt>tracepoints</rt></ruby>和 kprobes 事件追踪的基础。事件追踪文档重点关注追踪点,所以请在查阅文档时记住这一点。kprobes 与追踪点不同的是没有预定义的追踪点列表,而是采用动态创建的用于触发追踪事件信息收集的任意探测点。事件追踪子系统通过一系列 debugfs 文件来控制和监视。事件追踪(`CONFIG_EVENT_TRACING`)将在被如 kprobe 事件追踪子系统等需要时自动选择。
|
||||
|
||||
##### kprobes 事件
|
||||
|
||||
使用 kprobes 事件追踪子系统,用户可以在内核任意断点处指定要报告的信息,只需要指定任意现有可探测指令的地址以及格式化信息即可确定。在执行过程中遇到断点时,kprobes 将所请求的信息传递给事件追踪子系统的公共部分,这些部分将数据格式化并追加到追踪日志中,就像追踪点的工作方式一样。kprobes 使用一个类似的但是大部分是独立的 debugfs 文件来控制和显示追踪事件信息。该功能可使用 `CONFIG_KPROBE_EVENT` 来选择。Kprobetrace 文档^ 注3 提供了如何使用 kprobes 事件追踪的基本信息,并且应当被参考用以了解以下介绍示例的详细信息。
|
||||
|
||||
#### kprobes 和 perf
|
||||
|
||||
perf 工具为 kprobes 提供了另一个命令行接口。特别地,`perf probe` 允许探测点除了由函数名加偏移量和地址指定外,还可由源文件和行号指定。perf 接口实际上是使用 kprobes 的 debugfs 接口的封装器。
|
||||
|
||||
### Arm64 kprobes
|
||||
|
||||
上述所有 kprobes 的方面现在都在 arm64 上得到实现,然而实际上与其它架构上的有一些不同:
|
||||
|
||||
* 注册名称参数当然是依架构而特定的,并且可以在 ARM ARM 中找到。
|
||||
* 目前不是所有的指令类型都可被探测。当前不可探测的指令包括 mrs/msr(除了 DAIF 读取)、异常生成指令、eret 和 hint(除了 nop 变体)。在这些情况下,只探测一个附近的指令来代替是最简单的。这些指令在探测的黑名单里是因为在 kprobes 单步执行或者指令模拟时它们对处理器状态造成的改变是不安全的,这是由于 kprobes 构造的单步执行上下文和指令所需要的不一致,或者是由于指令不能容忍在 kprobes 中额外的处理时间和异常处理(ldx/stx)。
|
||||
* 试图识别在 ldx/stx 序列中的指令并且防止探测,但是理论上这种检查可能会失败,导致允许探测到的原子序列永远不会成功。当探测原子代码序列附近时应该小心。
|
||||
* 注意由于 linux ARM64 调用约定的具体信息,为探测函数可靠地复制栈帧是不可能的,基于此不要试图用 jprobes 这样做,这一点与支持 jprobes 的大多数其它架构不同。这样的原因是被调用者没有足够的信息来确定需要的栈数量。
|
||||
* 注意当探针被命中时,一个探针记录的栈指针信息将反映出使用中的特定栈指针,它是内核栈指针或者中断栈指针。
|
||||
* 有一组内核函数是不能被探测的,通常因为它们作为 kprobes 处理的一部分被调用。这组函数的一部分是依架构特定的,并且也包含如异常入口代码等。
|
||||
|
||||
### 使用 kprobes 事件追踪
|
||||
|
||||
kprobes 的一个常用例子是检测函数入口和/或出口。因为只需要使用函数名来作为探针地址,它安装探针特别简单。kprobes 事件追踪将查看符号名称并且确定地址。ARMv8 调用标准定义了函数参数和返回值的位置,并且这些可以作为 kprobes 事件处理的一部分被打印出来。
|
||||
|
||||
#### 例子: 函数入口探测
|
||||
|
||||
检测 USB 以太网驱动程序复位功能:
|
||||
|
||||
```
|
||||
$ pwd
|
||||
/sys/kernel/debug/tracing
|
||||
$ cat > kprobe_events <<EOF
|
||||
p ax88772_reset %x0
|
||||
EOF
|
||||
$ echo 1 > events/kprobes/enable
|
||||
```
|
||||
|
||||
此时每次该驱动的 `ax8872_reset()` 函数被调用,追踪事件都将会被记录。这个事件将显示指向通过作为此函数的唯一参数的 `X0`(按照 ARMv8 调用标准)传入的 `usbnet` 结构的指针。插入需要以太网驱动程序的 USB 加密狗后,我们看见以下追踪信息:
|
||||
|
||||
```
|
||||
$ cat trace
|
||||
# tracer: nop
|
||||
#
|
||||
# entries-in-buffer/entries-written: 1/1 #P:8
|
||||
#
|
||||
# _—–=> irqs-off
|
||||
# / _—-=> need-resched
|
||||
# | / _—=> hardirq/softirq
|
||||
# || / _–=> preempt-depth
|
||||
# ||| / delay
|
||||
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
|
||||
# | | | |||| | |
|
||||
kworker/0:0-4 [000] d… 10972.102939: p_ax88772_reset_0:
|
||||
(ax88772_reset+0x0/0x230) arg1=0xffff800064824c80
|
||||
```
|
||||
|
||||
这里我们可以看见传入到我们的探测函数的指针参数的值。由于我们没有使用 kprobes 事件追踪的可选标签功能,我们需要的信息自动被标注为 `arg1`。注意这指向我们需要 kprobes 记录这个探针的一组值的第一个,而不是函数参数的实际位置。在这个例子中它也只是碰巧是我们探测函数的第一个参数。
|
||||
|
||||
#### 例子: 函数入口和返回探测
|
||||
|
||||
kretprobe 功能专门用于探测函数返回。在函数入口 kprobes 子系统将会被调用并且建立钩子以便在函数返回时调用,钩子将记录需求事件信息。对最常见情况,返回信息通常在 `X0` 寄存器中,这是非常有用的。在 `%x0` 中返回值也可以被称为 `$retval`。以下例子也演示了如何提供一个可读的标签来展示有趣的信息。
|
||||
|
||||
使用 kprobes 和 kretprobe 检测内核 `do_fork()` 函数来记录参数和结果的例子:
|
||||
|
||||
```
|
||||
$ cd /sys/kernel/debug/tracing
|
||||
$ cat > kprobe_events <<EOF
|
||||
p _do_fork %x0 %x1 %x2 %x3 %x4 %x5
|
||||
r _do_fork pid=%x0
|
||||
EOF
|
||||
$ echo 1 > events/kprobes/enable
|
||||
```
|
||||
|
||||
此时每次对 `_do_fork()` 的调用都会产生两个记录到 trace 文件的 kprobe 事件,一个报告调用参数值,另一个报告返回值。返回值在 trace 文件中将被标记为 `pid`。这里是三次 fork 系统调用执行后的 trace 文件的内容:
|
||||
|
||||
```
|
||||
_$ cat trace
|
||||
# tracer: nop
|
||||
#
|
||||
# entries-in-buffer/entries-written: 6/6 #P:8
|
||||
#
|
||||
# _—–=> irqs-off
|
||||
# / _—-=> need-resched
|
||||
# | / _—=> hardirq/softirq
|
||||
# || / _–=> preempt-depth
|
||||
# ||| / delay
|
||||
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
|
||||
# | | | |||| | |
|
||||
bash-1671 [001] d… 204.946007: p__do_fork_0: (_do_fork+0x0/0x3e4) arg1=0x1200011 arg2=0x0 arg3=0x0 arg4=0x0 arg5=0xffff78b690d0 arg6=0x0
|
||||
bash-1671 [001] d..1 204.946391: r__do_fork_0: (SyS_clone+0x18/0x20 <- _do_fork) pid=0x724
|
||||
bash-1671 [001] d… 208.845749: p__do_fork_0: (_do_fork+0x0/0x3e4) arg1=0x1200011 arg2=0x0 arg3=0x0 arg4=0x0 arg5=0xffff78b690d0 arg6=0x0
|
||||
bash-1671 [001] d..1 208.846127: r__do_fork_0: (SyS_clone+0x18/0x20 <- _do_fork) pid=0x725
|
||||
bash-1671 [001] d… 214.401604: p__do_fork_0: (_do_fork+0x0/0x3e4) arg1=0x1200011 arg2=0x0 arg3=0x0 arg4=0x0 arg5=0xffff78b690d0 arg6=0x0
|
||||
bash-1671 [001] d..1 214.401975: r__do_fork_0: (SyS_clone+0x18/0x20 <- _do_fork) pid=0x726_
|
||||
```
|
||||
|
||||
#### 例子: 解引用指针参数
|
||||
|
||||
对于指针值,kprobes 事件处理子系统也允许解引用和打印所需的内存内容,适用于各种基本数据类型。为了展示所需字段,手动计算结构的偏移量是必要的。
|
||||
|
||||
检测 `_do_wait()` 函数:
|
||||
|
||||
```
|
||||
$ cat > kprobe_events <<EOF
|
||||
p:wait_p do_wait wo_type=+0(%x0):u32 wo_flags=+4(%x0):u32
|
||||
r:wait_r do_wait $retval
|
||||
EOF
|
||||
$ echo 1 > events/kprobes/enable
|
||||
```
|
||||
|
||||
注意在第一个探针中使用的参数标签是可选的,并且可用于更清晰地识别记录在追踪日志中的信息。带符号的偏移量和括号表明了寄存器参数是指向记录在追踪日志中的内存内容的指针。`:u32` 表明了内存位置包含一个无符号的 4 字节宽的数据(在这个例子中指局部定义的结构中的一个 emum 和一个 int)。
|
||||
|
||||
探针标签(冒号后)是可选的,并且将用来识别日志中的探针。对每个探针来说标签必须是独一无二的。如果没有指定,将从附近的符号名称自动生成一个有用的标签,如前面的例子所示。
|
||||
|
||||
也要注意 `$retval` 参数可以只是指定为 `%x0`。
|
||||
|
||||
这里是两次 fork 系统调用执行后的 trace 文件的内容:
|
||||
|
||||
```
|
||||
$ cat trace
|
||||
# tracer: nop
|
||||
#
|
||||
# entries-in-buffer/entries-written: 4/4 #P:8
|
||||
#
|
||||
# _—–=> irqs-off
|
||||
# / _—-=> need-resched
|
||||
# | / _—=> hardirq/softirq
|
||||
# || / _–=> preempt-depth
|
||||
# ||| / delay
|
||||
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
|
||||
# | | | |||| | |
|
||||
bash-1702 [001] d… 175.342074: wait_p: (do_wait+0x0/0x260) wo_type=0x3 wo_flags=0xe
|
||||
bash-1702 [002] d..1 175.347236: wait_r: (SyS_wait4+0x74/0xe4 <- do_wait) arg1=0x757
|
||||
bash-1702 [002] d… 175.347337: wait_p: (do_wait+0x0/0x260) wo_type=0x3 wo_flags=0xf
|
||||
bash-1702 [002] d..1 175.347349: wait_r: (SyS_wait4+0x74/0xe4 <- do_wait) arg1=0xfffffffffffffff6
|
||||
```
|
||||
|
||||
#### 例子: 探测任意指令地址
|
||||
|
||||
在前面的例子中,我们已经为函数的入口和出口插入探针,然而探测一个任意指令(除少数例外)是可能的。如果我们正在 C 函数中放置一个探针,第一步是查看代码的汇编版本以确定我们要放置探针的位置。一种方法是在 vmlinux 文件上使用 gdb,并在要放置探针的函数中展示指令。下面是一个在 `arch/arm64/kernel/modules.c` 中 `module_alloc` 函数执行此操作的示例。在这种情况下,因为 gdb 似乎更喜欢使用弱符号定义,并且它是与这个函数关联的存根代码,所以我们从 System.map 中来获取符号值:
|
||||
|
||||
```
|
||||
$ grep module_alloc System.map
|
||||
ffff2000080951c4 T module_alloc
|
||||
ffff200008297770 T kasan_module_alloc
|
||||
```
|
||||
|
||||
在这个例子中我们使用了交叉开发工具,并且在我们的主机系统上调用 gdb 来检查指令包含我们感兴趣函数。
|
||||
|
||||
```
|
||||
$ ${CROSS_COMPILE}gdb vmlinux
|
||||
(gdb) x/30i 0xffff2000080951c4
|
||||
0xffff2000080951c4 <module_alloc>: sub sp, sp, #0x30
|
||||
0xffff2000080951c8 <module_alloc+4>: adrp x3, 0xffff200008d70000
|
||||
0xffff2000080951cc <module_alloc+8>: add x3, x3, #0x0
|
||||
0xffff2000080951d0 <module_alloc+12>: mov x5, #0x713 // #1811
|
||||
0xffff2000080951d4 <module_alloc+16>: mov w4, #0xc0 // #192
|
||||
0xffff2000080951d8 <module_alloc+20>:
|
||||
mov x2, #0xfffffffff8000000 // #-134217728
|
||||
0xffff2000080951dc <module_alloc+24>: stp x29, x30, [sp,#16] 0xffff2000080951e0 <module_alloc+28>: add x29, sp, #0x10
|
||||
0xffff2000080951e4 <module_alloc+32>: movk x5, #0xc8, lsl #48
|
||||
0xffff2000080951e8 <module_alloc+36>: movk w4, #0x240, lsl #16
|
||||
0xffff2000080951ec <module_alloc+40>: str x30, [sp] 0xffff2000080951f0 <module_alloc+44>: mov w7, #0xffffffff // #-1
|
||||
0xffff2000080951f4 <module_alloc+48>: mov x6, #0x0 // #0
|
||||
0xffff2000080951f8 <module_alloc+52>: add x2, x3, x2
|
||||
0xffff2000080951fc <module_alloc+56>: mov x1, #0x8000 // #32768
|
||||
0xffff200008095200 <module_alloc+60>: stp x19, x20, [sp,#32] 0xffff200008095204 <module_alloc+64>: mov x20, x0
|
||||
0xffff200008095208 <module_alloc+68>: bl 0xffff2000082737a8 <__vmalloc_node_range>
|
||||
0xffff20000809520c <module_alloc+72>: mov x19, x0
|
||||
0xffff200008095210 <module_alloc+76>: cbz x0, 0xffff200008095234 <module_alloc+112>
|
||||
0xffff200008095214 <module_alloc+80>: mov x1, x20
|
||||
0xffff200008095218 <module_alloc+84>: bl 0xffff200008297770 <kasan_module_alloc>
|
||||
0xffff20000809521c <module_alloc+88>: tbnz w0, #31, 0xffff20000809524c <module_alloc+136>
|
||||
0xffff200008095220 <module_alloc+92>: mov sp, x29
|
||||
0xffff200008095224 <module_alloc+96>: mov x0, x19
|
||||
0xffff200008095228 <module_alloc+100>: ldp x19, x20, [sp,#16] 0xffff20000809522c <module_alloc+104>: ldp x29, x30, [sp],#32
|
||||
0xffff200008095230 <module_alloc+108>: ret
|
||||
0xffff200008095234 <module_alloc+112>: mov sp, x29
|
||||
0xffff200008095238 <module_alloc+116>: mov x19, #0x0 // #0
|
||||
```
|
||||
|
||||
在这种情况下,我们将在此函数中显示以下源代码行的结果:
|
||||
|
||||
```
|
||||
p = __vmalloc_node_range(size, MODULE_ALIGN, VMALLOC_START,
|
||||
VMALLOC_END, GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
|
||||
NUMA_NO_NODE, __builtin_return_address(0));
|
||||
```
|
||||
|
||||
……以及在此代码行的函数调用的返回值:
|
||||
|
||||
```
|
||||
if (p && (kasan_module_alloc(p, size) < 0)) {
|
||||
```
|
||||
|
||||
我们可以在从调用外部函数的汇编代码中识别这些。为了展示这些值,我们将在目标系统上的 `0xffff20000809520c` 和 `0xffff20000809521c` 处放置探针。
|
||||
|
||||
```
|
||||
$ cat > kprobe_events <<EOF
|
||||
p 0xffff20000809520c %x0
|
||||
p 0xffff20000809521c %x0
|
||||
EOF
|
||||
$ echo 1 > events/kprobes/enable
|
||||
```
|
||||
|
||||
现在将一个以太网适配器加密狗插入到 USB 端口后,我们看到以下写入追踪日志的内容:
|
||||
|
||||
```
|
||||
$ cat trace
|
||||
# tracer: nop
|
||||
#
|
||||
# entries-in-buffer/entries-written: 12/12 #P:8
|
||||
#
|
||||
# _—–=> irqs-off
|
||||
# / _—-=> need-resched
|
||||
# | / _—=> hardirq/softirq
|
||||
# || / _–=> preempt-depth
|
||||
# ||| / delay
|
||||
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
|
||||
# | | | |||| | |
|
||||
systemd-udevd-2082 [000] d… 77.200991: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff200001188000
|
||||
systemd-udevd-2082 [000] d… 77.201059: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
|
||||
systemd-udevd-2082 [000] d… 77.201115: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff200001198000
|
||||
systemd-udevd-2082 [000] d… 77.201157: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
|
||||
systemd-udevd-2082 [000] d… 77.227456: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff2000011a0000
|
||||
systemd-udevd-2082 [000] d… 77.227522: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
|
||||
systemd-udevd-2082 [000] d… 77.227579: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff2000011b0000
|
||||
systemd-udevd-2082 [000] d… 77.227635: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
|
||||
modprobe-2097 [002] d… 78.030643: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff2000011b8000
|
||||
modprobe-2097 [002] d… 78.030761: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
|
||||
modprobe-2097 [002] d… 78.031132: p_0xffff20000809520c: (module_alloc+0x48/0x98) arg1=0xffff200001270000
|
||||
modprobe-2097 [002] d… 78.031187: p_0xffff20000809521c: (module_alloc+0x58/0x98) arg1=0x0
|
||||
```
|
||||
|
||||
kprobes 事件系统的另一个功能是记录统计信息,这可在 `inkprobe_profile` 中找到。在以上追踪后,该文件的内容为:
|
||||
|
||||
```
|
||||
$ cat kprobe_profile
|
||||
p_0xffff20000809520c 6 0
|
||||
p_0xffff20000809521c 6 0
|
||||
```
|
||||
|
||||
这表明我们设置的两处断点每个共发生了 8 次命中,这当然与追踪日志数据是一致的。在 kprobetrace 文档中有更多 kprobe_profile 的功能描述。
|
||||
|
||||
也可以进一步过滤 kprobes 事件。用来控制这点的 debugfs 文件在 kprobetrace 文档中被列出,然而它们内容的详细信息大多在 trace events 文档中被描述。
|
||||
|
||||
### 总结
|
||||
|
||||
现在,Linux ARMv8 对支持 kprobes 功能也和其它架构相当。有人正在做添加 uprobes 和 systemtap 支持的工作。这些功能/工具和其他已经完成的功能(如: perf、 coresight)允许 Linux ARMv8 用户像在其它更老的架构上一样调试和测试性能。
|
||||
|
||||
* * *
|
||||
|
||||
参考文献
|
||||
|
||||
- 注1: Jim Keniston, Prasanna S. Panchamukhi, Masami Hiramatsu. “Kernel Probes (kprobes).” _GitHub_. GitHub, Inc., 15 Aug. 2016\. Web. 13 Dec. 2016.
|
||||
- 注2: Ts’o, Theodore, Li Zefan, and Tom Zanussi. “Event Tracing.” _GitHub_. GitHub, Inc., 3 Mar. 2016\. Web. 13 Dec. 2016.
|
||||
- 注3: Hiramatsu, Masami. “Kprobe-based Event Tracing.” _GitHub_. GitHub, Inc., 18 Aug. 2016\. Web. 13 Dec. 2016.
|
||||
|
||||
|
||||
----------------
|
||||
|
||||
作者简介 : [David Long][8] 在 Linaro Kernel - Core Development 团队中担任工程师。 在加入 Linaro 之前,他在商业和国防行业工作了数年,既做嵌入式实时工作又为Unix提供软件开发工具。之后,在 Digital(又名 Compaq)公司工作了十几年,负责 Unix 标准,C 编译器和运行时库的工作。之后 David 又去了一系列初创公司做嵌入式 Linux 和安卓系统,嵌入式定制操作系统和 Xen 虚拟化。他拥有 MIPS,Alpha 和 ARM 平台的经验(等等)。他使用过从 1979 年贝尔实验室 V6 开始的大部分Unix操作系统,并且长期以来一直是 Linux 用户和倡导者。他偶尔也因使用烙铁和数字示波器调试设备驱动而知名。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://www.linaro.org/blog/kprobes-event-tracing-armv8/
|
||||
|
||||
作者:[David Long][a]
|
||||
译者:[kimii](https://github.com/kimii)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://www.linaro.org/author/david-long/
|
||||
[1]:http://www.linaro.org/blog/kprobes-event-tracing-armv8/#
|
||||
[2]:https://github.com/torvalds/linux/blob/master/Documentation/kprobes.txt
|
||||
[3]:https://github.com/torvalds/linux/blob/master/Documentation/trace/events.txt
|
||||
[4]:https://github.com/torvalds/linux/blob/master/Documentation/trace/kprobetrace.txt
|
||||
[5]:https://github.com/torvalds/linux/blob/master/Documentation/kprobes.txt
|
||||
[6]:https://github.com/torvalds/linux/blob/master/Documentation/trace/events.txt
|
||||
[7]:https://github.com/torvalds/linux/blob/master/Documentation/trace/kprobetrace.txt
|
||||
[8]:http://www.linaro.org/author/david-long/
|
||||
[9]:http://www.linaro.org/blog/kprobes-event-tracing-armv8/#comments
|
||||
[10]:http://www.linaro.org/blog/kprobes-event-tracing-armv8/#
|
||||
[11]:http://www.linaro.org/tag/arm64/
|
||||
[12]:http://www.linaro.org/tag/armv8/
|
||||
[13]:http://www.linaro.org/tag/jprobes/
|
||||
[14]:http://www.linaro.org/tag/kernel/
|
||||
[15]:http://www.linaro.org/tag/kprobes/
|
||||
[16]:http://www.linaro.org/tag/kretprobes/
|
||||
[17]:http://www.linaro.org/tag/perf/
|
||||
[18]:http://www.linaro.org/tag/tracing/
|
||||
|
@ -0,0 +1,340 @@
|
||||
如何在 Linux 系统里用 Scrot 截屏
|
||||
============================================================
|
||||
|
||||
最近,我们介绍过 [gnome-screenshot][17] 工具,这是一个很优秀的屏幕抓取工具。但如果你想找一个在命令行运行的更好用的截屏工具,你一定要试试 Scrot。这个工具有一些 gnome-screenshot 没有的独特功能。在这篇文章里,我们会通过简单易懂的例子来详细介绍 Scrot。
|
||||
|
||||
请注意一下,这篇文章里的所有例子都在 Ubuntu 16.04 LTS 上测试过,我们用的 scrot 版本是 0.8。
|
||||
|
||||
### 关于 Scrot
|
||||
|
||||
[Scrot][18] (**SCR**eensh**OT**) 是一个屏幕抓取工具,使用 imlib2 库来获取和保存图片。由 Tom Gilbert 用 C 语言开发完成,通过 BSD 协议授权。
|
||||
|
||||
### 安装 Scrot
|
||||
|
||||
scort 工具可能在你的 Ubuntu 系统里预装了,不过如果没有的话,你可以用下面的命令安装:
|
||||
|
||||
```
|
||||
sudo apt-get install scrot
|
||||
```
|
||||
|
||||
安装完成后,你可以通过下面的命令来使用:
|
||||
|
||||
```
|
||||
scrot [options] [filename]
|
||||
```
|
||||
|
||||
**注意**:方括号里的参数是可选的。
|
||||
|
||||
### Scrot 的使用和特点
|
||||
|
||||
在这个小节里,我们会介绍如何使用 Scrot 工具,以及它的所有功能。
|
||||
|
||||
如果不带任何选项执行命令,它会抓取整个屏幕。
|
||||
|
||||
[
|
||||
![使用 Scrot](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/scrot.png)
|
||||
][19]
|
||||
|
||||
默认情况下,抓取的截图会用带时间戳的文件名保存到当前目录下,不过你也可以在运行命令时指定截图文件名。比如:
|
||||
|
||||
```
|
||||
scrot [image-name].png
|
||||
```
|
||||
|
||||
### 获取程序版本
|
||||
|
||||
你想的话,可以用 `-v` 选项来查看 scrot 的版本。
|
||||
|
||||
```
|
||||
scrot -v
|
||||
```
|
||||
|
||||
这是例子:
|
||||
|
||||
[
|
||||
![获取 scrot 版本](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/version.png)
|
||||
][20]
|
||||
|
||||
### 抓取当前窗口
|
||||
|
||||
这个工具可以限制抓取当前的焦点窗口。这个功能可以通过 `-u` 选项打开。
|
||||
|
||||
```
|
||||
scrot -u
|
||||
```
|
||||
例如,这是我在命令行执行上边命令时的桌面:
|
||||
|
||||
[
|
||||
![用 scrot 截取窗口](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/desktop.png)
|
||||
][21]
|
||||
|
||||
这是另一张用 scrot 抓取的截图:
|
||||
|
||||
[
|
||||
![用 scrot 抓取的图片](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/active.png)
|
||||
][22]
|
||||
|
||||
### 抓取选定窗口
|
||||
|
||||
这个工具还可以让你抓取任意用鼠标点击的窗口。这个功能可以用 `-s` 选项打开。
|
||||
|
||||
```
|
||||
scrot -s
|
||||
```
|
||||
|
||||
例如,在下面的截图里你可以看到,我有两个互相重叠的终端窗口。我在上层的窗口里执行上面的命令。
|
||||
|
||||
[
|
||||
![选择窗口](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/select1.png)
|
||||
][23]
|
||||
|
||||
现在假如我想抓取下层的终端窗口。这样我只要在执行命令后点击窗口就可以了 —— 在你用鼠标点击之前,命令的执行不会结束。
|
||||
|
||||
这是我点击了下层终端窗口后的截图:
|
||||
|
||||
[
|
||||
![窗口截图](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/select2.png)
|
||||
][24]
|
||||
|
||||
**注意**:你可以在上面的截图里看到,下层终端窗口的整个显示区域都被抓去下来了,甚至包括了上层窗口的部分叠加内容。
|
||||
|
||||
### 在截屏时包含窗口边框
|
||||
|
||||
我们之前介绍的 `-u` 选项在截屏时不会包含窗口边框。不过,需要的话你也可以在截屏时包含窗口边框。这个功能可以通过 `-b` 选项打开(当然要和 `-u` 选项一起)。
|
||||
|
||||
```
|
||||
scrot -ub
|
||||
```
|
||||
|
||||
下面是示例截图:
|
||||
|
||||
[
|
||||
![截屏时包含窗口边框](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/border-new.png)
|
||||
][25]
|
||||
|
||||
**注意**:截屏时包含窗口边框同时也会增加一点额外的背景。
|
||||
|
||||
### 延时截屏
|
||||
|
||||
你可以在开始截屏时增加一点延时。需要在 `--delay` 或 `-d` 选项后设定一个时间值参数。
|
||||
|
||||
```
|
||||
scrot --delay [NUM]
|
||||
|
||||
scrot --delay 5
|
||||
```
|
||||
|
||||
例如:
|
||||
|
||||
[
|
||||
![延时截屏](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/delay.png)
|
||||
][26]
|
||||
|
||||
在这例子里,scrot 会等待 5 秒再截屏。
|
||||
|
||||
### 截屏前倒数
|
||||
|
||||
这个工具也可以在你使用延时功能后显示一个倒计时。这个功能可以通过 `-c` 选项打开。
|
||||
|
||||
```
|
||||
scrot –delay [NUM] -c
|
||||
|
||||
scrot -d 5 -c
|
||||
```
|
||||
|
||||
下面是示例截图:
|
||||
|
||||
[
|
||||
![延时截屏示例](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/countdown.png)
|
||||
][27]
|
||||
|
||||
### 图片质量
|
||||
|
||||
你可以使用这个工具来调整截图的图片质量,范围是 1-100 之间。较大的值意味着更大的文件大小以及更低的压缩率。默认值是 75,不过最终效果根据选择的文件类型也会有一些差异。
|
||||
|
||||
这个功能可以通过 `--quality` 或 `-q` 选项打开,但是你必须提供一个 1 - 100 之间的数值作为参数。
|
||||
|
||||
```
|
||||
scrot –quality [NUM]
|
||||
|
||||
scrot –quality 10
|
||||
```
|
||||
|
||||
下面是示例截图:
|
||||
|
||||
[
|
||||
![截屏质量](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/img-quality.jpg)
|
||||
][28]
|
||||
|
||||
你可以看到,`-q` 选项的参数更靠近 1 让图片质量下降了很多。
|
||||
|
||||
### 生成缩略图
|
||||
|
||||
scort 工具还可以生成截屏的缩略图。这个功能可以通过 `--thumb` 选项打开。这个选项也需要一个 NUM 数值作为参数,基本上是指定原图大小的百分比。
|
||||
|
||||
```
|
||||
scrot --thumb NUM
|
||||
|
||||
scrot --thumb 50
|
||||
```
|
||||
|
||||
**注意**:加上 `--thumb` 选项也会同时保存原始截图文件。
|
||||
|
||||
例如,下面是我测试的原始截图:
|
||||
|
||||
[
|
||||
![原始截图](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/orig.png)
|
||||
][29]
|
||||
|
||||
下面是保存的缩略图:
|
||||
|
||||
[
|
||||
![截图缩略图](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/thmb.png)
|
||||
][30]
|
||||
|
||||
### 拼接多显示器截屏
|
||||
|
||||
如果你的电脑接了多个显示设备,你可以用 scort 抓取并拼接这些显示设备的截图。这个功能可以通过 `-m` 选项打开。
|
||||
|
||||
```
|
||||
scrot -m
|
||||
```
|
||||
|
||||
下面是示例截图:
|
||||
|
||||
[
|
||||
![拼接截屏](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/multiple.png)
|
||||
][31]
|
||||
|
||||
### 在保存截图后执行操作
|
||||
|
||||
使用这个工具,你可以在保存截图后执行各种操作 —— 例如,用像 gThumb 这样的图片编辑器打开截图。这个功能可以通过 `-e` 选项打开。下面是例子:
|
||||
|
||||
```
|
||||
scrot abc.png -e 'gthumb abc.png'
|
||||
```
|
||||
|
||||
这个命令里的 gthumb 是一个图片编辑器,上面的命令在执行后会自动打开。
|
||||
|
||||
下面是命令的截图:
|
||||
|
||||
[
|
||||
![截屏后执行命令](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/exec1.png)
|
||||
][32]
|
||||
|
||||
这个是上面命令执行后的效果:
|
||||
|
||||
[
|
||||
![示例截图](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/exec2.png)
|
||||
][33]
|
||||
|
||||
你可以看到 scrot 抓取了屏幕截图,然后再启动了 gThumb 图片编辑器打开刚才保存的截图图片。
|
||||
|
||||
如果你截图时没有指定文件名,截图将会用带有时间戳的文件名保存到当前目录 —— 这是 scrot 的默认设定,我们前面已经说过。
|
||||
|
||||
下面是一个使用默认名字并且加上 `-e` 选项来截图的例子:
|
||||
|
||||
```
|
||||
scrot -e 'gthumb $n'
|
||||
```
|
||||
|
||||
[
|
||||
![scrot 截屏后运行 gthumb](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/exec3.png)
|
||||
][34]
|
||||
|
||||
有个地方要注意的是 `$n` 是一个特殊字符串,用来获取当前截图的文件名。关于特殊字符串的更多细节,请继续看下个小节。
|
||||
|
||||
### 特殊字符串
|
||||
|
||||
scrot 的 `-e`(或 `--exec`)选项和文件名参数可以使用格式说明符。有两种类型格式。第一种是以 `%` 加字母组成,用来表示日期和时间,第二种以 `$` 开头,scrot 内部使用。
|
||||
|
||||
下面介绍几个 `--exec` 和文件名参数接受的说明符。
|
||||
|
||||
`$f` – 让你可以使用截图的全路径(包括文件名)。
|
||||
|
||||
例如:
|
||||
|
||||
```
|
||||
scrot ashu.jpg -e ‘mv $f ~/Pictures/Scrot/ashish/’
|
||||
```
|
||||
|
||||
下面是示例截图:
|
||||
|
||||
[
|
||||
![示例](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/f.png)
|
||||
][35]
|
||||
|
||||
如果你没有指定文件名,scrot 默认会用日期格式的文件名保存截图。这个是 scrot 的默认文件名格式:`%yy-%mm-%dd-%hhmmss_$wx$h_scrot.png`。
|
||||
|
||||
`$n` – 提供截图文件名。下面是示例截图:
|
||||
|
||||
[
|
||||
![scrot $n variable](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/n.png)
|
||||
][36]
|
||||
|
||||
`$s` – 获取截图的文件大小。这个功能可以像下面这样使用。
|
||||
|
||||
```
|
||||
scrot abc.jpg -e ‘echo $s’
|
||||
```
|
||||
|
||||
下面是示例截图:
|
||||
|
||||
[
|
||||
![scrot $s 变量](https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/s.png)
|
||||
][37]
|
||||
|
||||
类似的,你也可以使用其他格式字符串 `$p`、`$w`、 `$h`、`$t`、`$$` 以及 `\n` 来分别获取图片像素大小、图像宽度、图像高度、图像格式、输入 `$` 字符、以及换行。你可以像上面介绍的 `$s` 格式那样使用这些字符串。
|
||||
|
||||
### 结论
|
||||
|
||||
这个应用能轻松地安装在 Ubuntu 系统上,对初学者比较友好。scrot 也提供了一些高级功能,比如支持格式化字符串,方便专业用户用脚本处理。当然,如果你想用起来的话有一点轻微的学习曲线。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/
|
||||
|
||||
作者:[Himanshu Arora][a]
|
||||
译者:[zpl1025](https://github.com/zpl1025)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/
|
||||
[1]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#get-the-applicationnbspversion
|
||||
[2]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#capturing-current-window
|
||||
[3]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#selecting-a-window
|
||||
[4]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#includenbspwindow-border-in-screenshots
|
||||
[5]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#delay-in-taking-screenshots
|
||||
[6]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#countdown-before-screenshot
|
||||
[7]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#image-quality
|
||||
[8]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#generating-thumbnails
|
||||
[9]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#join-multiple-displays-shots
|
||||
[10]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#executing-operations-on-saved-images
|
||||
[11]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#special-strings
|
||||
[12]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#about-scrot
|
||||
[13]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#scrot-installation
|
||||
[14]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#scrot-usagefeatures
|
||||
[15]:https://www.howtoforge.com/tutorial/how-to-take-screenshots-in-linux-with-scrot/#conclusion
|
||||
[16]:https://www.howtoforge.com/subscription/
|
||||
[17]:https://www.howtoforge.com/tutorial/taking-screenshots-in-linux-using-gnome-screenshot/
|
||||
[18]:https://en.wikipedia.org/wiki/Scrot
|
||||
[19]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/scrot.png
|
||||
[20]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/version.png
|
||||
[21]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/desktop.png
|
||||
[22]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/active.png
|
||||
[23]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/select1.png
|
||||
[24]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/select2.png
|
||||
[25]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/border-new.png
|
||||
[26]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/delay.png
|
||||
[27]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/countdown.png
|
||||
[28]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/img-quality.jpg
|
||||
[29]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/orig.png
|
||||
[30]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/thmb.png
|
||||
[31]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/multiple.png
|
||||
[32]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/exec1.png
|
||||
[33]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/exec2.png
|
||||
[34]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/exec3.png
|
||||
[35]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/f.png
|
||||
[36]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/n.png
|
||||
[37]:https://www.howtoforge.com/images/how-to-take-screenshots-in-linux-with-scrot/big/s.png
|
@ -0,0 +1,92 @@
|
||||
如何在 Linux 启动时自动启动 LXD 容器
|
||||
======
|
||||
|
||||
Q:我正在使用基于 LXD(“Linux 容器”)的虚拟机。如何在 Linux 系统中启动时自动启动 LXD 容器?
|
||||
|
||||
当 LXD 在启动时运行,你就可以随时启动容器。你需要将 `boot.autostart` 设置为 `true`。你可以使用 `boot.autostart.priority`(默认值为 `0`)选项来定义启动容器的顺序(从最高开始)。你也可以使用 `boot.autostart.delay`(默认值 `0`)选项定义在启动一个容器后等待几秒后启动另一个容器。
|
||||
|
||||
### 语法
|
||||
|
||||
上面讨论的关键字可以使用 `lxc` 工具用下面的语法来设置:
|
||||
|
||||
```
|
||||
$ lxc config set {vm-name} {key} {value}
|
||||
$ lxc config set {vm-name} boot.autostart {true|false}
|
||||
$ lxc config set {vm-name} boot.autostart.priority integer
|
||||
$ lxc config set {vm-name} boot.autostart.delay integer
|
||||
```
|
||||
|
||||
### 如何在 Ubuntu Linux 16.10 中让 LXD 容器在启动时启动?
|
||||
|
||||
输入以下命令:
|
||||
|
||||
```
|
||||
$ lxc config set {vm-name} boot.autostart true
|
||||
```
|
||||
|
||||
设置一个 LXD 容器名称 “nginx-vm” 以在启动时启动
|
||||
|
||||
```
|
||||
$ lxc config set nginx-vm boot.autostart true
|
||||
```
|
||||
|
||||
你可以使用以下语法验证设置:
|
||||
|
||||
```
|
||||
$ lxc config get {vm-name} boot.autostart
|
||||
$ lxc config get nginx-vm boot.autostart
|
||||
```
|
||||
|
||||
示例输出:
|
||||
|
||||
```
|
||||
true
|
||||
```
|
||||
|
||||
你可以使用下面的语法在启动容器后等待 10 秒钟后启动另一个容器:
|
||||
|
||||
```
|
||||
$ lxc config set nginx-vm boot.autostart.delay 10
|
||||
```
|
||||
|
||||
最后,通过设置最高值来定义启动容器的顺序。确保 db_vm 容器首先启动,然后再启动 nginx_vm。
|
||||
|
||||
```
|
||||
$ lxc config set db_vm boot.autostart.priority 100
|
||||
$ lxc config set nginx_vm boot.autostart.priority 99
|
||||
```
|
||||
|
||||
使用[下面的 bash 循环在 Linux 上查看所有][1]配置值:
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
echo 'The current values of each vm boot parameters:'
|
||||
for c in db_vm nginx_vm memcache_vm
|
||||
do
|
||||
echo "*** VM: $c ***"
|
||||
for v in boot.autostart boot.autostart.priority boot.autostart.delay
|
||||
do
|
||||
echo "Key: $v => $(lxc config get $c $v) "
|
||||
done
|
||||
echo ""
|
||||
done
|
||||
```
|
||||
|
||||
示例输出:
|
||||
|
||||
![Fig.01: Get autostarting LXD containers values using a bash shell script][2]
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.cyberciti.biz/faq/how-to-auto-start-lxd-containers-at-boot-time-in-linux/
|
||||
|
||||
作者:[Vivek Gite][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.cyberciti.biz
|
||||
[1]:https://www.cyberciti.biz/faq/bash-for-loop/
|
||||
[2]:https://www.cyberciti.biz/media/new/faq/2017/02/Autostarting-LXD-containers-values.jpg
|
@ -0,0 +1,127 @@
|
||||
使用 molly-guard 保护你的 Linux/Unix 机器不会被错误地关机/重启
|
||||
======
|
||||
|
||||
我去!又是这样。 我还以为我登录到家里的服务器呢。 结果 [重启的居然是数据库服务器][1]。 另外我也有时会在错误终端内输入 "[shutdown -h 0][2]" 命令。 我知道有些人 [经常会犯这个错误 ][3]。
|
||||
|
||||
![我的愤怒无从容忍][4]
|
||||
|
||||
有办法解决这个问题吗?我真的只能忍受这种随机重启和关机的痛苦吗? 虽说人总是要犯错的,但总不能一错再错吧。
|
||||
|
||||
最新我在 tweet 上发了一通牢骚:
|
||||
|
||||
> 我总是一遍又一遍地犯下同样的错误 :( 本来应该输入:
|
||||
> `sudo virsh reboot d1`
|
||||
>
|
||||
> 却总是输错重启了自己的电脑
|
||||
> `sudo reboot d1`
|
||||
>
|
||||
> -- nixCraft (@nixcraft) [February 19,2017][5]
|
||||
|
||||
结果收到了一些建议。我们来试一下。
|
||||
|
||||
### 向你引荐 molly guard
|
||||
|
||||
Molly-Guard **尝试阻止你不小心关闭或重启 Linux 服务器**。它在 Debian/Ubuntu 中的包描述为:
|
||||
|
||||
> 这个包会安装一个 shell 脚本来屏蔽现有的 `shutdown`/`reboot`/`halt`/`poweroff`/`coldreboot`/`pm-hibernate`/`pm-suspend*` 命令。 `molly-gurad` 会首先运行一系列的脚本,只有在所有的脚本都返回成功的条件下, 才会调用真正的命令。 其中一个脚本会检查是否存在 SSH 会话。 如果是通过 SSH 会话调用的命令, shell 脚本会提示你输入相关闭主机的名称。 这应该足够防止你发生意外的关机或重启了。
|
||||
|
||||
貌似 [molly-guard][6] 还是个<ruby>专有名词<rt>Jargon File</rt></ruby>:
|
||||
|
||||
> 一种用于防止由于笨拙或者不小心触碰道大红开关的屏障。最初指的临时盖在 IBM 4341 的大红按钮上的有机玻璃,因为有一个程序员蹒跚学步的女儿(名叫 Molly)一天之内重启了它两次。 后来这个东西也被用来盖住磁盘和网络设备上的停止/重启按钮。在硬件目录中,你很少会看到 “guarded button” 这样无趣的描述"。
|
||||
|
||||
### 如何安装 molly guard
|
||||
|
||||
使用 [`apt-get` 命令][7] 或者 [`apt` 命令][8] 来搜索并安装 molly-guard:
|
||||
|
||||
```
|
||||
$ apt search molly-guard
|
||||
$ sudo apt-get install molly-guard
|
||||
```
|
||||
|
||||
结果为:
|
||||
|
||||
[![Fig.01: Installing molly guard on Linux][9]][10]
|
||||
|
||||
### 测试一下
|
||||
|
||||
输入 [`reboot` 命令 ][11] 和 `shutdown` 命令:
|
||||
|
||||
```
|
||||
$ sudo reboot
|
||||
# reboot
|
||||
$ shutdown -h 0
|
||||
# sudo shutdown -h 0
|
||||
### running wrong command such as follows instead of
|
||||
### sudo virsh reboot vm_name_here
|
||||
$ sudo reboot vm_name_here
|
||||
```
|
||||
|
||||
结果为:
|
||||
|
||||
![Fig.02: Molly guard saved my butt ;\)][12]
|
||||
|
||||
我超级喜欢 molly-guard。因此我将下行内容加入到 `apt-debian-ubuntu-common.yml` 文件中了:
|
||||
|
||||
```
|
||||
- apt:
|
||||
name: molly-guard
|
||||
|
||||
```
|
||||
|
||||
是的。我使用 Ansible 在所有的 Debian 和 Ubuntu 服务器上都自动安装上它了。
|
||||
|
||||
**相关** : [我的 10 大 UNIX 命令行错误][13]
|
||||
|
||||
### 如果我的 Linux 发行版或者 Unix 系统(比如 FreeBSD) 没有 molly-guard 怎么办呢?
|
||||
|
||||
不用怕,[设置 shell 别名 ][14]:
|
||||
```
|
||||
## bash shell example ###
|
||||
alias reboot = "echo 'Are you sure?' If so, run /sbin/reboot"
|
||||
alias shutdown = "echo 'Are you sure?' If so, run /sbin/shutdown"
|
||||
```
|
||||
|
||||
你也可以 [临时取消别名机制运行真正的命令][15]。比如要运行 reboot 可以这样:
|
||||
|
||||
```
|
||||
# \reboot
|
||||
```
|
||||
|
||||
或者
|
||||
|
||||
```
|
||||
# /sbin/reboot
|
||||
```
|
||||
|
||||
另外你也可以写一个 [shell/perl/python 脚本来调用这些命令并要求][16] 确认 `reboot`/`halt`/`shutdown` 的选项。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.cyberciti.biz/hardware/how-to-protects-linux-and-unix-machines-from-accidental-shutdownsreboots-with-molly-guard/
|
||||
|
||||
作者:[Vivek Gite][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.cyberciti.biz
|
||||
[1]:https://www.cyberciti.biz/faq/howto-reboot-linux/
|
||||
[2]:https://www.cyberciti.biz/faq/shutdown-linux-server/
|
||||
[3]:https://www.cyberciti.biz/tips/my-10-unix-command-line-mistakes.html (My 10 UNIX Command Line Mistakes)
|
||||
[4]:https://www.cyberciti.biz/media/new/cms/2017/02/anger.gif
|
||||
[5]:https://twitter.com/nixcraft/status/833320792880320513
|
||||
[6]:http://catb.org/~esr/jargon/html/M/molly-guard.html
|
||||
[7]://www.cyberciti.biz/tips/linux-debian-package-management-cheat-sheet.html (See Linux/Unix apt-get command examples for more info)
|
||||
[8]://www.cyberciti.biz/faq/ubuntu-lts-debian-linux-apt-command-examples/ (See Linux/Unix apt command examples for more info)
|
||||
[9]:https://www.cyberciti.biz/media/new/cms/2017/02/install-molly-guard-on-linux.jpg
|
||||
[10]:https://www.cyberciti.biz/hardware/how-to-protects-linux-and-unix-machines-from-accidental-shutdownsreboots-with-molly-guard/attachment/install-molly-guard-on-linux/
|
||||
[11]:https://www.cyberciti.biz/faq/linux-reboot-command/ (See Linux/Unix reboot command examples for more info)
|
||||
[12]:https://www.cyberciti.biz/media/new/cms/2017/02/saved-my-butt.jpg
|
||||
[13]:https://www.cyberciti.biz/tips/my-10-unix-command-line-mistakes.html
|
||||
[14]:https://www.cyberciti.biz/tips/bash-aliases-mac-centos-linux-unix.html
|
||||
[15]:https://www.cyberciti.biz/faq/bash-shell-temporarily-disable-an-alias/
|
||||
[16]:https://github.com/kjetilho/clumsy_protect
|
||||
[17]:https://twitter.com/nixcraft
|
||||
[18]:https://facebook.com/nixcraft
|
||||
[19]:https://plus.google.com/+CybercitiBiz
|
130
published/201712/20170413 More Unknown Linux Commands.md
Normal file
130
published/201712/20170413 More Unknown Linux Commands.md
Normal file
@ -0,0 +1,130 @@
|
||||
更多你所不知道的 Linux 命令
|
||||
============================================================
|
||||
|
||||
![unknown Linux commands](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/outer-limits-of-linux.jpg?itok=5L5xfj2v "unknown Linux commands")
|
||||
|
||||
> 在这篇文章中和 Carla Schroder 一起探索 Linux 中的一些鲜为人知的强大工具。
|
||||
|
||||
本文是一篇关于一些有趣但鲜为人知的工具 `termsaver`、`pv` 和 `calendar` 的文章。`termsaver` 是一个终端 ASCII 屏保,`pv` 能够测量数据吞吐量并模拟输入。Debian 的 `calendar` 拥有许多不同的日历,并且你还可以制定你自己的日历。
|
||||
|
||||
### 终端屏保
|
||||
|
||||
难道只有图形桌面能够拥有有趣的屏保吗?现在,你可以通过安装 `termsaver` 来享受 ASCII 屏保,比如 matrix(LCTT 译注:电影《黑客帝国》中出现的黑客屏保)、时钟、星球大战以及两个<ruby>不太安全<rt>not-safe-for-work</rt></ruby>(NSFW)的屏保。 NSFW 屏保还有很多。
|
||||
|
||||
`termsaver` 可以从 Debian/Ubuntu 的包管理器中直接下载安装,如果你使用别的不包含该软件包的发行版比如 CentOS,那么你可以从 [termsaver.brunobraga.net][7] 下载,然后按照安装指导进行安装。
|
||||
|
||||
运行 `termsaver -h` 来查看一系列屏保:
|
||||
|
||||
```
|
||||
randtxt displays word in random places on screen
|
||||
starwars runs the asciimation Star Wars movie
|
||||
urlfetcher displays url contents with typing animation
|
||||
quotes4all displays recent quotes from quotes4all.net
|
||||
rssfeed displays rss feed information
|
||||
matrix displays a matrix movie alike screensaver
|
||||
clock displays a digital clock on screen
|
||||
rfc randomly displays RFC contents
|
||||
jokes4all displays recent jokes from jokes4all.net (NSFW)
|
||||
asciiartfarts displays ascii images from asciiartfarts.com (NSFW)
|
||||
programmer displays source code in typing animation
|
||||
sysmon displays a graphical system monitor
|
||||
```
|
||||
|
||||
![Linux commands](https://www.linux.com/sites/lcom/files/styles/floated_images/public/linux-commands-fig-1.png?itok=HveXXLLK "Linux commands")
|
||||
|
||||
*图片 1: 星球大战屏保。*
|
||||
|
||||
你可以通过运行命令 `termsaver [屏保名]` 来使用屏保,比如 `termsaver matrix` ,然后按 `Ctrl+c` 停止。你也可以通过运行 `termsaver [屏保名] -h` 命令来获取关于某一个特定屏保的信息。图片 1 来自 `startwars` 屏保,它运行的是古老但受人喜爱的 [Asciimation Wars][8] 。
|
||||
|
||||
那些不太安全(NSFW)的屏保通过在线获取资源的方式运行,我并不喜欢它们,但好消息是,由于 `termsaver` 是一些 Python 脚本文件,因此,你可以很容易的利用它们连接到任何你想要的 RSS 资源。
|
||||
|
||||
### pv
|
||||
|
||||
`pv` 命令是一个非常有趣的小工具但却很实用。它的用途是监测数据复制的过程,比如,当你运行 `rsync` 命令或创建一个 `tar` 归档的时候。当你不带任何选项运行 `pv` 命令时,默认参数为:
|
||||
|
||||
* -p :进程
|
||||
* -t :时间,到当前总运行时间
|
||||
* -e :预计完成时间,这往往是不准确的,因为 `pv` 通常不知道需要移动的数据的大小
|
||||
* -r :速率计数器,或吞吐量
|
||||
* -b :字节计数器
|
||||
|
||||
一次 `rsync` 传输看起来像这样:
|
||||
|
||||
```
|
||||
$ rsync -av /home/carla/ /media/carla/backup/ | pv
|
||||
sending incremental file list
|
||||
[...]
|
||||
103GiB 0:02:48 [ 615MiB/s] [ <=>
|
||||
```
|
||||
|
||||
创建一个 tar 归档,就像下面这个例子:
|
||||
|
||||
```
|
||||
$ tar -czf - /file/path| (pv > backup.tgz)
|
||||
885MiB 0:00:30 [28.6MiB/s] [ <=>
|
||||
```
|
||||
|
||||
`pv` 能够监测进程,因此也可以监测 Web 浏览器的最大活动,令人惊讶的是,它产生了如此多的活动:
|
||||
|
||||
```
|
||||
$ pv -d 3095
|
||||
58:/home/carla/.pki/nssdb/key4.db: 0 B 0:00:33
|
||||
[ 0 B/s] [<=> ]
|
||||
78:/home/carla/.config/chromium/Default/Visited Links:
|
||||
256KiB 0:00:33 [ 0 B/s] [<=> ]
|
||||
]
|
||||
85:/home/carla/.con...romium/Default/data_reduction_proxy_leveldb/LOG:
|
||||
298 B 0:00:33 [ 0 B/s] [<=> ]
|
||||
```
|
||||
|
||||
在网上,我偶然发现一个使用 `pv` 最有趣的方式:使用 `pv` 来回显输入的内容:
|
||||
|
||||
```
|
||||
$ echo "typing random stuff to pipe through pv" | pv -qL 8
|
||||
typing random stuff to pipe through pv
|
||||
```
|
||||
|
||||
普通的 `echo` 命令会瞬间打印一整行内容。通过管道传给 `pv` 之后能够让内容像是重新输入一样的显示出来。我不知道这是否有实际的价值,但是我非常喜欢它。`-L` 选项控制回显的速度,即多少字节每秒。
|
||||
|
||||
`pv` 是一个非常古老且非常有趣的命令,这么多年以来,它拥有了许多的选项,包括有趣的格式化选项,多种输出选项,以及传输速度修改器。你可以通过 `man pv` 来查看所有的选项。
|
||||
|
||||
### /usr/bin/calendar
|
||||
|
||||
通过浏览 `/usr/bin` 目录以及其他命令目录和阅读 man 手册,你能够学到很多东西。在 Debian/Ubuntu 上的 `/usr/bin/calendar` 是 BSD 日历的一个变种,但它漏掉了月亮历和太阳历。它保留了多个日历包括 `calendar.computer, calendar.discordian, calendar.music` 以及 `calendar.lotr`。在我的系统上,man 手册列出了 `/usr/bin/calendar` 里存在的不同日历。下面这个例子展示了指环王日历接下来的 60 天:
|
||||
|
||||
```
|
||||
$ calendar -f /usr/share/calendar/calendar.lotr -A 60
|
||||
Apr 17 An unexpected party
|
||||
Apr 23 Crowning of King Ellesar
|
||||
May 19 Arwen leaves Lorian to wed King Ellesar
|
||||
Jun 11 Sauron attacks Osgilliath
|
||||
```
|
||||
|
||||
这些日历是纯文本文件,因此,你可以轻松的创建你自己的日历。最简单的方式就是复制已经存在的日历文件的格式。你可以通过 `man calendar` 命令来查看创建个人日历文件的更详细的指导。
|
||||
|
||||
又一次很快走到了尽头。你可以花费一些时间来浏览你的文件系统,挖掘更多有趣的命令。
|
||||
|
||||
_你可以通过来自 Linux 基金会和 edx 的免费课程 ["Introduction to Linux"][5] 来学习更过关于 Linux 的知识_。
|
||||
|
||||
(题图:[CC Zero][2] Pixabay)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/learn/intro-to-linux/2017/4/more-unknown-linux-commands
|
||||
|
||||
作者:[CARLA SCHRODER][a]
|
||||
译者:[ucasFL](https://github.com/ucasFL)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/cschroder
|
||||
[1]:https://www.linux.com/licenses/category/used-permission
|
||||
[2]:https://www.linux.com/licenses/category/creative-commons-zero
|
||||
[3]:https://www.linux.com/files/images/linux-commands-fig-1png
|
||||
|
||||
[4]:https://www.linux.com/files/images/outer-limits-linuxjpg
|
||||
[5]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
||||
[6]:https://www.addtoany.com/share#url=https%3A%2F%2Fwww.linux.com%2Flearn%2Fintro-to-linux%2F2017%2F4%2Fmore-unknown-linux-commands&amp;amp;title=More%20Unknown%20Linux%20Commands
|
||||
[7]:http://termsaver.brunobraga.net/
|
||||
[8]:http://www.asciimation.co.nz/
|
105
published/201712/20170530 How to Improve a Legacy Codebase.md
Normal file
105
published/201712/20170530 How to Improve a Legacy Codebase.md
Normal file
@ -0,0 +1,105 @@
|
||||
如何改善遗留的代码库
|
||||
=================
|
||||
|
||||
在每一个程序员、项目管理员、团队领导的一生中,这都会至少发生一次。原来的程序员早已离职去度假了,给你留下了一坨几百万行屎一样的、勉强支撑公司运行的代码和(如果有的话)跟代码驴头不对马嘴的文档。
|
||||
|
||||
你的任务:带领团队摆脱这个混乱的局面。
|
||||
|
||||
当你的第一反应(逃命)过去之后,你开始去熟悉这个项目。公司的管理层都在关注着你,所以项目只能成功;然而,看了一遍代码之后却发现失败几乎是不可避免。那么该怎么办呢?
|
||||
|
||||
幸运(不幸)的是我已经遇到好几次这种情况了,我和我的小伙伴发现将这坨热气腾腾的屎变成一个健康可维护的项目是一个有丰厚利润的业务。下面这些是我们的一些经验:
|
||||
|
||||
### 备份
|
||||
|
||||
在开始做任何事情之前备份与之可能相关的所有文件。这样可以确保不会丢失任何可能会在另外一些地方很重要的信息。一旦修改了其中一些文件,你可能花费一天或者更多天都解决不了这个愚蠢的问题。配置数据通常不受版本控制,所以特别容易受到这方面影响,如果定期备份数据时连带着它一起备份了,还是比较幸运的。所以谨慎总比后悔好,复制所有东西到一个绝对安全的地方并不要轻易碰它,除非这些文件是只读模式。
|
||||
|
||||
### 重要的先决条件:必须确保代码能够在生产环境下构建运行并产出
|
||||
|
||||
之前我假设环境已经存在,所以完全丢了这一步,但 Hacker News 的众多网友指出了这一点,并且事实证明他们是对的:第一步是确认你知道在生产环境下运行着什么东西,也意味着你需要在你的设备上构建一个跟生产环境上运行的版本每一个字节都一模一样的版本。如果你找不到实现它的办法,一旦你将它投入生产环境,你很可能会遭遇一些预料之外的糟糕事情。确保每一部分都尽力测试,之后在你足够确信它能够很好的运行的时候将它部署生产环境下。无论它运行的怎么样都要做好能够马上切换回旧版本的准备,确保日志记录下了所有情况,以便于接下来不可避免的 “验尸” 。
|
||||
|
||||
### 冻结数据库
|
||||
|
||||
直到你修改代码结束之前尽可能冻结你的数据库,在你已经非常熟悉代码库和遗留代码之后再去修改数据库。在这之前过早的修改数据库的话,你可能会碰到大问题,你会失去让新旧代码和数据库一起构建稳固的基础的能力。保持数据库完全不变,就能比较新的逻辑代码和旧的逻辑代码运行的结果,比较的结果应该跟预期的没有差别。
|
||||
|
||||
### 写测试
|
||||
|
||||
在你做任何改变之前,尽可能多的写一些端到端测试和集成测试。确保这些测试能够正确的输出,并测试你对旧的代码运行的各种假设(准备好应对一些意外状况)。这些测试有两个重要的作用:其一,它们能够在早期帮助你抛弃一些错误观念,其二,这些测试在你写新代码替换旧代码的时候也有一定防护作用。
|
||||
|
||||
要自动化测试,如果你有 CI 的使用经验可以用它,并确保在你提交代码之后 CI 能够快速的完成所有测试。
|
||||
|
||||
### 日志监控
|
||||
|
||||
如果旧设备依然可用,那么添加上监控功能。在一个全新的数据库,为每一个你能想到的事件都添加一个简单的计数器,并且根据这些事件的名字添加一个函数增加这些计数器。用一些额外的代码实现一个带有时间戳的事件日志,你就能大概知道发生多少事件会导致另外一些种类的事件。例如:用户打开 APP 、用户关闭 APP 。如果这两个事件导致后端调用的数量维持长时间的不同,这个数量差就是当前打开的 APP 的数量。如果你发现打开 APP 比关闭 APP 多的时候,你就必须要知道是什么原因导致 APP 关闭了(例如崩溃)。你会发现每一个事件都跟其它的一些事件有许多不同种类的联系,通常情况下你应该尽量维持这些固定的联系,除非在系统上有一个明显的错误。你的目标是减少那些错误的事件,尽可能多的在开始的时候通过使用计数器在调用链中降低到指定的级别。(例如:用户支付应该得到相同数量的支付回调)。
|
||||
|
||||
这个简单的技巧可以将每一个后端应用变成一个像真实的簿记系统一样,而像一个真正的簿记系统,所有数字必须匹配,如果它们在某个地方对不上就有问题。
|
||||
|
||||
随着时间的推移,这个系统在监控健康方面变得非常宝贵,而且它也是使用源码控制修改系统日志的一个好伙伴,你可以使用它确认 BUG 引入到生产环境的时间,以及对多种计数器造成的影响。
|
||||
|
||||
我通常保持每 5 分钟(一小时 12 次)记录一次计数器,但如果你的应用生成了更多或者更少的事件,你应该修改这个时间间隔。所有的计数器公用一个数据表,每一个记录都只是简单的一行。
|
||||
|
||||
### 一次只修改一处
|
||||
|
||||
不要陷入在提高代码或者平台可用性的同时添加新特性或者是修复 BUG 的陷阱。这会让你头大,因为你现在必须在每一步操作想好要出什么样的结果,而且会让你之前建立的一些测试失效。
|
||||
|
||||
### 修改平台
|
||||
|
||||
如果你决定转移你的应用到另外一个平台,最主要的是跟之前保持一模一样。如果你觉得需要,你可以添加更多的文档和测试,但是不要忘记这一点,所有的业务逻辑和相互依赖要跟从前一样保持不变。
|
||||
|
||||
### 修改架构
|
||||
|
||||
接下来处理的是改变应用的结构(如果需要)。这一点上,你可以自由的修改高层的代码,通常是降低模块间的横向联系,这样可以降低代码活动期间对终端用户造成的影响范围。如果旧代码很庞杂,那么现在正是让它模块化的时候,将大段代码分解成众多小的部分,不过不要改变量和数据结构的名字。
|
||||
|
||||
Hacker News 的 [mannykannot][1] 网友指出,修改高层代码并不总是可行,如果你特别不幸的话,你可能为了改变一些架构必须付出沉重的代价。我赞同这一点也应该在这里加上提示,因此这里有一些补充。我想额外补充的是如果你修改高层代码的时候修改了一点点底层代码,那么试着只修改一个文件或者最坏的情况是只修改一个子系统,尽可能限制修改的范围。否则你可能很难调试刚才所做的更改。
|
||||
|
||||
### 底层代码的重构
|
||||
|
||||
现在,你应该非常理解每一个模块的作用了,准备做一些真正的工作吧:重构代码以提高其可维护性并且使代码做好添加新功能的准备。这很可能是项目中最消耗时间的部分,记录你所做的任何操作,在你彻底的记录并且理解模块之前不要对它做任何修改。之后你可以自由的修改变量名、函数名以及数据结构以提高代码的清晰度和统一性,然后请做测试(情况允许的话,包括单元测试)。
|
||||
|
||||
### 修复 bug
|
||||
|
||||
现在准备做一些用户可见的修改,战斗的第一步是修复很多积累了几年的 bug。像往常一样,首先证实 bug 仍然存在,然后编写测试并修复这个 bug,你的 CI 和端对端测试应该能避免一些由于不太熟悉或者一些额外的事情而犯的错误。
|
||||
|
||||
### 升级数据库
|
||||
|
||||
如果你在一个坚实且可维护的代码库上完成所有工作,你就可以选择更改数据库模式的计划,或者使用不同的完全替换数据库。之前完成的步骤能够帮助你更可靠的修改数据库而不会碰到问题,你可以完全的测试新数据库和新代码,而之前写的所有测试可以确保你顺利的迁移。
|
||||
|
||||
### 按着路线图执行
|
||||
|
||||
祝贺你脱离的困境并且可以准备添加新功能了。
|
||||
|
||||
### 任何时候都不要尝试彻底重写
|
||||
|
||||
彻底重写是那种注定会失败的项目。一方面,你在一个未知的领域开始,所以你甚至不知道构建什么,另一方面,你会把所有的问题都推到新系统马上就要上线的前一天。非常不幸的是,这也是你失败的时候。假设业务逻辑被发现存在问题,你会得到异样的眼光,那时您会突然明白为什么旧系统会用某种奇怪的方式来工作,最终也会意识到能将旧系统放在一起工作的人也不都是白痴。在那之后。如果你真的想破坏公司(和你自己的声誉),那就重写吧,但如果你是聪明人,你会知道彻底重写系统根本不是一个可选的选择。
|
||||
|
||||
### 所以,替代方法:增量迭代工作
|
||||
|
||||
要解开这些线团最快方法是,使用你熟悉的代码中任何的元素(它可能是外部的,也可能是内核模块),试着使用旧的上下文去增量改进。如果旧的构建工具已经不能用了,你将必须使用一些技巧(看下面),但至少当你开始做修改的时候,试着尽力保留已知的工作。那样随着代码库的提升你也对代码的作用更加理解。一个典型的代码提交应该最多两三行。
|
||||
|
||||
### 发布!
|
||||
|
||||
每一次的修改都发布到生产环境,即使一些修改不是用户可见的。使用最少的步骤也是很重要的,因为当你缺乏对系统的了解时,有时候只有生产环境能够告诉你问题在哪里。如果你只做了一个很小的修改之后出了问题,会有一些好处:
|
||||
|
||||
* 很容易弄清楚出了什么问题
|
||||
* 这是一个改进流程的好位置
|
||||
* 你应该马上更新文档展示你的新见解
|
||||
|
||||
### 使用代理的好处
|
||||
|
||||
如果你做 web 开发那就谢天谢地吧,可以在旧系统和用户之间加一个代理。这样你能很容易的控制每一个网址哪些请求定向到旧系统,哪些请求定向到新系统,从而更轻松更精确的控制运行的内容以及谁能够看到运行系统。如果你的代理足够的聪明,你可以使用它针对个别 URL 把一定比例的流量发送到新系统,直到你满意为止。如果你的集成测试也能连接到这个接口那就更好了。
|
||||
|
||||
### 是的,但这会花费很多时间!
|
||||
|
||||
这就取决于你怎样看待它了。的确,在按照以上步骤优化代码时会有一些重复的工作步骤。但是它确实有效,而这里介绍的任何一个步骤都是假设你对系统的了解比现实要多。我需要保持声誉,也真的不喜欢在工作期间有负面的意外。如果运气好的话,公司系统已经出现问题,或者有可能会严重影响到客户。在这样的情况下,我比较喜欢完全控制整个流程得到好的结果,而不是节省两天或者一星期。如果你更多地是牛仔的做事方式,并且你的老板同意可以接受冒更大的风险,那可能试着冒险一下没有错,但是大多数公司宁愿采取稍微慢一点但更确定的胜利之路。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jacquesmattheij.com/improving-a-legacy-codebase
|
||||
|
||||
作者:[Jacques Mattheij][a]
|
||||
译者:[aiwhj](https://github.com/aiwhj)
|
||||
校对:[JianqinWang](https://github.com/JianqinWang), [wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://jacquesmattheij.com/
|
||||
[1]:https://news.ycombinator.com/item?id=14445661
|
@ -0,0 +1,300 @@
|
||||
用户指南:Linux 文件系统的链接
|
||||
============================================================
|
||||
|
||||
> 学习如何使用链接,通过从 Linux 文件系统多个位置来访问文件,可以让日常工作变得轻松。
|
||||
|
||||
![linux 文件链接用户指南](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/links.png?itok=enaPOi4L "A user's guide to links in the Linux filesystem")
|
||||
|
||||
Image by : [Paul Lewin][8]. Modified by Opensource.com. [CC BY-SA 2.0][9]
|
||||
|
||||
在我为 opensource.com 写过的关于 Linux 文件系统方方面面的文章中,包括 [Linux 的 EXT4 文件系统的历史、特性以及最佳实践][10]; [在 Linux 中管理设备][11];[Linux 文件系统概览][12] 和 [用户指南:逻辑卷管理][13],我曾简要的提到过 Linux 文件系统一个有趣的特性,它允许用户从多个位置来访问 Linux 文件目录树中的文件来简化一些任务。
|
||||
|
||||
Linux 文件系统中有两种<ruby>链接<rt>link</rt></ruby>:<ruby>硬链接<rt>hard link</rt></ruby>和<ruby>软链接<rt>soft link</rt></ruby>。虽然二者差别显著,但都用来解决相似的问题。它们都提供了对单个文件的多个目录项(引用)的访问,但实现却大为不同。链接的强大功能赋予了 Linux 文件系统灵活性,因为[一切皆是文件][14]。
|
||||
|
||||
举个例子,我曾发现一些程序要求特定的版本库方可运行。 当用升级后的库替代旧库后,程序会崩溃,提示旧版本库缺失。通常,库名的唯一变化就是版本号。出于直觉,我仅仅给程序添加了一个新的库链接,并以旧库名称命名。我试着再次启动程序,运行良好。程序就是一个游戏,人人都明白,每个玩家都会尽力使游戏进行下去。
|
||||
|
||||
事实上,几乎所有的应用程序链接库都使用通用的命名规则,链接名称中包含了主版本号,链接所指向的文件的文件名中同样包含了小版本号。再比如,程序的一些必需文件为了迎合 Linux 文件系统规范,从一个目录移动到另一个目录中,系统为了向后兼容那些不能获取这些文件新位置的程序在旧的目录中存放了这些文件的链接。如果你对 `/lib64` 目录做一个长清单列表,你会发现很多这样的例子。
|
||||
|
||||
```
|
||||
lrwxrwxrwx. 1 root root 36 Dec 8 2016 cracklib_dict.hwm -> ../../usr/share/cracklib/pw_dict.hwm
|
||||
lrwxrwxrwx. 1 root root 36 Dec 8 2016 cracklib_dict.pwd -> ../../usr/share/cracklib/pw_dict.pwd
|
||||
lrwxrwxrwx. 1 root root 36 Dec 8 2016 cracklib_dict.pwi -> ../../usr/share/cracklib/pw_dict.pwi
|
||||
lrwxrwxrwx. 1 root root 27 Jun 9 2016 libaccountsservice.so.0 -> libaccountsservice.so.0.0.0
|
||||
-rwxr-xr-x. 1 root root 288456 Jun 9 2016 libaccountsservice.so.0.0.0
|
||||
lrwxrwxrwx 1 root root 15 May 17 11:47 libacl.so.1 -> libacl.so.1.1.0
|
||||
-rwxr-xr-x 1 root root 36472 May 17 11:47 libacl.so.1.1.0
|
||||
lrwxrwxrwx. 1 root root 15 Feb 4 2016 libaio.so.1 -> libaio.so.1.0.1
|
||||
-rwxr-xr-x. 1 root root 6224 Feb 4 2016 libaio.so.1.0.0
|
||||
-rwxr-xr-x. 1 root root 6224 Feb 4 2016 libaio.so.1.0.1
|
||||
lrwxrwxrwx. 1 root root 30 Jan 16 16:39 libakonadi-calendar.so.4 -> libakonadi-calendar.so.4.14.26
|
||||
-rwxr-xr-x. 1 root root 816160 Jan 16 16:39 libakonadi-calendar.so.4.14.26
|
||||
lrwxrwxrwx. 1 root root 29 Jan 16 16:39 libakonadi-contact.so.4 -> libakonadi-contact.so.4.14.26
|
||||
```
|
||||
|
||||
`/lib64` 目录下的一些链接
|
||||
|
||||
在上面展示的 `/lib64` 目录清单列表中,文件模式第一个字母 `l` (小写字母 l)表示这是一个软链接(又称符号链接)。
|
||||
|
||||
### 硬链接
|
||||
|
||||
在 [Linux 的 EXT4 文件系统的历史、特性以及最佳实践][15]一文中,我曾探讨过这样一个事实,每个文件都有一个包含该文件信息的 inode,包含了该文件的位置信息。上述文章中的[图2][16]展示了一个指向 inode 的单一目录项。每个文件都至少有一个目录项指向描述该文件信息的 inode ,目录项是一个硬链接,因此每个文件至少都有一个硬链接。
|
||||
|
||||
如下图 1 所示,多个目录项指向了同一 inode 。这些目录项都是硬链接。我曾在三个目录项中使用波浪线 (`~`) 的缩写,这是用户目录的惯例表示,因此在该例中波浪线等同于 `/home/user` 。值得注意的是,第四个目录项是一个完全不同的目录,`/home/shared`,可能是该计算机上用户的共享文件目录。
|
||||
|
||||
![fig1directory_entries.png](https://opensource.com/sites/default/files/images/life/fig1directory_entries.png)
|
||||
|
||||
*图 1*
|
||||
|
||||
硬链接被限制在一个单一的文件系统中。此处的“文件系统” 是指挂载在特定挂载点上的分区或逻辑卷,此例中是 `/home`。这是因为在每个文件系统中的 inode 号都是唯一的。而在不同的文件系统中,如 `/var` 或 `/opt`,会有和 `/home` 中相同的 inode 号。
|
||||
|
||||
因为所有的硬链接都指向了包含文件元信息的单一 inode ,这些属性都是文件的一部分,像所属关系、权限、到该 inode 的硬链接数目,对每个硬链接来说这些特性没有什么不同的。这是一个文件所具有的一组属性。唯一能区分这些文件的是包含在 inode 信息中的文件名。链接到同一目录中的单一文件/ inode 的硬链接必须拥有不同的文件名,这是基于同一目录下不能存在重复的文件名的事实的。
|
||||
|
||||
文件的硬链接数目可通过 `ls -l` 来查看,如果你想查看实际节点号,可使用 `ls -li` 命令。
|
||||
|
||||
### 符号(软)链接
|
||||
|
||||
硬链接和软链接(也称为<ruby>符号链接<rt>symlink</rt></ruby>)的区别在于,硬链接直接指向属于该文件的 inode ,而软链接直接指向一个目录项,即指向一个硬链接。因为软链接指向的是一个文件的硬链接而非该文件的 inode ,所以它们并不依赖于 inode 号,这使得它们能跨越不同的文件系统、分区和逻辑卷起作用。
|
||||
|
||||
软链接的缺点是,一旦它所指向的硬链接被删除或重命名后,该软链接就失效了。软链接虽然还在,但所指向的硬链接已不存在。所幸的是,`ls` 命令能以红底白字的方式在其列表中高亮显示失效的软链接。
|
||||
|
||||
### 实验项目: 链接实验
|
||||
|
||||
我认为最容易理解链接用法及其差异的方法是动手搭建一个项目。这个项目应以非超级用户的身份在一个空目录下进行。我创建了 `~/temp` 目录做这个实验,你也可以这么做。这么做可为项目创建一个安全的环境且提供一个新的空目录让程序运作,如此以来这儿仅存放和程序有关的文件。
|
||||
|
||||
#### 初始工作
|
||||
|
||||
首先,在你要进行实验的目录下为该项目中的任务创建一个临时目录,确保当前工作目录(PWD)是你的主目录,然后键入下列命令。
|
||||
|
||||
```
|
||||
mkdir temp
|
||||
```
|
||||
|
||||
使用这个命令将当前工作目录切换到 `~/temp`。
|
||||
|
||||
```
|
||||
cd temp
|
||||
```
|
||||
|
||||
实验开始,我们需要创建一个能够链接到的文件,下列命令可完成该工作并向其填充内容。
|
||||
|
||||
```
|
||||
du -h > main.file.txt
|
||||
```
|
||||
|
||||
使用 `ls -l` 长列表命名确认文件正确地创建了。运行结果应类似于我的。注意文件大小只有 7 字节,但你的可能会有 1~2 字节的变动。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ ls -l
|
||||
total 4
|
||||
-rw-rw-r-- 1 dboth dboth 7 Jun 13 07:34 main.file.txt
|
||||
```
|
||||
|
||||
在列表中,文件模式串后的数字 `1` 代表存在于该文件上的硬链接数。现在应该是 1 ,因为我们还没有为这个测试文件建立任何硬链接。
|
||||
|
||||
#### 对硬链接进行实验
|
||||
|
||||
硬链接创建一个指向同一 inode 的新目录项,当为文件添加一个硬链接时,你会看到链接数目的增加。确保当前工作目录仍为 `~/temp`。创建一个指向 `main.file.txt` 的硬链接,然后查看该目录下文件列表。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ ln main.file.txt link1.file.txt
|
||||
[dboth@david temp]$ ls -l
|
||||
total 8
|
||||
-rw-rw-r-- 2 dboth dboth 7 Jun 13 07:34 link1.file.txt
|
||||
-rw-rw-r-- 2 dboth dboth 7 Jun 13 07:34 main.file.txt
|
||||
```
|
||||
|
||||
目录中两个文件都有两个链接且大小相同,时间戳也一样。这就是有一个 inode 和两个硬链接(即该文件的目录项)的一个文件。再建立一个该文件的硬链接,并列出目录清单内容。你可以建立硬链接: `link1.file.txt` 或 `main.file.txt`。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ ln link1.file.txt link2.file.txt ; ls -l
|
||||
total 16
|
||||
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 link1.file.txt
|
||||
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 link2.file.txt
|
||||
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 main.file.txt
|
||||
```
|
||||
|
||||
注意,该目录下的每个硬链接必须使用不同的名称,因为同一目录下的两个文件不能拥有相同的文件名。试着创建一个和现存链接名称相同的硬链接。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ ln main.file.txt link2.file.txt
|
||||
ln: failed to create hard link 'link2.file.txt': File exists
|
||||
```
|
||||
|
||||
显然不行,因为 `link2.file.txt` 已经存在。目前为止我们只在同一目录下创建硬链接,接着在临时目录的父目录(你的主目录)中创建一个链接。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ ln main.file.txt ../main.file.txt ; ls -l ../main*
|
||||
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt
|
||||
```
|
||||
|
||||
上面的 `ls` 命令显示 `main.file.txt` 文件确实存在于主目录中,且与该文件在 `temp` 目录中的名称一致。当然它们不是不同的文件,它们是同一文件的两个链接,指向了同一文件的目录项。为了帮助说明下一点,在 `temp` 目录中添加一个非链接文件。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ touch unlinked.file ; ls -l
|
||||
total 12
|
||||
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link1.file.txt
|
||||
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link2.file.txt
|
||||
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt
|
||||
-rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
|
||||
```
|
||||
|
||||
使用 `ls` 命令的 `i` 选项查看 inode 的硬链接号和新创建文件的硬链接号。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ ls -li
|
||||
total 12
|
||||
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link1.file.txt
|
||||
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link2.file.txt
|
||||
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt
|
||||
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
|
||||
```
|
||||
|
||||
注意上面文件模式左边的数字 `657024` ,这是三个硬链接文件所指的同一文件的 inode 号,你也可以使用 `i` 选项查看主目录中所创建的链接的节点号,和该值相同。而那个只有一个链接的 inode 号和其他的不同,在你的系统上看到的 inode 号或许不同于本文中的。
|
||||
|
||||
接着改变其中一个硬链接文件的大小。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ df -h > link2.file.txt ; ls -li
|
||||
total 12
|
||||
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link1.file.txt
|
||||
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link2.file.txt
|
||||
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 main.file.txt
|
||||
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
|
||||
```
|
||||
|
||||
现在所有的硬链接文件大小都比原来大了,因为多个目录项都链接着同一文件。
|
||||
|
||||
下个实验在我的电脑上会出现这样的结果,是因为我的 `/tmp` 目录在一个独立的逻辑卷上。如果你有单独的逻辑卷或文件系统在不同的分区上(如果未使用逻辑卷),确定你是否能访问那个分区或逻辑卷,如果不能,你可以在电脑上挂载一个 U 盘,如果上述方式适合你,你可以进行这个实验。
|
||||
|
||||
试着在 `/tmp` 目录中建立一个 `~/temp` 目录下文件的链接(或你的文件系统所在的位置)。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ ln link2.file.txt /tmp/link3.file.txt
|
||||
ln: failed to create hard link '/tmp/link3.file.txt' => 'link2.file.txt':
|
||||
Invalid cross-device link
|
||||
```
|
||||
|
||||
为什么会出现这个错误呢? 原因是每一个单独的可挂载文件系统都有一套自己的 inode 号。简单的通过 inode 号来跨越整个 Linux 文件系统结构引用一个文件会使系统困惑,因为相同的节点号会存在于每个已挂载的文件系统中。
|
||||
|
||||
有时你可能会想找到一个 inode 的所有硬链接。你可以使用 `ls -li` 命令。然后使用 `find` 命令找到所有硬链接的节点号。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ find . -inum 657024
|
||||
./main.file.txt
|
||||
./link1.file.txt
|
||||
./link2.file.txt
|
||||
```
|
||||
|
||||
注意 `find` 命令不能找到所属该节点的四个硬链接,因为我们在 `~/temp` 目录中查找。 `find` 命令仅在当前工作目录及其子目录中查找文件。要找到所有的硬链接,我们可以使用下列命令,指定你的主目录作为起始查找条件。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ find ~ -samefile main.file.txt
|
||||
/home/dboth/temp/main.file.txt
|
||||
/home/dboth/temp/link1.file.txt
|
||||
/home/dboth/temp/link2.file.txt
|
||||
/home/dboth/main.file.txt
|
||||
```
|
||||
|
||||
如果你是非超级用户,没有权限,可能会看到错误信息。这个命令也使用了 `-samefile` 选项而不是指定文件的节点号。这个效果和使用 inode 号一样且更容易,如果你知道其中一个硬链接名称的话。
|
||||
|
||||
#### 对软链接进行实验
|
||||
|
||||
如你刚才看到的,不能跨越文件系统边界创建硬链接,即在逻辑卷或文件系统中从一个文件系统到另一个文件系统。软链接给出了这个问题的解决方案。虽然它们可以达到相同的目的,但它们是非常不同的,知道这些差异是很重要的。
|
||||
|
||||
让我们在 `~/temp` 目录中创建一个符号链接来开始我们的探索。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ ln -s link2.file.txt link3.file.txt ; ls -li
|
||||
total 12
|
||||
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link1.file.txt
|
||||
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link2.file.txt
|
||||
658270 lrwxrwxrwx 1 dboth dboth 14 Jun 14 15:21 link3.file.txt ->
|
||||
link2.file.txt
|
||||
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 main.file.txt
|
||||
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
|
||||
```
|
||||
|
||||
拥有节点号 `657024` 的那些硬链接没有变化,且硬链接的数目也没有变化。新创建的符号链接有不同的 inode 号 `658270`。 名为 `link3.file.txt` 的软链接指向了 `link2.file.txt` 文件。使用 `cat` 命令查看 `link3.file.txt` 文件的内容。符号链接的 inode 信息以字母 `l` (小写字母 l)开头,意味着这个文件实际是个符号链接。
|
||||
|
||||
上例中软链接文件 `link3.file.txt` 的大小只有 14 字节。这是文本内容 `link3.file.txt` 的大小,即该目录项的实际内容。目录项 `link3.file.txt` 并不指向一个 inode ;它指向了另一个目录项,这在跨越文件系统建立链接时很有帮助。现在试着创建一个软链接,之前在 `/tmp` 目录中尝试过的。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ ln -s /home/dboth/temp/link2.file.txt
|
||||
/tmp/link3.file.txt ; ls -l /tmp/link*
|
||||
lrwxrwxrwx 1 dboth dboth 31 Jun 14 21:53 /tmp/link3.file.txt ->
|
||||
/home/dboth/temp/link2.file.txt
|
||||
```
|
||||
|
||||
#### 删除链接
|
||||
|
||||
当你删除硬链接或硬链接所指的文件时,需要考虑一些问题。
|
||||
|
||||
首先,让我们删除硬链接文件 `main.file.txt`。注意指向 inode 的每个目录项就是一个硬链接。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ rm main.file.txt ; ls -li
|
||||
total 8
|
||||
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link1.file.txt
|
||||
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link2.file.txt
|
||||
658270 lrwxrwxrwx 1 dboth dboth 14 Jun 14 15:21 link3.file.txt ->
|
||||
link2.file.txt
|
||||
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
|
||||
```
|
||||
|
||||
`main.file.txt` 是该文件被创建时所创建的第一个硬链接。现在删除它,仍然保留着原始文件和硬盘上的数据以及所有剩余的硬链接。要删除原始文件,你必须删除它的所有硬链接。
|
||||
|
||||
现在删除 `link2.file.txt` 硬链接文件。
|
||||
|
||||
```
|
||||
[dboth@david temp]$ rm link2.file.txt ; ls -li
|
||||
total 8
|
||||
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link1.file.txt
|
||||
658270 lrwxrwxrwx 1 dboth dboth 14 Jun 14 15:21 link3.file.txt ->
|
||||
link2.file.txt
|
||||
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 main.file.txt
|
||||
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file
|
||||
```
|
||||
|
||||
注意软链接的变化。删除软链接所指的硬链接会使该软链接失效。在我的系统中,断开的链接用颜色高亮显示,目标的硬链接会闪烁显示。如果需要修复这个损坏的软链接,你需要在同一目录下建立一个和旧链接相同名字的硬链接,只要不是所有硬链接都已删除就行。您还可以重新创建链接本身,链接保持相同的名称,但指向剩余的硬链接中的一个。当然如果软链接不再需要,可以使用 `rm` 命令删除它们。
|
||||
|
||||
`unlink` 命令在删除文件和链接时也有用。它非常简单且没有选项,就像 `rm` 命令一样。然而,它更准确地反映了删除的基本过程,因为它删除了目录项与被删除文件的链接。
|
||||
|
||||
### 写在最后
|
||||
|
||||
我用过这两种类型的链接很长一段时间后,我开始了解它们的能力和特质。我为我所教的 Linux 课程编写了一个实验室项目,以充分理解链接是如何工作的,并且我希望增进你的理解。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
作者简介:
|
||||
|
||||
戴维.布斯 - 戴维.布斯是 Linux 和开源倡导者,居住在北卡罗莱纳的罗列 。他在 IT 行业工作了四十年,为 IBM 工作了 20 多年的 OS/2。在 IBM 时,他在 1981 年编写了最初的 IBM PC 的第一个培训课程。他为 RedHat 教授过 RHCE 班,并曾在 MCI Worldcom、思科和北卡罗莱纳州工作。他已经用 Linux 和开源软件工作将近 20 年了。
|
||||
|
||||
---------------------------------
|
||||
|
||||
via: https://opensource.com/article/17/6/linking-linux-filesystem
|
||||
|
||||
作者:[David Both][a]
|
||||
译者:[yongshouzhang](https://github.com/yongshouzhang)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/dboth
|
||||
[1]:https://opensource.com/resources/what-is-linux?src=linux_resource_menu
|
||||
[2]:https://opensource.com/resources/what-are-linux-containers?src=linux_resource_menu
|
||||
[3]:https://developers.redhat.com/promotions/linux-cheatsheet/?intcmp=7016000000127cYAAQ
|
||||
[4]:https://developers.redhat.com/cheat-sheet/advanced-linux-commands-cheatsheet?src=linux_resource_menu&intcmp=7016000000127cYAAQ
|
||||
[5]:https://opensource.com/tags/linux?src=linux_resource_menu
|
||||
[6]:https://opensource.com/article/17/6/linking-linux-filesystem?rate=YebHxA-zgNopDQKKOyX3_r25hGvnZms_33sYBUq-SMM
|
||||
[7]:https://opensource.com/user/14106/feed
|
||||
[8]:https://www.flickr.com/photos/digypho/7905320090
|
||||
[9]:https://creativecommons.org/licenses/by/2.0/
|
||||
[10]:https://linux.cn/article-8685-1.html
|
||||
[11]:https://linux.cn/article-8099-1.html
|
||||
[12]:https://linux.cn/article-8887-1.html
|
||||
[13]:https://opensource.com/business/16/9/linux-users-guide-lvm
|
||||
[14]:https://opensource.com/life/15/9/everything-is-a-file
|
||||
[15]:https://linux.cn/article-8685-1.html
|
||||
[16]:https://linux.cn/article-8685-1.html#3_19182
|
||||
[17]:https://opensource.com/users/dboth
|
||||
[18]:https://opensource.com/article/17/6/linking-linux-filesystem#comments
|
@ -0,0 +1,374 @@
|
||||
LinchPin:一个使用 Ansible 的简化的编配工具
|
||||
============================================================
|
||||
|
||||
> 2016 年末开始的 LinchPin,现在已经拥有一个 Python API 和一个成长中的社区。
|
||||
|
||||
![LinchPin 1.0:一个使用 Ansible 的成熟的混合云编配工具](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/toolbox-learn-draw-container-yearbook.png?itok=xDbwz1pP "LinchPin 1.0: A maturing hybrid cloud orchestration tool using Ansible")
|
||||
|
||||
>Image by : [Internet Archive Book Images][10]. Modified by Opensource.com. CC BY-SA 4.0
|
||||
|
||||
去年,[我的团队公布了][11] [LinchPin][12],这是一个使用 Ansible 的混合云<ruby>编配<rt>orchestration</rt></ruby>工具。<ruby>配给<rt>provision</rt></ruby>云资源从来没有这么容易便捷过。借助 Ansible 强力支持,LinchPin 专注于简化,使云资源让用户可以触手可及。在这篇文章中,我将介绍 LinchPin,并且去看看过去的 10 个月该项目是如何逐渐成熟。
|
||||
|
||||
(LCTT 译注:关于 orchestration 应该翻译成惯例的“编排”还是“编配”,有个 @wffger 提出的[建议](https://github.com/LCTT/TranslateProject/issues/6715) ,欢迎大家参与讨论。)
|
||||
|
||||
LinchPin 刚出现的时候,使用 `ansible-playbook` 命令去运行 LinchPin ,虽然可以完成,但是还是很复杂的,LinchPin 现在有一个前端命令行用户界面(CLI),它是用 [Click][14] 写的,而且它使 LinchPin 比以前更简化。
|
||||
|
||||
没有止步于 CLI,LinchPin 现在还有一个 [Python][15] API,它可以用于管理资源,比如,Amazon EC2 和 OpenStack 实例、网络、存储、安全组等等。这个 API [文档][16] 可以在你想去尝试 LinchPin 的 Python API 时帮助你。
|
||||
|
||||
### Playbook 是一个库
|
||||
|
||||
因为 LinchPin 的核心是 [Ansible playbook][17],其角色、模块、过滤器,以及任何被称为 Ansible 模块的东西都被移进 LinchPin 库中,这意味着我们虽然可以直接调用 playbook,但它不是资源管理的首选机制。`linchpin` 可执行文件事实上已经成为该命令行的前端。
|
||||
|
||||
### 深入了解命令行
|
||||
|
||||
让我们深入了解 `linchpin` 命令行:
|
||||
|
||||
```
|
||||
$ linchpin
|
||||
Usage: linchpin [OPTIONS] COMMAND [ARGS]...
|
||||
|
||||
linchpin: hybrid cloud orchestration
|
||||
|
||||
Options:
|
||||
-c, --config PATH Path to config file
|
||||
-w, --workspace PATH Use the specified workspace if the familiar Jenkins
|
||||
$WORKSPACE environment variable is not set
|
||||
-v, --verbose Enable verbose output
|
||||
--version Prints the version and exits
|
||||
--creds-path PATH Use the specified credentials path if WORKSPACE
|
||||
environment variable is not set
|
||||
-h, --help Show this message and exit.
|
||||
|
||||
Commands:
|
||||
init Initializes a linchpin project.
|
||||
up Provisions nodes from the given target(s) in...
|
||||
destroy Destroys nodes from the given target(s) in...
|
||||
```
|
||||
|
||||
你可以立即看到一个简单的描述,以及命令的选项和参数。这个帮助的最下面的三个命令是本文的重点内容。
|
||||
|
||||
#### 配置文件
|
||||
|
||||
之前有个名为 `linchpin_config.yml` 的文件。但现在这个文件没有了,替换它的是一个 ini 形式的配置文件,称为 `linchpin.conf`。虽然这个文件可以被修改或放到别的地方,它可以放置在配置文件容易找到的库路径中。在多数情况下,`linchpin.conf` 文件是不需要去修改的。
|
||||
|
||||
#### 工作空间
|
||||
|
||||
<ruby>工作空间<rt>workspace</rt></ruby>是一个定义好的文件系统路径,它是一个逻辑上的资源组。一个工作空间可以认为是一个特定环境、服务组、或其它逻辑组的一个单点。它也可以是一个所有可管理资源的大的存储容器。
|
||||
|
||||
工作空间可以在命令行上使用 `--workspace` (`-w`) 选项去指定,随后是工作空间路径。它也可以使用环境变量指定(比如,bash 中的 `$WORKSPACE`)。默认工作空间是当前目录。
|
||||
|
||||
#### 初始化 (`linchpin init`)
|
||||
|
||||
运行 `linchpin init` 将生成一个需要的目录结构,以及一个 `PinFile`、`topology`、和 `layout` 文件的示例:
|
||||
|
||||
```
|
||||
$ export WORKSPACE=/tmp/workspace
|
||||
$ linchpin init
|
||||
PinFile and file structure created at /tmp/workspace
|
||||
$ cd /tmp/workspace/
|
||||
$ tree
|
||||
.
|
||||
├── credentials
|
||||
├── hooks
|
||||
├── inventories
|
||||
├── layouts
|
||||
│ └── example-layout.yml
|
||||
├── PinFile
|
||||
├── resources
|
||||
└── topologies
|
||||
└── example-topology.yml
|
||||
```
|
||||
|
||||
在这个时候,可以执行 `linchpin up` ,然后提供一个 `libvirt` 虚拟机,和一个名为 `linchpin-centos71` 的网络。会生成一个<ruby>库存<rt>inventory</rt></ruby>,并放在 `inventories/libvirt.inventory` 目录中。它可以通过读取 `topologies/example-topology.yml` 和 `topology_name` 的值了解它。
|
||||
|
||||
#### <ruby>配给<rt>provisioning</rt></ruby> (`linchpin up`)
|
||||
|
||||
一旦有了一个 PinFile、拓扑、和一个可选的布局,就可以<ruby>配给<rt>provisioning</rt></ruby>了。
|
||||
|
||||
我们使用 dummy (模拟)工具,因为用它来配给非常简单;它不需要任何额外的东西(认证、网络、等等)。dummy 配给程序会创建一个临时文件,它表示所配给的主机。如果临时文件没有任何数据,说明主机没有被配给,或者它已经被销毁了。
|
||||
|
||||
dummy 配给程序的目录树大致如下:
|
||||
|
||||
```
|
||||
$ tree
|
||||
.
|
||||
├── hooks
|
||||
├── inventories
|
||||
├── layouts
|
||||
│ └── dummy-layout.yml
|
||||
├── PinFile
|
||||
├── resources
|
||||
└── topologies
|
||||
└── dummy-cluster.yml
|
||||
```
|
||||
|
||||
PinFile 也很简单;它指定了它的拓扑,并且为 `dummy1` 目标提供一个可选的布局:
|
||||
|
||||
```
|
||||
---
|
||||
dummy1:
|
||||
topology: dummy-cluster.yml
|
||||
layout: dummy-layout.yml
|
||||
```
|
||||
|
||||
`dummy-cluster.yml` 拓扑文件是一个引用,指向到配给的三个 `dummy_node` 类型的资源:
|
||||
|
||||
```
|
||||
---
|
||||
topology_name: "dummy_cluster" # topology name
|
||||
resource_groups:
|
||||
-
|
||||
resource_group_name: "dummy"
|
||||
resource_group_type: "dummy"
|
||||
resource_definitions:
|
||||
-
|
||||
name: "web"
|
||||
type: "dummy_node"
|
||||
count: 3
|
||||
```
|
||||
|
||||
执行命令 `linchpin up` 将基于上面的 `topology_name`(在这个案例中是 `dummy_cluster`)生成 `resources` 和 `inventory` 文件。
|
||||
|
||||
```
|
||||
$ linchpin up
|
||||
target: dummy1, action: up
|
||||
|
||||
$ ls {resources,inventories}/dummy*
|
||||
inventories/dummy_cluster.inventory resources/dummy_cluster.output
|
||||
```
|
||||
|
||||
要验证 dummy 集群的资源,可以检查 `/tmp/dummy.hosts`:
|
||||
|
||||
```
|
||||
$ cat /tmp/dummy.hosts
|
||||
web-0.example.net
|
||||
web-1.example.net
|
||||
web-2.example.net
|
||||
```
|
||||
|
||||
Dummy 模块为假定的(或模拟的)配给提供了一个基本工具。关于在 OpenStack、AWS EC2、Google Cloud 上和 LinchPin 的更多详细情况,可以去看[示例][18]。
|
||||
|
||||
#### <ruby>库存<rt>inventory</rt></ruby>生成
|
||||
|
||||
作为上面提到的 PinFile 的一部分,可以指定一个 `layout`。如果这个文件被指定,并且放在一个正确的位置上,就会为配给的资源自动生成一个用于 Ansible 的静态<ruby>库存<rt>inventory</rt></ruby>文件:
|
||||
|
||||
```
|
||||
---
|
||||
inventory_layout:
|
||||
vars:
|
||||
hostname: __IP__
|
||||
hosts:
|
||||
example-node:
|
||||
count: 3
|
||||
host_groups:
|
||||
- example
|
||||
```
|
||||
|
||||
当 `linchpin up` 运行完成,资源文件将提供一个很有用的详细信息。特别是,插入到静态库存的 IP 地址或主机名:
|
||||
|
||||
```
|
||||
[example]
|
||||
web-2.example.net hostname=web-2.example.net
|
||||
web-1.example.net hostname=web-1.example.net
|
||||
web-0.example.net hostname=web-0.example.net
|
||||
|
||||
[all]
|
||||
web-2.example.net hostname=web-2.example.net
|
||||
web-1.example.net hostname=web-1.example.net
|
||||
web-0.example.net hostname=web-0.example.net
|
||||
```
|
||||
|
||||
#### 卸载 (`linchpin destroy`)
|
||||
|
||||
LinchPin 也可以执行资源卸载。卸载动作一般认为该资源是已经配给好的;然而,因为 Ansible 是<ruby>幂等的<rt>idempotent</rt></ruby>,`linchpin destroy` 将仅检查确认该资源是启用的。如果这个资源已经是启用的,它将去卸载它。
|
||||
|
||||
命令 `linchpin destroy` 也将使用资源和/或拓扑文件去决定合适的卸载过程。
|
||||
|
||||
Ansible `dummy` 角色不使用资源,卸载期间仅有拓扑:
|
||||
|
||||
```
|
||||
$ linchpin destroy
|
||||
target: dummy1, action: destroy
|
||||
|
||||
$ cat /tmp/dummy.hosts
|
||||
-- EMPTY FILE --
|
||||
```
|
||||
|
||||
针对暂时的资源,卸载功能有一些限制,像网络、存储、等等。网络资源可以被用于多个云实例。在这种情况下,执行一个 `linchpin destroy` 某些资源就不能卸载。这取决于每个供应商的实现。查看每个[供应商][19]的具体实现。
|
||||
|
||||
### LinchPin 的 Python API
|
||||
|
||||
在 `linchpin` 命令行中实现的功能大多数都是用 Python API 写的。这个 API,虽然不完整,但它已经成为 LinchPin 工具的至关重要的组件。
|
||||
|
||||
这个 API 由下面的三个包组成:
|
||||
|
||||
* `linchpin`
|
||||
* `linchpin.cli`
|
||||
* `linchpin.api`
|
||||
|
||||
该命令行工具是基于 `linchpin` 包来管理的。它导入了 `linchpin.cli` 模块和类,该类是 `linchpin.api` 的子类。这样做的目的是为了允许使用 `linchpin.api` 来做其它的 LinchPin 实现,比如像计划中的 RESTful API。
|
||||
|
||||
更多信息,去查看 [Python API library documentation on Read the Docs][20]。
|
||||
|
||||
### Hook
|
||||
|
||||
LinchPin 1.0 的其中一个大的变化是转向 hook。hook 的目标是在 `linchpin` 运行期间的特定状态下,允许配置使用更多外部资源。目前的状态有:
|
||||
|
||||
* `preup`: 在配给拓扑资源之前运行
|
||||
* `postup`: 在配给拓扑资源之后运行,并且生成可选的<ruby>库存<rt>inventory</rt></ruby>
|
||||
* `predestroy`: 卸载拓扑资源之前运行
|
||||
* `postdestroy`: 卸载拓扑资源之后运行
|
||||
|
||||
在每种状态下,这些 hooks 允许运行外部脚本。存在几种类型的 hook,包括一个定制的叫做 _Action Managers_。这是一个内置的 Action Manager 的列表:
|
||||
|
||||
* `shell`: 允许任何的<ruby>内联<rt>inline</rt></ruby>的 shell 命令,或者一个可运行的 shell 脚本
|
||||
* `python`: 运行一个 Python 脚本
|
||||
* `ansible`: 运行一个 Ansible playbook,允许传递一个 `vars_file` 和 `extra_vars` 作为 Python 字典
|
||||
* `nodejs`: 运行一个 Node.js 脚本
|
||||
* `ruby`: 运行一个 Ruby 脚本
|
||||
|
||||
hook 被绑定到一个特定的目标,并且每个目标使用时必须重新声明。将来,hook 将可能是全局的,然后它们在每个目标的 `hooks` 节下命名会更简单。
|
||||
|
||||
#### 使用 hook
|
||||
|
||||
hook 描述起来非常简单,但理解它们强大的功能却并不简单。这个特性的存在是为了给用户灵活提供那些 LinchPin 开发者所没有考虑到的功能。这个概念可能会带来 ping 一套系统的简单方式,举个实例,比如在运行另一个 hook 之前。
|
||||
|
||||
更仔细地去研究 _工作空间_ ,你可能会注意到 `hooks` 目录,让我们看一下这个目录的结构:
|
||||
|
||||
```
|
||||
$ tree hooks/
|
||||
hooks/
|
||||
├── ansible
|
||||
│ ├── ping
|
||||
│ │ └── dummy_ping.yaml
|
||||
└── shell
|
||||
└── database
|
||||
├── init_db.sh
|
||||
└── setup_db.sh
|
||||
```
|
||||
|
||||
在任何情况下,hook 都可以用在 `PinFile` 中,展示如下:
|
||||
|
||||
```
|
||||
---
|
||||
dummy1:
|
||||
topology: dummy-cluster.yml
|
||||
layout: dummy-layout.yml
|
||||
hooks:
|
||||
postup:
|
||||
- name: ping
|
||||
type: ansible
|
||||
actions:
|
||||
- dummy_ping.yaml
|
||||
- name: database
|
||||
type: shell
|
||||
actions:
|
||||
- setup_db.sh
|
||||
- init_db.sh
|
||||
```
|
||||
|
||||
基本概念是有三个 postup 动作要完成。Hook 是从上到下运行的,因此,Ansible `ping` 任务将首先运行,紧接着是两个 shell 任务, `setup_db.sh` 和 `init_db.sh`。假设 hook 运行成功。将发生一个系统的 ping,然后,一个数据库被安装和初始化。
|
||||
|
||||
### 认证的驱动程序
|
||||
|
||||
在 LinchPin 的最初设计中,开发者决定在 Ansible playbooks 中管理认证;然而,逐渐有更多的 API 和命令行驱动的工具后,意味着认证将被置于 playbooks 库之外,并且还可以根据需要去传递认证值。
|
||||
|
||||
#### 配置
|
||||
|
||||
让用户使用驱动程序提供的认证方法去完成这个任务。举个实例,如果对于 OpenStack 调用的拓扑,标准方法是使用一个 yaml 文件,或者类似于 `OS_` 前缀的环境变量。`clouds.yaml` 文件是一个 profile 文件的组成部分,它有一个 `auth` 节:
|
||||
|
||||
```
|
||||
clouds:
|
||||
default:
|
||||
auth:
|
||||
auth_url: http://stack.example.com:5000/v2.0/
|
||||
project_name: factory2
|
||||
username: factory-user
|
||||
password: password-is-not-a-good-password
|
||||
```
|
||||
|
||||
更多详细信息在 [OpenStack documentation][21]。
|
||||
|
||||
这个 `clouds.yaml` 或者任何其它认证文件位于 `default_credentials_path` (比如,`~/.config/linchpin`)中,并在拓扑中引用:
|
||||
|
||||
```
|
||||
---
|
||||
topology_name: openstack-test
|
||||
resource_groups:
|
||||
-
|
||||
resource_group_name: linchpin
|
||||
resource_group_type: openstack
|
||||
resource_definitions:
|
||||
- name: resource
|
||||
type: os_server
|
||||
flavor: m1.small
|
||||
image: rhel-7.2-server-x86_64-released
|
||||
count: 1
|
||||
keypair: test-key
|
||||
networks:
|
||||
- test-net2
|
||||
fip_pool: 10.0.72.0/24
|
||||
credentials:
|
||||
filename: clouds.yaml
|
||||
profile: default
|
||||
```
|
||||
|
||||
`default_credentials_path` 可以通过修改 `linchpin.conf` 改变。
|
||||
|
||||
拓扑在底部包含一个新的 `credentials` 节。使用 `openstack`、`ec2`、和 `gcloud` 模块,也可以去指定类似的凭据。认证驱动程序将查看给定的名为 `clouds.yaml` 的文件,并搜索名为 `default` 的 _配置_。
|
||||
|
||||
假设认证被找到并被加载,配给将正常继续。
|
||||
|
||||
### 简化
|
||||
|
||||
虽然 LinchPin 可以完成复杂的拓扑、库存布局、hooks、和认证管理,但是,终极目标是简化。通过使用一个命令行界面的简化,除了提升已经完成的 1.0 版的开发者体验外,LinchPin 将持续去展示复杂的配置可以很简单地去管理。
|
||||
|
||||
### 社区的成长
|
||||
|
||||
在过去的一年中,LinchPin 的社区现在已经有了 [邮件列表][22]和一个 IRC 频道(#linchpin on chat.freenode.net,而且在 [GitHub][23] 中我们很努力地管理它。
|
||||
|
||||
在过去的一年里,社区成员已经从 2 位核心开发者增加到大约 10 位贡献者。更多的人持续参与到项目中。如果你对 LinchPin 感兴趣,可以给我们写信、在 GitHub 上提问,加入 IRC,或者给我们发邮件。
|
||||
|
||||
_这篇文章是基于 Clint Savage 在 OpenWest 上的演讲 [Introducing LinchPin: Hybrid cloud provisioning using Ansible][7] 整理的。[OpenWest][8] 将在 2017 年 7 月 12-15 日在盐城湖市举行。_
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
作者简介:
|
||||
|
||||
Clint Savage - 工作于 Red Hat 是一位负责原子项目(Project Atomic)的高级软件工程师。他的工作是为 Fedora、CentOS、和 Red Hat Enterprise Linux(RHEL)提供自动原子服务器构建。
|
||||
|
||||
-------------
|
||||
|
||||
via: https://opensource.com/article/17/6/linchpin
|
||||
|
||||
作者:[Clint Savage][a]
|
||||
译者:[qhwdw](https://github.com/qhwdw)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/herlo
|
||||
[1]:https://opensource.com/resources/cloud?src=cloud_resource_menu1
|
||||
[2]:https://opensource.com/resources/what-is-openstack?src=cloud_resource_menu2
|
||||
[3]:https://opensource.com/resources/what-is-kubernetes?src=cloud_resource_menu3
|
||||
[4]:https://opensource.com/16/12/yearbook-why-operating-system-matters?src=cloud_resource_menu4
|
||||
[5]:https://opensource.com/business/16/10/interview-andy-cathrow-anchore?src=cloud_resource_menu5
|
||||
[6]:https://opensource.com/article/17/6/linchpin?rate=yx4feHOc5Kf9gaZe5S4MoVAmf9mgtociUimJKAYgwZs
|
||||
[7]:https://www.openwest.org/custom/description.php?id=166
|
||||
[8]:https://www.openwest.org/
|
||||
[9]:https://opensource.com/user/145261/feed
|
||||
[10]:https://www.flickr.com/photos/internetarchivebookimages/14587478927/in/photolist-oe2Gwy-otuvuy-otus3U-otuuh3-ovwtoH-oe2AXD-otutEw-ovwpd8-oe2Me9-ovf688-oxhaVa-oe2mNh-oe3AN6-ovuyL7-ovf9Kt-oe2m4G-ovwqsH-ovjfJY-ovjfrU-oe2rAU-otuuBw-oe3Dgn-oe2JHY-ovfcrF-oe2Ns1-ovjh2N-oe3AmK-otuwP7-ovwrHt-ovwmpH-ovf892-ovfbsr-ovuAzN-ovf3qp-ovuFcJ-oe2T3U-ovwn8r-oe2L3T-oe3ELr-oe2Dmr-ovuyB9-ovuA9s-otuvPG-oturHA-ovuDAh-ovwkV6-ovf5Yv-ovuCC5-ovfc2x-oxhf1V
|
||||
[11]:http://sexysexypenguins.com/posts/introducing-linch-pin/
|
||||
[12]:http://linch-pin.readthedocs.io/en/develop/
|
||||
[13]:https://opensource.com/resources/cloud
|
||||
[14]:http://click.pocoo.org/
|
||||
[15]:https://opensource.com/resources/python
|
||||
[16]:http://linchpin.readthedocs.io/en/develop/libdocs.html
|
||||
[17]:http://docs.ansible.com/ansible/playbooks.html
|
||||
[18]:https://github.com/CentOS-PaaS-SIG/linchpin/tree/develop/linchpin/examples/topologies
|
||||
[19]:https://github.com/CentOS-PaaS-SIG/linch-pin/tree/develop/linchpin/provision/roles
|
||||
[20]:http://linchpin.readthedocs.io/en/develop/libdocs.html
|
||||
[21]:https://docs.openstack.org/developer/python-openstackclient/configuration.html
|
||||
[22]:https://www.redhat.com/mailman/listinfo/linchpin
|
||||
[23]:https://github.com/CentOS-PaaS-SIG/linch-pin/projects/4
|
||||
[24]:https://opensource.com/users/herlo
|
@ -0,0 +1,124 @@
|
||||
Neo4j 和图数据库起步
|
||||
============================================================
|
||||
|
||||
> 在这个三篇文章系列中的第二篇中,安装 Neo4j 并通过网页客户端来在图中插入和查询数据。
|
||||
|
||||
![Neo4j 和图数据库: 开始](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/LIFE_wavegraph.png?itok=z4pXCf_c "Neo4j and graph databases: Getting started")
|
||||
|
||||
在本系列的 [第一篇][8] 中,我们介绍了图数据库中的一些核心概念。在这篇,我们将安装 [Neo4j][9] 并通过网页客户端在图中插入并查询数据。
|
||||
|
||||
可通过 [他们的网站][10] 下载社区版的 Neo4j!你可以下载 Windows 或 OSX 版来测试,也有各 Linux 发行版对应的版本,还有 Docker 版。
|
||||
|
||||
我会在 Debian 9 (stretch) 上安装软件。你可在 [这里][11] 查看完整说明。如果你正在使用 Debian 8 (jessie) 或更老的版本,你可以安装当前的版本,但会出现的一点小问题是 jessie 中并没有安装 Neo4j 运行所需要的 Java 8 环境。
|
||||
|
||||
```
|
||||
wget -O - https://debian.neo4j.org/neotechnology.gpg.key | sudo apt-key add - echo 'deb https://debian.neo4j.org/repo stable/' | sudo tee /etc/apt/sources.list.d/neo4j.list sudo apt-get update sudo apt-get install neo4j
|
||||
```
|
||||
|
||||
在我的系统中,出于某些原因,我创建好 `/var/run/neo4j` 之后它就可以很轻松地开始了。Neo4j 给了一个“最大打开文件数”的警告,但因为是测试环境所以我不太需要关心这个问题。Neo4j 默认只会监听本机 localhost 上的连接。如果你的机器是 Debian ,那这很好,但是我的不是。我修改了 `/etc/neo4j/neo4j.conf` ,取消注释了下面这行:
|
||||
|
||||
```
|
||||
dbms.connectors.default_listen_address=0.0.0.0
|
||||
```
|
||||
|
||||
在重启 Neo4j 之后,我可以通过 7474 端口来访问服务器的 Neo4j 服务。默认的用户名和密码是 `Neo4j` 和 `neo4j`; 你需要设置一个新密码,然后会出现初始页面:
|
||||
|
||||
![Installing Neo4J](https://opensource.com/sites/default/files/u128651/article_2_image_1.jpg "Installing Neo4J")
|
||||
|
||||
让我们在 Neo4j 上创建[上篇文章][8]中使用过的图。如下图:
|
||||
|
||||
![Graph database image 2, defining a new type of node](https://opensource.com/sites/default/files/u128651/article_1_image_2.jpg "Graph database image 2, defining a new type of node")
|
||||
|
||||
类似 MySQL 和其它的数据库系统,Neo4j 的各类操作也使用一套查询语句。Cypher,就是 Neo4j 使用的查询语句,但有一些语法区别需要去学习和注意。<ruby>节点<rt>node</rt></ruby>需要用圆括号表示,而<ruby>关系 <rt>relationship</rt></ruby> 需要放在方括号中。因为这是系统中唯二的数据类型,所以了解这些就够了。
|
||||
|
||||
首先,我们创建所有的节点。你需要将下面内容复制黏贴到浏览器顶部区域中,在那里运行查询语句。
|
||||
|
||||
```
|
||||
CREATE (a:Person { name: 'Jane Doe', favorite_color: 'purple' }) CREATE (b:Person { name: 'John Doe' }) CREATE (c:Person { name: 'Mary Smith', favorite_color: 'red', dob: '1992-11-09' }) CREATE (d:Person { name: 'Robert Roe' }) CREATE (e:Person { name: 'Rhonda Roe' }) CREATE (f:Person { name: 'Ryan Roe' }) CREATE (t:City { name: 'Petaluma, CA' }) CREATE (u:City { name: 'Cypress, TX' }) CREATE (v:City { name: 'Grand Prairie, TX' }) CREATE (w:City { name: 'Houston, TX' })
|
||||
```
|
||||
|
||||
注意,在标签前的字符就是变量。这些信息会在出现在各个地方,但我们在这里并不会用到。但你不能不指定相应信息就盲目创建,所以我们使用它们然后就忽略它们。
|
||||
|
||||
在上面一共创建了 10 个节点和 13 个属性。想查看它们? 通过下面语句来匹配查询所有节点:
|
||||
|
||||
```
|
||||
MATCH (n) RETURN n
|
||||
```
|
||||
|
||||
这条语句会返回一个可视化的图。(在应用内,你可以在返回的图中使用”全屏”按钮来查看大图)。你将会看到类似下面的图像:
|
||||
|
||||
|
||||
![Visual graph](https://opensource.com/sites/default/files/u128651/article_2_image_2.jpg "Visual graph")
|
||||
|
||||
添加关系需要一点技巧;你需要连接的节点必须是 “<ruby>在限定范围内的<rt>in scope</rt></ruby>”,意思连接的节点是在当前查询语句所限定的范围内的。我们之前使用的查询语句范围太大,所以让我们找到 John 和 Jane 并让他们结婚:
|
||||
|
||||
```
|
||||
MATCH (a:Person),(b:Person) WHERE a.name='Jane Doe' AND b.name='John Doe' CREATE (a)-[r:MARRIAGE {date: '2017-03-04', place: 'Houston, TX'}]->(b)
|
||||
```
|
||||
|
||||
这条语句会创建一个关系并设置两个属性。重新运行该 `MATCH` 语句会显示那个关系。你可以通过鼠标点击任意的节点或关系来查看它们的属性。
|
||||
|
||||
我们来添加其它的关系。比起使用一些列的 `MATCH` 语句,我会一次性做完并从中 `CREATE` 创建多个关系。
|
||||
|
||||
```
|
||||
MATCH (a:Person),(b:Person),(c:Person),(d:Person),(e:Person),(f:Person),(t:City),(u:City),(v:City),(w:City) WHERE a.name='Jane Doe' AND b.name='John Doe' AND c.name='Mary Smith' AND d.name='Robert Roe' AND e.name='Rhonda Roe' AND f.name='Ryan Roe' AND t.name='Petaluma, CA' AND u.name='Cypress, TX' AND v.name='Grand Prairie, TX' AND w.name='Houston, TX' CREATE (d)-[m2:MARRIAGE {date: '1990-12-01', place: 'Chicago, IL'}]->(e) CREATE (a)-[n:CHILD]->(c) CREATE (d)-[n2:CHILD]->(f) CREATE (e)-[n3:CHILD]->(f) CREATE (b)-[n4:STEPCHILD]->(c) CREATE (a)-[o:BORN_IN]->(v) CREATE (b)-[o2:BORN_IN]->(t) CREATE (c)-[p:DATING]->(f) CREATE (a)-[q:LIVES_IN]->(u) CREATE (b)-[q1:LIVES_IN]->(u) CREATE (a)-[r:WORKS_IN]->(w) CREATE (a)-[s:FRIEND]->(d) CREATE (a)-[s2:FRIEND]->(e)
|
||||
```
|
||||
|
||||
重新运行该 `MATCH` 语句,你将会看到下面图像:
|
||||
|
||||
|
||||
![Graph after re-querying with MATCH](https://opensource.com/sites/default/files/u128651/article_2_image_3.jpg "Graph after re-querying with MATCH")
|
||||
|
||||
如果你喜欢,你可以将节点拖拉成像我之前画的图的样子。
|
||||
|
||||
在这个例子中,我们唯一使用的 `MATCH` 就是 `MATCH` 所有的东西。下面这个查询会返回两个结婚了的夫妻并显示他们之间的关系:
|
||||
|
||||
```
|
||||
MATCH (a)-[b:MARRIAGE]->(c) RETURN a,b,c
|
||||
```
|
||||
|
||||
在一个更复杂的图中,你可以做更多的细节查询。(LCTT 译注:此例子为 Neo4j 自带例子的)例如,你有关于电影和人的节点,还有像 `ACTED IN`、`DIRECTED`、`WROTE SCREENPLAY` 等属性的关系,你可以运行下面这个查询:
|
||||
|
||||
```
|
||||
MATCH (p:Person { name: 'Mel Gibson' })--(m:Movie) RETURN m.title
|
||||
```
|
||||
|
||||
……上述是查询和 Mel Gibson 相关的所有影片。但如果你想查询他演过的所有电影,下面这条语句会更有用:
|
||||
|
||||
```
|
||||
MATCH (p:Person { name: 'Mel Gibson' })-[r:ACTED_IN]->(m:movie) RETURN m.title,r.role
|
||||
```
|
||||
|
||||
还有更多更炫酷的 Cypher 语句可以使用,但我们就简单介绍这些。更详细完整的 Cypher 语句可以在 Neo4j 的[官网][12]上查看, 并且也有很多例子可以练习。
|
||||
|
||||
在此系列的下篇文章中,我们会通过写些 Perl 脚本来展示如何在应用中使用图数据库。
|
||||
|
||||
(图片来源 : opensource.com)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/17/7/neo4j-graph-databases-getting-started
|
||||
|
||||
作者:[Ruth Holloway][a]
|
||||
译者:[happygeorge01](https://github.com/happygeorge01)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/druthb
|
||||
[1]:https://opensource.com/file/363066
|
||||
[2]:https://opensource.com/file/363061
|
||||
[3]:https://opensource.com/file/363071
|
||||
[4]:https://opensource.com/file/363076
|
||||
[5]:https://opensource.com/article/17/7/neo4j-graph-databases-getting-started?rate=hqfP7Li5t_MqS9sV0FXwGAC0fVBoBXOglypRL7c-Zn4
|
||||
[6]:https://opensource.com/users/druthb
|
||||
[7]:https://opensource.com/user/36051/feed
|
||||
[8]:https://linux.cn/article-8728-1.html
|
||||
[9]:https://neo4j.com/
|
||||
[10]:https://neo4j.com/download/community-edition/
|
||||
[11]:http://debian.neo4j.org/?_ga=2.172102506.853767004.1499179137-1089522652.1499179137
|
||||
[12]:https://neo4j.com/docs/developer-manual/current/cypher/
|
||||
[13]:https://opensource.com/users/druthb
|
||||
[14]:https://opensource.com/users/druthb
|
||||
[15]:https://opensource.com/users/druthb
|
||||
[16]:https://opensource.com/tags/programming
|
@ -0,0 +1,219 @@
|
||||
在红帽企业版 Linux 中将系统服务容器化(一)
|
||||
====================
|
||||
|
||||
在 2017 年红帽峰会上,有几个人问我“我们通常用完整的虚拟机来隔离如 DNS 和 DHCP 等网络服务,那我们可以用容器来取而代之吗?”答案是可以的,下面是在当前红帽企业版 Linux 7 系统上创建一个系统容器的例子。
|
||||
|
||||
### 我们的目的
|
||||
|
||||
**创建一个可以独立于任何其它系统服务而更新的网络服务,并且可以从主机端容易地管理和更新。**
|
||||
|
||||
让我们来探究一下在容器中建立一个运行在 systemd 之下的 BIND 服务器。在这一部分,我们将了解到如何建立自己的容器以及管理 BIND 配置和数据文件。
|
||||
|
||||
在本系列的第二部分,我们将看到如何整合主机中的 systemd 和容器中的 systemd。我们将探究如何管理容器中的服务,并且使它作为一种主机中的服务。
|
||||
|
||||
### 创建 BIND 容器
|
||||
|
||||
为了使 systemd 在一个容器中轻松运行,我们首先需要在主机中增加两个包:`oci-register-machine` 和 `oci-systemd-hook`。`oci-systemd-hook` 这个钩子允许我们在一个容器中运行 systemd,而不需要使用特权容器或者手工配置 tmpfs 和 cgroups。`oci-register-machine` 这个钩子允许我们使用 systemd 工具如 `systemctl` 和 `machinectl` 来跟踪容器。
|
||||
|
||||
```
|
||||
[root@rhel7-host ~]# yum install oci-register-machine oci-systemd-hook
|
||||
```
|
||||
|
||||
回到创建我们的 BIND 容器上。[红帽企业版 Linux 7 基础镜像][6]包含了 systemd 作为其初始化系统。我们可以如我们在典型的系统中做的那样安装并激活 BIND。你可以从 [git 仓库中下载这份 Dockerfile][8]。
|
||||
|
||||
```
|
||||
[root@rhel7-host bind]# vi Dockerfile
|
||||
|
||||
# Dockerfile for BIND
|
||||
FROM registry.access.redhat.com/rhel7/rhel
|
||||
ENV container docker
|
||||
RUN yum -y install bind && \
|
||||
yum clean all && \
|
||||
systemctl enable named
|
||||
STOPSIGNAL SIGRTMIN+3
|
||||
EXPOSE 53
|
||||
EXPOSE 53/udp
|
||||
CMD [ "/sbin/init" ]
|
||||
```
|
||||
|
||||
因为我们以 PID 1 来启动一个初始化系统,当我们告诉容器停止时,需要改变 docker CLI 发送的信号。从 `kill` 系统调用手册中 (`man 2 kill`):
|
||||
|
||||
> 唯一可以发送给 PID 1 进程(即 init 进程)的信号,是那些初始化系统明确安装了<ruby>信号处理器<rt>signal handler</rt></ruby>的信号。这是为了避免系统被意外破坏。
|
||||
|
||||
对于 systemd 信号处理器,`SIGRTMIN+3` 是对应于 `systemd start halt.target` 的信号。我们也需要为 BIND 暴露 TCP 和 UDP 端口号,因为这两种协议可能都要使用。
|
||||
|
||||
### 管理数据
|
||||
|
||||
有了一个可以工作的 BIND 服务,我们还需要一种管理配置文件和区域文件的方法。目前这些都放在容器里面,所以我们任何时候都可以进入容器去更新配置或者改变一个区域文件。从管理的角度来说,这并不是很理想。当要更新 BIND 时,我们将需要重建这个容器,所以镜像中的改变将会丢失。任何时候我们需要更新一个文件或者重启服务时,都需要进入这个容器,而这增加了步骤和时间。
|
||||
|
||||
相反的,我们将从这个容器中提取出配置文件和数据文件,把它们拷贝到主机上,然后在运行的时候挂载它们。用这种方式我们可以很容易地重启或者重建容器,而不会丢失所做出的更改。我们也可以使用容器外的编辑器来更改配置和区域文件。因为这个容器的数据看起来像“该系统所提供服务的特定站点数据”,让我们遵循 Linux <ruby>文件系统层次标准<rt>File System Hierarchy</rt></ruby>,并在当前主机上创建 `/srv/named` 目录来保持管理权分离。
|
||||
|
||||
```
|
||||
[root@rhel7-host ~]# mkdir -p /srv/named/etc
|
||||
|
||||
[root@rhel7-host ~]# mkdir -p /srv/named/var/named
|
||||
```
|
||||
|
||||
*提示:如果你正在迁移一个已有的配置文件,你可以跳过下面的步骤并且将它直接拷贝到 `/srv/named` 目录下。你也许仍然要用一个临时容器来检查一下分配给这个容器的 GID。*
|
||||
|
||||
让我们建立并运行一个临时容器来检查 BIND。在将 init 进程以 PID 1 运行时,我们不能交互地运行这个容器来获取一个 shell。我们会在容器启动后执行 shell,并且使用 `rpm` 命令来检查重要文件。
|
||||
|
||||
```
|
||||
[root@rhel7-host ~]# docker build -t named .
|
||||
|
||||
[root@rhel7-host ~]# docker exec -it $( docker run -d named ) /bin/bash
|
||||
|
||||
[root@0e77ce00405e /]# rpm -ql bind
|
||||
```
|
||||
|
||||
对于这个例子来说,我们将需要 `/etc/named.conf` 和 `/var/named/` 目录下的任何文件。我们可以使用 `machinectl` 命令来提取它们。如果注册了一个以上的容器,我们可以在任一机器上使用 `machinectl status` 命令来查看运行的是什么。一旦有了这些配置,我们就可以终止这个临时容器了。
|
||||
|
||||
*如果你喜欢,资源库中也有一个[样例 `named.conf` 和针对 `example.com` 的区域文件][8]。*
|
||||
|
||||
```
|
||||
[root@rhel7-host bind]# machinectl list
|
||||
|
||||
MACHINE CLASS SERVICE
|
||||
8824c90294d5a36d396c8ab35167937f container docker
|
||||
|
||||
[root@rhel7-host ~]# machinectl copy-from 8824c90294d5a36d396c8ab35167937f /etc/named.conf /srv/named/etc/named.conf
|
||||
|
||||
[root@rhel7-host ~]# machinectl copy-from 8824c90294d5a36d396c8ab35167937f /var/named /srv/named/var/named
|
||||
|
||||
[root@rhel7-host ~]# docker stop infallible_wescoff
|
||||
```
|
||||
|
||||
### 最终的创建
|
||||
|
||||
为了创建和运行最终的容器,添加卷选项以挂载:
|
||||
|
||||
- 将文件 `/srv/named/etc/named.conf` 映射为 `/etc/named.conf`
|
||||
- 将目录 `/srv/named/var/named` 映射为 `/var/named`
|
||||
|
||||
因为这是我们最终的容器,我们将提供一个有意义的名字,以供我们以后引用。
|
||||
|
||||
```
|
||||
[root@rhel7-host ~]# docker run -d -p 53:53 -p 53:53/udp -v /srv/named/etc/named.conf:/etc/named.conf:Z -v /srv/named/var/named:/var/named:Z --name named-container named
|
||||
```
|
||||
|
||||
在最终容器运行时,我们可以更改本机配置来改变这个容器中 BIND 的行为。这个 BIND 服务器将需要在这个容器分配的任何 IP 上监听。请确保任何新文件的 GID 与来自这个容器中的其余的 BIND 文件相匹配。
|
||||
|
||||
```
|
||||
[root@rhel7-host bind]# cp named.conf /srv/named/etc/named.conf
|
||||
|
||||
[root@rhel7-host ~]# cp example.com.zone /srv/named/var/named/example.com.zone
|
||||
|
||||
[root@rhel7-host ~]# cp example.com.rr.zone /srv/named/var/named/example.com.rr.zone
|
||||
```
|
||||
|
||||
> 很好奇为什么我不需要在主机目录中改变 SELinux 上下文?^注1
|
||||
|
||||
我们将运行这个容器提供的 `rndc` 二进制文件重新加载配置。我们可以使用 `journald` 以同样的方式检查 BIND 日志。如果运行出现错误,你可以在主机中编辑该文件,并且重新加载配置。在主机中使用 `host` 或 `dig`,我们可以检查来自该容器化服务的 example.com 的响应。
|
||||
|
||||
```
|
||||
[root@rhel7-host ~]# docker exec -it named-container rndc reload
|
||||
server reload successful
|
||||
|
||||
[root@rhel7-host ~]# docker exec -it named-container journalctl -u named -n
|
||||
-- Logs begin at Fri 2017-05-12 19:15:18 UTC, end at Fri 2017-05-12 19:29:17 UTC. --
|
||||
May 12 19:29:17 ac1752c314a7 named[27]: automatic empty zone: 9.E.F.IP6.ARPA
|
||||
May 12 19:29:17 ac1752c314a7 named[27]: automatic empty zone: A.E.F.IP6.ARPA
|
||||
May 12 19:29:17 ac1752c314a7 named[27]: automatic empty zone: B.E.F.IP6.ARPA
|
||||
May 12 19:29:17 ac1752c314a7 named[27]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA
|
||||
May 12 19:29:17 ac1752c314a7 named[27]: reloading configuration succeeded
|
||||
May 12 19:29:17 ac1752c314a7 named[27]: reloading zones succeeded
|
||||
May 12 19:29:17 ac1752c314a7 named[27]: zone 1.0.10.in-addr.arpa/IN: loaded serial 2001062601
|
||||
May 12 19:29:17 ac1752c314a7 named[27]: zone 1.0.10.in-addr.arpa/IN: sending notifies (serial 2001062601)
|
||||
May 12 19:29:17 ac1752c314a7 named[27]: all zones loaded
|
||||
May 12 19:29:17 ac1752c314a7 named[27]: running
|
||||
|
||||
[root@rhel7-host bind]# host www.example.com localhost
|
||||
Using domain server:
|
||||
Name: localhost
|
||||
Address: ::1#53
|
||||
Aliases:
|
||||
www.example.com is an alias for server1.example.com.
|
||||
server1.example.com is an alias for mail
|
||||
```
|
||||
|
||||
> 你的区域文件没有更新吗?可能是因为你的编辑器,而不是序列号。^注2
|
||||
|
||||
### 终点线
|
||||
|
||||
我们已经达成了我们打算完成的目标,从容器中为 DNS 请求和区域文件提供服务。我们已经得到一个持久化的位置来管理更新和配置,并且更新后该配置不变。
|
||||
|
||||
在这个系列的第二部分,我们将看到怎样将一个容器看作为主机中的一个普通服务来运行。
|
||||
|
||||
---
|
||||
|
||||
[关注 RHEL 博客](http://redhatstackblog.wordpress.com/feed/),通过电子邮件来获得本系列第二部分和其它新文章的更新。
|
||||
|
||||
---
|
||||
|
||||
### 附加资源
|
||||
|
||||
- **所附带文件的 Github 仓库:** [https://github.com/nzwulfin/named-container](https://github.com/nzwulfin/named-container)
|
||||
- **注1:** **通过容器访问本地文件的 SELinux 上下文**
|
||||
|
||||
你可能已经注意到当我从容器向本地主机拷贝文件时,我没有运行 `chcon` 将主机中的文件类型改变为 `svirt_sandbox_file_t`。为什么它没有出错?将一个文件拷贝到 `/srv` 会将这个文件标记为类型 `var_t`。我 `setenforce 0` (关闭 SELinux)了吗?
|
||||
|
||||
当然没有,这将让 [Dan Walsh 大哭](https://stopdisablingselinux.com/)(LCTT 译注:RedHat 的 SELinux 团队负责人,倡议不要禁用 SELinux)。是的,`machinectl` 确实将文件标记类型设置为期望的那样,可以看一下:
|
||||
|
||||
启动一个容器之前:
|
||||
|
||||
```
|
||||
[root@rhel7-host ~]# ls -Z /srv/named/etc/named.conf
|
||||
-rw-r-----. unconfined_u:object_r:var_t:s0 /srv/named/etc/named.conf
|
||||
```
|
||||
|
||||
不过,运行中我使用了一个卷选项可以使 Dan Walsh 先生高兴起来,`:Z`。`-v /srv/named/etc/named.conf:/etc/named.conf:Z` 命令的这部分做了两件事情:首先它表示这需要使用一个私有卷的 SELiunx 标记来重新标记;其次它表明以读写挂载。
|
||||
|
||||
启动容器之后:
|
||||
|
||||
```
|
||||
[root@rhel7-host ~]# ls -Z /srv/named/etc/named.conf
|
||||
-rw-r-----. root 25 system_u:object_r:svirt_sandbox_file_t:s0:c821,c956 /srv/named/etc/named.conf
|
||||
```
|
||||
|
||||
- **注2:** **VIM 备份行为能改变 inode**
|
||||
|
||||
如果你在本地主机中使用 `vim` 来编辑配置文件,而你没有看到容器中的改变,你可能不经意的创建了容器感知不到的新文件。在编辑时,有三种 `vim` 设定影响备份副本:`backup`、`writebackup` 和 `backupcopy`。
|
||||
|
||||
我摘录了 RHEL 7 中的来自官方 VIM [backup_table][9] 中的默认配置。
|
||||
|
||||
```
|
||||
backup writebackup
|
||||
off on backup current file, deleted afterwards (default)
|
||||
```
|
||||
所以我们不创建残留下的 `~` 副本,而是创建备份。另外的设定是 `backupcopy`,`auto` 是默认的设置:
|
||||
|
||||
```
|
||||
"yes" make a copy of the file and overwrite the original one
|
||||
"no" rename the file and write a new one
|
||||
"auto" one of the previous, what works best
|
||||
```
|
||||
|
||||
这种组合设定意味着当你编辑一个文件时,除非 `vim` 有理由(请查看文档了解其逻辑),你将会得到一个包含你编辑内容的新文件,当你保存时它会重命名为原先的文件。这意味着这个文件获得了新的 inode。对于大多数情况,这不是问题,但是这里容器的<ruby>绑定挂载<rt>bind mount</rt></ruby>对 inode 的改变很敏感。为了解决这个问题,你需要改变 `backupcopy` 的行为。
|
||||
|
||||
不管是在 `vim` 会话中还是在你的 `.vimrc`中,请添加 `set backupcopy=yes`。这将确保原先的文件被清空并覆写,维持了 inode 不变并且将该改变传递到了容器中。
|
||||
|
||||
------------
|
||||
|
||||
via: http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/
|
||||
|
||||
作者:[Matt Micene][a]
|
||||
译者:[liuxinyu123](https://github.com/liuxinyu123)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/
|
||||
[1]:http://rhelblog.redhat.com/author/mmicenerht/
|
||||
[2]:http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/#repo
|
||||
[3]:http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/#sidebar_1
|
||||
[4]:http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/#sidebar_2
|
||||
[5]:http://redhatstackblog.wordpress.com/feed/
|
||||
[6]:https://access.redhat.com/containers
|
||||
[7]:http://rhelblog.redhat.com/2017/07/19/containing-system-services-in-red-hat-enterprise-linux-part-1/#repo
|
||||
[8]:https://github.com/nzwulfin/named-container
|
||||
[9]:http://vimdoc.sourceforge.net/htmldoc/editing.html#backup-table
|
@ -0,0 +1,251 @@
|
||||
GIT 命令“从初学到专业”完整进阶指南
|
||||
===========
|
||||
|
||||
在[之前的教程][1]中,我们已经学习了在机器上安装 git。本教程,我们将讨论如何使用 git,比如与 git 一起使用的各种命令。所以我们开始吧,
|
||||
|
||||
- 推荐阅读:[如何在 Linux 上安装 GIT (Ubuntu 和 CentOS)][1]
|
||||
|
||||
### 设置用户信息
|
||||
|
||||
这应该是安装完 git 的第一步。我们将添加用户信息 (用户名和邮箱),所以当我们提交代码时,会产生带有用户信息的提交信息,这使得跟踪提交过程变得更容易。要添加用户信息,命令是 `git config`:
|
||||
|
||||
```
|
||||
$ git config --global user.name "Daniel"
|
||||
$ git config --global user.email "dan.mike@xyz.com"
|
||||
```
|
||||
|
||||
添加完用户信息之后,通过运行下面命令,我们将检查这些信息是否成功更新。
|
||||
|
||||
```
|
||||
$ git config --list
|
||||
```
|
||||
|
||||
我们应该能够看到输出的用户信息。
|
||||
|
||||
### GIT 命令
|
||||
#### 新建一个仓库
|
||||
|
||||
为了建立一个新仓库,运行如下命令:
|
||||
|
||||
```
|
||||
$ git init
|
||||
```
|
||||
|
||||
#### 查找一个仓库
|
||||
|
||||
为了查找一个仓库,命令如下:
|
||||
|
||||
```
|
||||
$ git grep "repository"
|
||||
```
|
||||
|
||||
#### 与远程仓库连接
|
||||
|
||||
为了与远程仓库连接,运行如下命令:
|
||||
|
||||
```
|
||||
$ git remote add origin remote_server
|
||||
```
|
||||
|
||||
然后检查所有配置的远程服务器,运行如下命令:
|
||||
|
||||
```
|
||||
$ git remote -v
|
||||
```
|
||||
|
||||
#### 克隆一个仓库
|
||||
|
||||
为了从本地服务器克隆一个仓库,运行如下代码:
|
||||
|
||||
```
|
||||
$ git clone repository_path
|
||||
```
|
||||
|
||||
如果我们想克隆远程服务器上的一个仓库,那克隆这个仓库的命令是:
|
||||
|
||||
```
|
||||
$ git clone repository_path
|
||||
```
|
||||
|
||||
#### 在仓库中列出分支
|
||||
|
||||
为了检查所有可用的和当前工作的分支列表,执行:
|
||||
|
||||
```
|
||||
$ git branch
|
||||
```
|
||||
|
||||
#### 创建新分支
|
||||
|
||||
创建并使用一个新分支,命令是:
|
||||
|
||||
```
|
||||
$ git checkout -b 'branchname'
|
||||
```
|
||||
|
||||
#### 删除一个分支
|
||||
|
||||
为了删除一个分支,执行:
|
||||
|
||||
```
|
||||
$ git branch -d 'branchname'
|
||||
```
|
||||
|
||||
为了删除远程仓库的一个分支,执行:
|
||||
|
||||
```
|
||||
$ git push origin:'branchname'
|
||||
```
|
||||
|
||||
#### 切换到另一个分支
|
||||
|
||||
从当前分支切换到另一个分支,使用
|
||||
|
||||
```
|
||||
$ git checkout 'branchname'
|
||||
```
|
||||
|
||||
#### 添加文件
|
||||
|
||||
添加文件到仓库,执行:
|
||||
|
||||
```
|
||||
$ git add filename
|
||||
```
|
||||
|
||||
#### 文件状态
|
||||
|
||||
检查文件状态 (那些将要提交或者添加的文件),执行:
|
||||
|
||||
```
|
||||
$ git status
|
||||
```
|
||||
|
||||
#### 提交变更
|
||||
|
||||
在我们添加一个文件或者对一个文件作出变更之后,我们通过运行下面命令来提交代码:
|
||||
|
||||
```
|
||||
$ git commit -a
|
||||
```
|
||||
|
||||
提交变更到 head 但不提交到远程仓库,命令是:
|
||||
|
||||
```
|
||||
$ git commit -m "message"
|
||||
```
|
||||
|
||||
#### 推送变更
|
||||
|
||||
推送对该仓库 master 分支所做的变更,运行:
|
||||
|
||||
```
|
||||
$ git push origin master
|
||||
```
|
||||
|
||||
#### 推送分支到仓库
|
||||
|
||||
推送对单一分支做出的变更到远程仓库,运行:
|
||||
|
||||
```
|
||||
$ git push origin 'branchname'
|
||||
```
|
||||
|
||||
推送所有分支到远程仓库,运行:
|
||||
|
||||
```
|
||||
$ git push -all origin
|
||||
```
|
||||
|
||||
#### 合并两个分支
|
||||
|
||||
合并另一个分支到当前活动分支,使用命令:
|
||||
|
||||
```
|
||||
$ git merge 'branchname'
|
||||
```
|
||||
|
||||
#### 从远端服务器合并到本地服务器
|
||||
|
||||
从远端服务器下载/拉取变更到到本地服务器的工作目录,运行:
|
||||
|
||||
```
|
||||
$ git pull
|
||||
```
|
||||
|
||||
#### 检查合并冲突
|
||||
|
||||
查看对库文件的合并冲突,运行:
|
||||
|
||||
```
|
||||
$ git diff -base 'filename'
|
||||
```
|
||||
|
||||
查看所有冲突,运行:
|
||||
|
||||
```
|
||||
$ git diff
|
||||
```
|
||||
|
||||
如果我们在合并之前想预览所有变更,运行:
|
||||
|
||||
```
|
||||
$ git diff 'source-branch' 'target-branch'
|
||||
```
|
||||
|
||||
#### 创建标记
|
||||
|
||||
创建标记来标志任一重要的变更,运行:
|
||||
|
||||
```
|
||||
$ git tag 'tag number' 'commit id'
|
||||
```
|
||||
|
||||
通过运行以下命令,我们可以查找 commit id :
|
||||
|
||||
```
|
||||
$ git log
|
||||
```
|
||||
#### 推送标记
|
||||
|
||||
推送所有创建的标记到远端服务器,运行:
|
||||
|
||||
```
|
||||
$ git push -tags origin
|
||||
```
|
||||
|
||||
#### 回复做出的变更
|
||||
|
||||
如果我们想用 head 中最后一次变更来替换对当前工作树的变更,运行:
|
||||
|
||||
```
|
||||
$ git checkout -'filename'
|
||||
```
|
||||
|
||||
我们也可以从远端服务器获取最新的历史,并且将它指向本地仓库的 master 分支,而不是丢弃掉所有本地所做所有变更。为了这么做,运行:
|
||||
|
||||
```
|
||||
$ git fetch origin
|
||||
$ git reset -hard master
|
||||
```
|
||||
|
||||
好了,伙计们。这些就是我们使用 git 服务器的命令。我们将会很快为大家带来更有趣的教程。如果你希望我们对某个特定话题写一个教程,请通过下面的评论箱告诉我们。像往常一样, 欢迎您的各种意见和建议。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://linuxtechlab.com/beginners-to-pro-guide-for-git-commands/
|
||||
|
||||
作者:[Shusain][a]
|
||||
译者:[liuxinyu123](https://github.com/liuxinyu123)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://linuxtechlab.com/author/shsuain/
|
||||
[1]:http://linuxtechlab.com/install-git-linux-ubuntu-centos/
|
||||
[2]:/cdn-cgi/l/email-protection
|
||||
[3]:http://linuxtechlab.com/scheduling-important-jobs-crontab/
|
||||
[4]:https://www.facebook.com/linuxtechlab/
|
||||
[5]:https://twitter.com/LinuxTechLab
|
||||
[6]:https://plus.google.com/+linuxtechlab
|
||||
[7]:http://linuxtechlab.com/contact-us-2/
|
42
published/201712/20170910 Cool vim feature sessions.md
Normal file
42
published/201712/20170910 Cool vim feature sessions.md
Normal file
@ -0,0 +1,42 @@
|
||||
vim 的酷功能:会话!
|
||||
============================================================
|
||||
|
||||
昨天我在编写我的[vimrc][5]的时候了解到一个很酷的 vim 功能!(主要为了添加 fzf 和 ripgrep 插件)。这是一个内置功能,不需要特别的插件。
|
||||
|
||||
所以我画了一个漫画。
|
||||
|
||||
基本上你可以用下面的命令保存所有你打开的文件和当前的状态
|
||||
|
||||
```
|
||||
:mksession ~/.vim/sessions/foo.vim
|
||||
|
||||
```
|
||||
|
||||
接着用 `:source ~/.vim/sessions/foo.vim` 或者 `vim -S ~/.vim/sessions/foo.vim` 还原会话。非常酷!
|
||||
|
||||
一些 vim 插件给 vim 会话添加了额外的功能:
|
||||
|
||||
* [https://github.com/tpope/vim-obsession][1]
|
||||
* [https://github.com/mhinz/vim-startify][2]
|
||||
* [https://github.com/xolox/vim-session][3]
|
||||
|
||||
这是漫画:
|
||||
|
||||
![](https://jvns.ca/images/vimsessions.png)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://jvns.ca/blog/2017/09/10/vim-sessions/
|
||||
|
||||
作者:[Julia Evans][a]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://jvns.ca/about
|
||||
[1]:https://github.com/tpope/vim-obsession
|
||||
[2]:https://github.com/mhinz/vim-startify
|
||||
[3]:https://github.com/xolox/vim-session
|
||||
[4]:https://jvns.ca/categories/vim
|
||||
[5]:https://github.com/jvns/vimconfig/blob/master/vimrc
|
@ -0,0 +1,75 @@
|
||||
在 Linux 启动或重启时执行命令与脚本
|
||||
======
|
||||
|
||||
有时可能会需要在重启时或者每次系统启动时运行某些命令或者脚本。我们要怎样做呢?本文中我们就对此进行讨论。 我们会用两种方法来描述如何在 CentOS/RHEL 以及 Ubuntu 系统上做到重启或者系统启动时执行命令和脚本。 两种方法都通过了测试。
|
||||
|
||||
### 方法 1 – 使用 rc.local
|
||||
|
||||
这种方法会利用 `/etc/` 中的 `rc.local` 文件来在启动时执行脚本与命令。我们在文件中加上一行来执行脚本,这样每次启动系统时,都会执行该脚本。
|
||||
|
||||
不过我们首先需要为 `/etc/rc.local` 添加执行权限,
|
||||
|
||||
```
|
||||
$ sudo chmod +x /etc/rc.local
|
||||
```
|
||||
|
||||
然后将要执行的脚本加入其中:
|
||||
|
||||
```
|
||||
$ sudo vi /etc/rc.local
|
||||
```
|
||||
|
||||
在文件最后加上:
|
||||
|
||||
```
|
||||
sh /root/script.sh &
|
||||
```
|
||||
|
||||
然后保存文件并退出。使用 `rc.local` 文件来执行命令也是一样的,但是一定要记得填写命令的完整路径。 想知道命令的完整路径可以运行:
|
||||
|
||||
```
|
||||
$ which command
|
||||
```
|
||||
|
||||
比如:
|
||||
|
||||
```
|
||||
$ which shutter
|
||||
/usr/bin/shutter
|
||||
```
|
||||
|
||||
如果是 CentOS,我们修改的是文件 `/etc/rc.d/rc.local` 而不是 `/etc/rc.local`。 不过我们也需要先为该文件添加可执行权限。
|
||||
|
||||
注意:- 启动时执行的脚本,请一定保证是以 `exit 0` 结尾的。
|
||||
|
||||
### 方法 2 – 使用 Crontab
|
||||
|
||||
该方法最简单了。我们创建一个 cron 任务,这个任务在系统启动后等待 90 秒,然后执行命令和脚本。
|
||||
|
||||
要创建 cron 任务,打开终端并执行
|
||||
|
||||
```
|
||||
$ crontab -e
|
||||
```
|
||||
|
||||
然后输入下行内容,
|
||||
|
||||
```
|
||||
@reboot ( sleep 90 ; sh \location\script.sh )
|
||||
```
|
||||
|
||||
这里 `\location\script.sh` 就是待执行脚本的地址。
|
||||
|
||||
我们的文章至此就完了。如有疑问,欢迎留言。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: http://linuxtechlab.com/executing-commands-scripts-at-reboot/
|
||||
|
||||
作者:[Shusain][a]
|
||||
译者:[lujun9972](https://github.com/lujun9972)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:http://linuxtechlab.com/author/shsuain/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user