Most of computer fonts people using are TrueType fonts. TrueType fonts end with .ttf
, which stand for TrueType Font. This tutorial shows how to install TrueType fonts in Linux (Debian, Ubuntu, Linux Mint, etc).
Linux 下默认安装的字体都被存放在 /usr/share/fonts
下。
如果是个人使用可以将字体文件拷贝到 ~/.fonts
目录中。所有支持的字体文件路径可以通过系统的 /etc/fonts/fonts.conf
文件查看到。
把字体文件拷贝到对应的目录之后,需要执行
# create an index of scalable font files for X
mkfontscale
# create an index of X font files in a directory
mkfontdir
fc-cache -fv
使用如下命令来查看已安装字体:
fc-list
# 查看中文字体
fc-list :lang=zh
All of the TrueType fonts are under /usr/share/fonts/truetype
, simplest way is to copy ttf file to this directory and give it the right permission. For example, if you want to install Ubuntu font family manually. You can download the font file from official site.
In the terminal, download the package:
wget http://font.ubuntu.com/download/ubuntu-font-family-0.80.zip
unzip the file into directory ubuntu-font-family-0.80
unzip ubuntu-font-family-0.80.zip
and then use copy command to copy all the files to /usr/share/fonts/truetype
,/usr/share/fonts
directory and sub directory need root to write, so you should add sudo
before command. The -r
paramater represent recursive, it means all the files under ubuntu-font-family-0.80 will be copied to the right place.
sudo cp -r ubuntu-font-family-0.80/ /usr/share/fonts/truetype/
finally, you shoulde give this directory and all the ttf under this directory right permission. All the new fonts now can only be used by root. We need to change the permission to let all the users to use these fonts:
sudo chmod 755 /usr/share/fonts/truetype/ubuntu-font-family-0.80/ -R
then, refresh the font cache to let system detect these fonts:
fc-cache -f -v
As I mentioned in the first part, if you copy the ttf file to /usr/share/fonts
directory, all the users can use these new fonts. But if you only want to provide these fonts to specific user, like current login user , you can just copy the file to ~/.fonts
directory. If there is no such directory, just create it. The ~ stand for current user’s home directory, full path is /home/<username>
. So repeat the operation to install Ubuntu font family:
mkdir ~/.fonts
cp -r ubuntu-font-family-0.80/ ~/.fonts/
fc-cache -fv
Microsoft Core Fonts include these fonts:
Debian/Ubuntn/Linux Mint user just open terminal and run these command:
sudo apt-get install ttf-mscorefonts-installer
or Linux Mint user can find this package in the Software Manager, just search it and click install.
.ttf
files are the English fonts, while .TTF files are Chinese fonts. If we check the C:\Windows\Fonts
under Microsoft Windows, there are 3 kind of fonts. One is the .fon
fonts, which is the DOS system font, and other two fonts are .ttf
and .TTF
. We can just make a copy of all .ttf
and .TTF
file and copy all the files to /usr/share/fonts/
directory under Linux. Although it is illegal under Microsoft’s TOC, but we can still do it. :)
If you dual boot your computer, mount the Windows and copy the files
sudo mkdir /usr/share/fonts/truetype/WindowsFonts
sudo cp -r /media/Windows/Fonts/*.ttf /usr/share/fonts/truetype/WindowsFonts/
sudo cp -r /media/Windows/Fonts/*.TTF /usr/share/fonts/truetype/WindowsFonts/
Install open source Chinese fonts, like 文泉驿 - 微米黑 文泉驿 - 正黑
sudo apt-get install ttf-wqy-microhei ttf-wqy-zenhei
several Chinese font we can choose:
To check more about Chinese font visit Arch wiki
Linux Mint user can find a font manager under Software Manager. It is really a cool tool to manager your fonts.
fc-list
is a quick and handy command to lists fonts and styles available on the system for applications using fontconfig. You can use fc-list to find out whether particular language font is installed or not.
To list all font faces:
$ fc-list
To lists font faces that cover Chinese language:
$ fc-list :lang=zh
Output will be all available Chinese fonts.
After I installed WPS for Linux under Linux Mint 17.2, I met this problem, “系统缺失字体 symbol、wingdings、wingdings 2、wingdings 3、wedding”. According to the copyright, WPS for Linux doesn’t contains these five fonts. You can only find these five fonts and install them in the right place like I said before. One way to find these fonts is to find them in Microsoft Windows system. And another way is to download these files from Internet and install.
Use following command to search Korean font
apt-cache search korean font
and use this command to install Korean font to linux:
sudo apt-get install fonts-unfonts-core fonts-unfonts-extra
字体类型:
Sans-serif
无衬线体 = 黑体:并不是具体一款字体,而是一类字体,选择它其实等于选择这类字体中优先级最高的那款字体。Serif
衬线体 = 白体:同上Monospace
等宽字体,意思是字符宽度相同:同上点阵字体
位图字体无衬线体更适合电脑屏幕阅读,衬线体适合打印。因为衬线可以使得人视线平齐于一行。也就是说不会读破行。
中文显示时有不同的方式,一方面因为中文本身拥有的横和同高度就可以导致这种平齐。行距对中文更重要。
For more information check Debian page Arch wiki and Ubuntu wiki
之前做过一个简单的 git 的介绍,下面是 PPT 的摘录。
Git is a free and open source distributed version control system(VCS) designed to handle everything from small to very large projects with speed and efficiency.
Git 是一个分散式版本控制软件,最初由林纳斯·托瓦兹(Linus Torvalds)创作,于 2005 年以 GPL 发布。最初目的是为更好地管理 Linux 内核开发而设计。Linus Torvalds 自嘲的取名“git”,该词源自英国俚语,意思大约是“混账 1”。
Microsoft Word 如果你用 Microsoft Word 写过长篇大论,那你一定有这样的经历:
想删除一个段落,又怕将来想恢复找不回来怎么办?有办法,先把当前文件“另存为……”一个新的 Word 文件,再接着改,改到一定程度,再“另存为……”一个新文件,这样一直改下去,最后你的 Word 文档变成了这样:
Wikis
https://zh.wikipedia.org/w/index.php?title=Git&action=history
Undo Windows: Ctrl+z Mac: Command+z
Version control has a very long histroy.
BitKeeper SCM
Git is born
Git become popular, GitHub launched in 2008 to host Git repositories:
Git 是一种分布式版本控制,不需要服务器端软件也可运行
anyone wanting to track edits
anyone needing to share changes with collaborators
anyone not afraid of command-line tools
需要注意以下几点:
只能跟踪文本文件的改动,二进制文件不行,也就是说 如果使用 Git 追踪 Word ,版本控制系统并不知道改动了那些行,只能知道二进制变化了。
programmer
not as useful for tracking non-text files
编码问题,如果在多平台使用请千万使用 UTF-8 编码
使用 Windows 的童鞋要特别注意: 千万不要使用 Windows 自带的记事本编辑任何⽂文本⽂文件。原因是 Microsoft 开发记事本的团 队使⽤用了⼀一 个非常弱智的⾏行为来保存 UTF-8 编码的⽂文件,他们⾃自作聪明地在每个⽂文件开头添 加了 0xefbbbf(⼗十六进制)的字符,你会遇到很多不可思议的问题,比 如,网页第一⾏行可 能会显⽰示⼀一个“?”,明明正确的程序⼀一编译就报语法错误,等等,都是由记事本的弱智⾏行 为带来的。建议你下载 Notepad++ 代替记事本,不但功能强⼤大,而且免费!记得把 Notepad++ 的默认编码设置为 UTF-8 without BOM 即可
sudo apt-get install git
or sudo yum install git
brew install git
在开始使用 Git 之前有些配置
git config --global user.name "John Doe" # 配置提交用户名
git config --global user.email johndoe@example.com # 配置提交邮箱
git init
git status
git add filename
# 暂存区
git commit -m “"
git log
commit message best practices
git branch <branchname>
git checkout <branchname>
git checkout -b <branchname>
git push origin <branchname>
git push origin --delete <branchname>
http://nvie.com/posts/a-successful-git-branching-model/
git remote add origin git@blcu.tk:einverne/gitdemo.git
git push -u origin master
git remote show origin
git tag # list all tags
git tag v0.9
git tag -a v1.0 -m “my version 1.0"
git show tag name #show tag details
git push origin tag name
git push origin --tags
https://github.com/github/gitignore
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
http://server.address
http://git.or.cz/gitwiki/GitFaq#head-90fa13ebe170116f1586156e73b549cc2135b784 ↩
注意如果使用 Java SE 8 及以上,建议使用 java.time
(JSR-210) 来代替使用 Joda-time。
Java 中日期,时间处理类库 Joda time
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.2</version>
</dependency>
最新的版本官网查看 1
5 个最常用的 date-time 类:
表示时刻,瞬时的时间
表示时间间隔,是一个半开区间,包括开始时刻,但不包括结束时刻。结束时刻永远要大于或者等于开始时刻。有两个实现 Interval 和 MutableInterval
表示持续时间,用 milliseconds 表示,duration 通常从 interval 中获取。
instant + duration = instant
一段时间,通常比如三年五个月两天 7 小时。他和 Duration 的区别在于,Period 是不精确的(在 milliseconds 级别)。比如有一个月的时间段,那么在二月一号加上一个月会得到三月一号,而在三月一号加上一个月,会得到四月一号,但是这两个 duration(in milliseconds)是完全不一样的。
instant + period = instant
有两个实现 Period 和 MutablePeriod
有很多构造方法
DateTime dateTime1 = new DateTime();
DateTime dateTime2 = new DateTime(2015,11,11,0,0,0);
DateTime dateTime3 = new DateTime(1447171200000L);
DateTime dateTime4 = new DateTime(new Date());
DateTime dateTime5 = new DateTime("2015-11-11T00:00:00.000+08:00");
Joda Time 中的 LocalTime 表示的是一个没有日期的时间
常用方法
LocalTime.now()
Joda-Time 为时间段的表示提供了支持。
因为 Joda Time 非常稳定可靠,在 JDK 8 以前成为了 Java 处理时间相关的事实标准,JDK 8 中引入了 java.time
等一组新 api 用来处理时间日期,遵守 JSR 310,弥补了 Java 在时间处理方面的不足。Joda-Time 的作者 Stephen Colebourne 和 Oracle 一起共同参与了这些 API 的设计和实现。
JDK 8 以前 Date 和 Calendar 类存在的问题:
相关类:
基本上他们的接口定义都是 ofXX 来构造一个实例,而通过 parseXX 来将一个现有的时间戳转变成对应的实例。
https://mvnrepository.com/artifact/joda-time/joda-time ↩
wget 是一个非常常用的下载命令,但其实 wget 非常强大,这里就列举一些很常用的选项。
备份或者下载整站:
wget -r -np http://www.mysite.com/Pictures/
wget -r --no-parent --reject "index.html*" http://www.mysite.com/Pictures/
说明:
-r
表示 recursively 递归下载-np
或者 --no-parent
表示不延伸到父目录,当想要下载特定目录下的文件时,记得加上这个选项当然如果你的目的非常单纯只是想备份网站,之前也写过一篇 Httrack 备份全站 的文章。
使用 -A
或者 -R
wget -A jpg,pdf http://site
wget --accept jpg,pdf http://site
wget -R "index.html" http://site
说明:
-A
或者 --accept
后面接逗号分割的后缀或者模式,表示下载接受的文件格式,或者符合正则表达式的内容-R
或者 --reject
表示不下载匹配的需要注意的是如果书写正则表达式,那么需要用双引号。
在使用 wget 备份网站目录时可能遇到网站路径编码下载到本地之后乱码的情况,这个时候需要使用 --restrict-file-names=nocontrol
有些时候可能要离线文档用来在本地浏览,这个时候需要用到 -k
wget --mirror --convert-links --adjust-extension --page-requisites
--no-parent http://example.org
wget -mkEpnp http://example.org
说明:
-m
或者 --mirror
镜像网站,这个选项会开启递归和时间戳,并且保持目录结构,等效于 -r -N -l inf --no-remove-listing
-k
或者 --convert-links
表示将连接转成 localhost,方便本地浏览-E
或者 --adjust-extension
表示会根据文件的 MIME 类型,将一些文件调整为 HTML 等等后缀,方便在不同的 WEB 服务器中托管-p
或者 --page-requisites
会将任何 HTML 页面显示需要的资源都下载下来,包括 images,sounds,css,js 等等wget 使用选项 --limit-rate
来限制速度:
wget --limit-rate=423k
单位是 bytes per second,如果要表示 kiloBytes,在结尾加上 k
.
使用 --tries=70
来自定义重试次数,默认情况下 wget 会重试 20 次。
接触韩国电影并不是很长时间,而之前在我看过的电影中推荐过《10部不得不看的韩国电影》,这之后通过周围的推荐和影评,渐渐的看到了更多的韩国电影。《追击者》《太极旗飘扬》《汉江怪物》,这些都是非常不错的片子,可惜当时并不知道。而这部《太极旗飘扬》终于在昨天看完了。
如何去定义这部电影呢?战争片,历史片,影片主要讲述朝鲜战争,也就是韩国说的6.25战争,兄弟俩被强制征兵到前线抵抗北朝鲜的进攻,而哥哥为了保护弟弟屡次铤而走险,完成战功,获得勋章,而过程中哥哥却变的残暴。故事中的哥哥多次的反转,或许这里真的要称赞一下电影的编剧,从来没想到故事的发展会如此的曲折,而最后终也能将电影所要衬托出的主题凸显出—-这是一部彻彻底底的反战电影—-就像之前看的一篇影评中所说,历史上的朝鲜战争,在世界各国的书本中都描述成中国,前苏联和美国的势力角逐。而这部电影让我们看到韩国人对这次战争的思考,当世界两大力量在小小的朝鲜半岛展开时,血腥,暴力是无法想象的,而导演也同样没有回避,用大量的镜头描写战争场面的残酷。
作为一个中国人来看,或许很多人的印象中都是“雄赳赳气昂昂,踏过鸭绿江”,我们的教科书,我们的老师,我们的教育从来没有教育我们战争对于人类来说是什么。多少次观影的过程中,我希望中国从来没有参战,没有之后的更加疯狂的杀戮,也同样不会有那些年战死的中国志愿军。而历史就是历史,一直知道中国会参战,而当韩国军队获得胜利朝鸭绿江挺近的时候,我依然会和主人公一样的开心。这是一部很长的电影,长得让人难受的电影,导演用镜头诉说着那段历史,一个个的反转让人思考。
其中最大的反转就是哥哥这个角色,最开始哥哥弟弟并不愿意参战,而后来哥哥为了弟弟变得疯狂,看到北朝鲜屠杀村民,哥哥变得嗜血,屠戮战俘,哥哥甚至为了功勋而忘记了初心,勋章荣誉让哥哥沉迷其中,成为战争英雄。而之后哥哥看到自己的未婚妻因为战时投奔共产党讨得一点饭吃而被韩国同胞处死,而自己的弟弟被关在仓库烧死(哥哥并不知道弟弟侥幸逃走),从而变得更加疯狂,被北朝鲜俘虏之后成为了北朝鲜的主力“大旗部队”,哥哥的一生,为自己的弟弟,为自己的国家战斗过,也为北朝鲜战斗过,他甚至并不知道为什么要打来打去,莫名其妙的被拉上战场,而之后的一切都被动的产生了。导演很聪明,没有直接明了的说道理,去站在上帝的视角去评价这场战争,同样也很聪明的屏蔽了外界的一切的干扰,中国志愿军只出现了一幕,而美国军队的登陆也只是在收音机中出现,所有的镜头都是正面的战场,保留了观众对这场战争的评价,是非曲直,看完的观众心中自有一个定论。
而弟弟的表现则告诉我们,一个人保留有一丝的人性是多么的重要,即使战争再残酷,人作为人最基本的人性应该保存着,这也就是他即使再忙也会跑到家里去看望自己的母亲和嫂嫂,这也就是他即使所有人都认为那个投降朝鲜的天真擦皮鞋的老乡该杀的时候他会跑出来保护他,这也就是他即使知道前线的危险也会再跑到战场去寻找他的哥哥的原因。人作为人,是应该像哥哥那样,还是像弟弟那样?就像电影中弟弟告诉他哥哥的那样,“如果把那些战俘都杀死,那我们和那些北朝鲜的人又有什么两样?”。
很多人提到这部片子会想到另外一部战争大片《拯救大兵瑞恩》,有的时候我真的会问自己,“为了一个人,又牺牲了那么多的人,真的值得吗?”,我的回答肯定是“值!”,因为这里面就包含着人对生命的尊敬,对战争的敬畏,我相信看完这些电影的人一定是反战的,战争是反人类的。说到底战争只是政府政治斗争的一枚棋子,而受到伤害的永远都是社会底层的平民。
PS.
写完本来是要分享到豆瓣的,只是又不过审了。
Bash 的前身 shell 是 Unix 系统下的命令行解释器,主要用于用户和系统交互。 Unix 系统上有很多 Shell,首个 Shell,Bourne Shell,1978 年推出,后来又演变出 C Shell,Bash 等不同版本的 Shell。
Bash 全称为 Bourne-Again Shell,是一个为 GNU 项目编写的的 Unix Shell。Bash 脚本功能强大,尤其是在处理循环或者批量任务时。Bash 是大多数 Linux 平台默认的 Shell,所以学好 Bash 是基础。
首选来看一下 Bash 的版本,输入下面命令
echo $BASH_VERSION
可以使用 set -o | egrep -w "(vi|emacs)"
命令查看,当前命令行编辑模式。
$ set -o vi
$ set -o|egrep -w "(vi|emacs)"
emacs off
vi on
All the above assume that bash is running in the default Emacs setting, if you prefer this can be switched to Vi shortcuts instead.
Set Vi Mode in bash:
$ set -o vi
Set Emacs Mode in bash:
$ set -o emacs
using set -o
to check all the bash options.
Bash Keyboard Shortcuts 在绝大多数情况下一下快捷键可以直接使用
在终端移动快捷键,下面几个快捷键在命令行中非常有用,尤其是当命令比较长时,在行前,行末快速切换能够提高不少效率。而如果要修改命令行中间内容,这时候组合使用 alt ctrl 和 b f 则能够快速定位到中间修改的内容,再进行修改。
Command | Explain |
---|---|
Ctrl + a | 移动到命令最前 Go to the beginning of the line (Home) |
Ctrl + e | 移动到行尾 Go to the End of the line (End) |
Ctrl + p | 上一个命令 Previous command (Up arrow) |
Ctrl + n | 下一个命令 Next command (Down arrow) |
Alt + b | 不删除命令的情况下,向前移动一个单词 Back (left) one word |
Alt + f | 向后一个单词 Forward (right) one word |
Ctrl + b | 光标向前移动一个字符 Backward |
Ctrl + f | 光标向后移动一个字符 Forward |
Ctrl + xx | 在行首和当前光标的位置来回切换 Toggle between the start of line and current cursor position |
Ctrl-b
和 Ctrl-f
这两个快捷键是我经常容易忘记的两个,但是有的时候又要比左右方向键要方便很多,所以还是要记一下的。
编辑相关的快捷键,对我而言 Ctrl + w 是一个非常常用的快捷键,当输入发生错误时,直接快速删除前一个单词再进行修正。
Command | Explain |
---|---|
Ctrl + L | Clear the Screen, similar to the clear command |
Alt + Del | Delete the Word before the cursor. |
Alt + d | Delete the Word after the cursor. |
Ctrl + d | Delete character under the cursor |
Ctrl + h | Delete character before the cursor (Backspace) |
Ctrl + w | Cut the Word before the cursor to the clipboard. 一般用来快速删除前一个单词,也可以用 Alt + Backspace |
Ctrl + k | Cut the Line after the cursor to the clipboard. 将光标后面的内容剪切 |
Ctrl + u | Cut/delete the Line before the cursor to the clipboard. 一般用来快速清除当前输入命令 |
Alt + t | Swap current word with previous |
Ctrl + t | Swap the last two characters before the cursor (typo). |
Esc + t | Swap the last two words before the cursor. |
Ctrl + y | Paste the last thing to be cut (yank) |
Alt + u | UPPER capitalize every character from the cursor to the end of the current word. |
Alt + l | Lower the case of every character from the cursor to the end of the current word. |
Alt + c | Capitalize the character under the cursor and move to the end of the word. |
Alt + r | Cancel the changes and put back the line as it was in the history (revert). |
Ctrl + _ | Undo |
TAB | Tab completion for file/directory names |
For example, to move to a directory ‘sample1’; Type cd sam ; then press TAB and ENTER. type just enough characters to uniquely identify the directory you wish to open.
查询 bash 命令历史,快速执行历史命令
Command | Explain |
---|---|
Ctrl + r | Recall the last command including the specified character(s) searches the command history as you type. Equivalent to : vim ~/.bash_history. |
Ctrl + p | Previous command in history (i.e. walk back through the command history) |
Ctrl + n | Next command in history (i.e. walk forward through the command history) |
Ctrl + s | Go back to the next most recent command. (beware to not execute it from a terminal because this will also launch its XOFF). |
Ctrl + o | Execute the command found via Ctrl+r or Ctrl+s |
Ctrl + g | Escape from history searching mode |
!! | Repeat last command |
!abc | Run last command starting with abc |
!abc:p | Print last command starting with abc |
!$ | Last argument of previous command |
ALT + . | Last argument of previous command |
!* | All arguments of previous command |
^abc^def | Run previous command, replacing abc with def |
下面几个命令可以控制命令行中正在执行的进程,包括中止进程,放置进程到后台,唤起进程等等。
Command | Explain |
---|---|
Ctrl + C | Interrupt/Kill whatever you are running (SIGINT) |
Ctrl + s | Stop output to the screen (for long running verbose commands) |
Then use PgUp/PgDn for navigation | |
Ctrl + q | Allow output to the screen (if previously stopped using command above) |
Ctrl + D | 退出当前 Shell Send an EOF marker, unless disabled by an option, this will close the current shell (EXIT) |
Ctrl + Z | Send the signal SIGTSTP to the current task, which suspends it. To return to it later enter fg ‘process name’ (foreground). |
最常使用的应该还是 Ctrl-a
, Ctrl-e
, Ctrl-f
, Ctrl-b
, Ctrl-l
, Ctrl-h
, Ctrl-w
, Ctrl-k
, Ctrl-u
, Ctrl-y
, Ctrl-r
.
命令 | 说明 |
---|---|
Ctrl-B | 后移一个字符 |
Ctrl-F | 向前移动一个字符 |
DEL | 向后删除一个字符 |
Ctrl-D | 向前删除一个字符 |
Ctrl-A | 移到行首 |
Ctrl-E | 移到行尾 |
Ctrl-K | 向前删除到行尾 |
Ctrl-P | 移到前一行 |
Ctrl-N | 移到后一行 |
Ctrl-R | 向后搜索 |
Ctrl-J | 等同于 RETURN |
Ctrl-L | 清除屏幕,将当前行放到屏幕最上面 |
Ctrl-M | 等同于 RETURN |
Ctrl-O | 等同于 RETURN 随后在显示历史命令中下一行 |
Ctrl-T | 颠倒光标左右两个字符,将光标向前移一个 |
Ctrl-U | 从光标位置开始删除行 ,向后删除到行首 |
Ctrl-V | 引用插入 |
通过设置 set -o vi
进入 Vi 编辑模式,正常环境为输入模式,对命令进行修改则按 Esc。完整命令参考.
命令包括 h, l, w, b 等等 Vi 中使用的命令,可参考另外一篇 Vim 学习笔记。
Esc
, Ctrl+l(L lower case)
,clear screen。最重要的 Bash 文件是 .bash_profile
,它在每次用户登陆系统时被读取 /etc/profile
。Bash 允许有 .bash_profile
两个同义文件, C Shell 的 .bash_login
以及 Bourne Shell 和 Korn Shell 的 .profile
。登录时三者中只有一个被读取,如果用户根目录下 .bash_profile
不存在,则 bash 依次查找 .bash_login
, .profile
.
.bash_profile
只被登录 shell 读取并执行,如果通过命令键入 Bash 启动一个新 Shell, 它就会读取 bashrc 中的命令。
.bash_logout
在每次 shell 退出时被读取并执行。
可以使用 source ~/.bashrc
来使配置文件立即生效。
修改 .bashrc
文件可以精确到对当前用户有效。修改 /etc/profile
对全局用户生效。
给命令添加熟悉的别名
alias name=command
指定 name 是 command 的别名。在“=”两边没有空格,严格语法。
别名是可递归的,可以使用别名定义另外的别名。
别名可以为命令创建方便的名字,它们实际上并不改变 shell 的行为。选项则不然。基本命令:
set -o optionname - 号 开启
set +o optionname + 号 关闭
检查 bash 所有可选项,使用 set -o
打印所有列表。
shopt 选项
选项 | 含义 |
---|---|
-p | 显示可选设置及其当前取值 |
-s | 设置 |
-u | 失效 |
-o | 允许选项名取值通过 set 命令 -o 选项定义 |
列表选项如下:
allexport off
braceexpand on
emacs off
errexit off
errtrace off
functrace off
hashall on
histexpand on
history on
ignoreeof off
interactive-comments on
keyword off
monitor on
noclobber on
noexec off
noglob off
nolog off
notify off
nounset off
onecmd off
physical off
pipefail off
posix off
privileged off
verbose off
vi on
xtrace off
选项 | 解释 |
---|---|
emacs | emacs 编辑模式 |
vi | vi 编辑模式 |
ignoreeof | 不允许单独使用 Ctrl-D 退出 |
noclobber | 不允许输出重定向(>)覆盖已存在的文件 |
noglob | 不允许扩展文件名通配符如* 和 ? |
nounset | 试图使用未定义变量时给出错误 |
Shell 变量也是一个拥有取值的名字,bash 有一些内置的变量,shell 编程也可以自定义变量。按照惯例,内置变量名均为大写,当然也有两个例外。
varname=value
等号两边必须没有空格。
引用变量,使用符号 $
, 单引号内部的变量会直接使用而不需要转义,而双引号内部变量需要转义。
echo $varname
bash 有很多内置变量分布在各个配置文件中。
PATH 变量,帮助 shell 找到输入的命令。输入 echo $PATH
得到类似:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
变量 | 含义 |
---|---|
HOME | 主目录 |
SECONDS | 调用 shell 的秒数 |
BASH | 正在运行的 shell 实例路径名 |
BASH_VERSION | shell 版本号 |
BASH_VERSINFO | shell 版本信息数组 |
PWD | 当前目录 |
OLDPWD | 最后一个 cd 命令前的目录 |
Linux 是一个多用户、多任务的操作系统,所以为了运行这样一套系统,必须要有一套用户管理系统。
root 用户是所有类 Unix 系统中的超级管理员,UID 是 0。
类似如下:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
7 个部分:
/etc/shadow
目录中UID 是不能有冲突的,并且普通用户必须从 1000 开始,即使前面有空缺。
加密的密码
9 个部分:
useradd
命令可以用来新增用户
root@linux ~# useradd username
可以通过 id username
来查看用户的具体资料。
新增用户模板
GROUP=100 #默认用户组 HOME=/home #默认 Home 目录 INACTIVE=-1 # /etc/shadow 内第 7 栏 EXPIRE= # /etc/shadow 内第 8 栏 SHELL=/bin/bash #默认 shell SKEL=/etc/skel #home 目录内容数据参考
新增用户 home 目录参考
设置密码,直接 passwd
则是修改自己密码
root@Linux ~# passwd username
调整用户帐户信息
比如将用户 einverne 加入 docker 组:
sudo usermod -aG docker einverne
记住这里的 -a
是非常重要的,是 append 附加到最后的意思,如果不加则会把历史的全部清空。
删除用户
root@linux /# userdel [-r] username
-r
连同 home 目录一起删除
为了管理一组用户,Linux 系统中有组概念,通过用户组 GID, 来区别。
类似
root:x:0:root
daemon:x:1:root,bin,daemon
bin:x:2:root,bin,daemon
sys:x:3:root,bin,adm
4 部分:
查看以 einverne 用户身份登录,支持的用户组命令:
pi@linux / $ groups
pi adm dialout cdrom sudo audio video plugdev games users netdev gpio i2c spi input
使用命令 newgrp groupname
切换有效用户
groups einverne
类似:
root:::root
4 个字段:
命令:
root@linux ~# groupadd groupname
调整 group 相关参数
root@linux ~# groupmod -g 103 -n groupname groupothername
删除用户组
root@linux ~# groupdel groupname
/etc/sudoers
文件,建议使用 visudo
编辑该文件
格式:用户帐号 登录主机 = (可变换的身份) 可执行的命令
用户
einverne ALL = (ALL) ALL
用户组内
%groupname ALL = (ALL) ALL
不需要密码
%groupname ALL = (ALL) NOPASSWD: ALL
change file group
chgrp users dirname/filename [-R]
chown change file owner
chown root:root filename
change file property, SUID
number
r:4
w:2
x:1
chmod [-R] xyz filename/dir
符号
加入 - 除去 = 设置 u user g group o others a all
通过 Ubuntu 内置的 compgen
打印系统中所有的用户及组织。
compgen -u
compgen -g
Java 容器是 JDK 为 Java 使用者设计好的一套基础的数据结构。
Collection 是接口,包含 List 、Set 和 Queue。List 有序,Set 无序不允许重复元素。
其中 LinkedList 实现了 List 和 Queue 接口。
另外一个重要的接口是 Map,实现有 HashMap,TreeMap。
List 接口下主要实现
动态数组实现,继承 AbstractList 实现了 List,RandomAccess,Cloneable, Serializable 等接口。
线程不安全,多线程使用 Vector 或者 CopyOnWriterArrayList
源码解读 基于 jdk 1.8
int newCapacity = oldCapacity + (oldCapacity >> 1);
.clone()
方法来创建全新 ArrayListLinkedList 双向链表,继承自 AbstractSequentialList
,可以被当做堆栈,队列,双端队列,实现了 List,Deque,Cloneable,Serializable 等接口。
非线程安全
源码解读 jdk 1.8
Vector 继承 AbstractList,实现了 RandomAccess,Cloneable, Serializable 接口,是一个列表。
线程安全。效率较低。
Vector 的线程安全使用过 synchronized 关键字来实现的,比如说
public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true; }
队列「先进先出」
Map 是一个键值对映射接口,Map 不能包含重复键。
HashMap 继承自 AbstractMap 实现了 Map<K,V>
, Cloneable, Serializable 接口。线程不安全。
HashMap 类有两个参数影响其性能:“初始容量” 和 “加载因子”。容量是哈希表中桶的数量,初始容量 只是哈希表在创建时的容量。加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。
HashMap 中 key-value 的值都存在 Entry 的数组中 (Java 8 中 Node 结构)。
transient Node<K,V>[] table;
说到 HashMap,都知道 Java 中每一个 Object 都有一个 hashCode() 方法,该方法返回一个 int 值,相同的对象必须返回相同的 hash Code(不同的对象不一定要求返回不同的值). 在 HashMap 中 hashCode() 方法首先被用来计算 bucket 然后计算 index。
Buckets 是 HashMap 中的一个数组元素,它用来保存节点,节点可能有相同的 bucket。Buckets 的容量是不同的,bucket 的容量大致:
capacity = number of buckets * load factor
单一的一个 bucket 可以拥有超过一个 nodes,hashCode() 方法越好,那么 bucket 会利用的更好。
HashCode 会产生一组 int 数值,如果我们创建一个这个范围的数组,极有可能造成 outOfMemoryException。所以需要知道产生数组的一个最小大小:
index = hashCode(key) & (n-1)
n 是 bucket 的数值。
重要的成员变量:
Entry[]
数组,单向链表在上面的描述中,我们知道如果发生 hash 冲突,所有的节点都保存在一个 linked-list 中,那么最坏的时间复杂度可能是 O(n).
为了解决这个问题,Java 8 中 hash 元素当达到一个阈值之后使用了 balanced trees 而不是 linked list. 这意味着 HashMap 在达到一定数量之后将 Entry 对象转而存储到 balanced tree 中,而最坏的时间复杂度从 O(n) 降至 O(log n)
Java 8 中的 hash() 方法:
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
为了解决哈希碰撞,将 put 到 HashMap 的 key 的 hashCode() 高位和地位综合考虑,在计算时亦或一下高低位(高 16 位异或低 16 位)。
Hashtable 继承 Dictionary,实现 Map, Cloneable, Serializable 接口。Hashtable 函数都是同步的,线程安全的,key 和 value 都不能为 null。
Hashtable 和 HashMap 一样,也是通过“拉链法”来实现的。
TreeMap 是一个有序的 key-value 集合,顺序通过 key 排列,通过红黑树实现
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable
内部根据 key 的自然顺序排序,或者根据创建时提供的 Comparator 排序。基本操作包括 containsKey, get, put, remove 的时间复杂度是 log(n).
TreeMap 不是线程安全的。
内部 Entry 结构包含红黑树节点的 6 个组成部分
static final class Entry<K,V> implements Map.Entry<K,V> {
K key;
V value;
Entry<K,V> left;
Entry<K,V> right;
Entry<K,V> parent;
boolean color = BLACK;
[[WeakHashMap]] 是弱键,当某个键不再正常使用时会被从 WeakHashMap 中自动移除。准确的来说,对于一个给定的键,并不能阻止垃圾回收器对该键的回收。
WeakHashMap 的 key 是弱键,通过 WeakReference 类型实现。
ReferenceQueue 是一个队列,保存被 GC 回收的弱键。
WeakHashMap 是不同步的,可以使用 Collections.synchronizedMap 来构造同步的 WeakHashMap。
在理解 WeakHashMap 之前首先要知道 Java 中的几种引用,Strong,Soft,和 Weak 引用。
强引用
Integer one = 1;
GC 不会随意回收强引用
软引用
Integer prime = 1;
SoftReference<Integer> soft = new SoftReference<Integer>(prime);
prime = null;
GC 只有在 JVM 及需内存时才会回收软引用
弱引用
Integer prime = 1;
WeakReference<Integer> soft = new WeakReference<Integer>(prime);
prime = null;
GC 会频繁的回收弱引用内存,即使不是极其需要内存也会进行回收。
WeakHashMap 中就是用了 WeakReference 类型。
比如某些情况下需要在 value 中保存极大的内容,比如图片内容,那么会消耗极大的内存,而如果使用普通 HashMap 那么这些图片的内容不会轻易释放,这个时候就使用 WeakHashMap 比较合适。
hash 函数的目的是为了让 key 的 hash 尽量均匀的分布到 bucket 中
final int hash(Object k) {
int h = k.hashCode();
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
Set 的实现类基于 Map 实现
没有重复元素的集合,由 HashMap 实现,不保证顺序,允许使用 null。非同步。
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
有序 Set 集合,基于 TreeMap 实现,二叉树实现,非同步的
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable {
枚举类和迭代器,都能用来变量集合,他们都是接口
public interface Enumeration<E> {
boolean hasMoreElements();
E nextElement();
}
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
Enumeration 只能够读取集合数据,不能修改;而 Iterator 能够删除
Iterator 支持 fail-fast 机制(多个线程对集合内容操作),而 Enumeration 不支持。
Comparable 是排序接口,一个类如果实现了 Comparable 接口,意味着该类支持排序。
public interface Comparable<T> {
public int compareTo(T o);
}
通过 x.compareTo(y) 函数比较 x, y 大小,返回负数则 x < y
, 返回 0 则 x=y
,返回正数则 x>y
Comparator 是比较接口,如果要控制某个类的次序,而类本身不支持排序(没有实现 Comparable 接口)那么可以建立一个类比较器。
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
Comparable 相当于“内部比较器”,而 Comparator 相当于“外部比较器”。如果你无法修改某个类来改变其实现,而又想要让他实现排序,那么只能够使用外部比较器了。
==
作用是判断两个对象地址是否相等,即判断两个对象是不是同一个对象。
equals 作用也是判断两个对象是否相等,但有两种情况:
Here is some config file paths and some commands I used to deal with GitLab. This is a learning note, not an instruction of installing GitLab on your server. For the detail of installation, please check the official site and playlist I create on Youtube.
gitlab 主要配置目录 /etc/gitlab/gitlab.rb
gitlab-ctl reconfigure
always run this command after modifying the config file /etc/gitlab/gitlab.rb
. All the config files are generated by this command and located under opt/gitlab/embedded/service/gitlab-rails/config
.
gitlab-ctl start|stop|restart start stop and restart gitlab service
gitlab-ctl status 输出类似下面的格式:
run: logrotate: (pid 744) 197s; run: log: (pid 737) 197s
run: nginx: (pid 743) 197s; run: log: (pid 731) 197s
run: postgresql: (pid 748) 197s; run: log: (pid 738) 197s
run: redis: (pid 746) 197s; run: log: (pid 734) 197s
run: sidekiq: (pid 747) 197s; run: log: (pid 736) 197s
run: unicorn: (pid 745) 197s; run: log: (pid 735) 197s
gitlab-ctl tail trace the log, and check error
gitlab-ctl tail postgresql 单独查看 postgresql 日志
/opt/gitlab gitlab 和依赖应用的代码
/var/opt/gitlab/bin gitlab-ctl reconfigure 命令写入的地方,存放应用数据和配置文件 /etc/gitlab omnibus 版本 gitlab 的配置文件,平常只需要修改这个配置文件就够了
/var/opt/gitlab/git-data/repositories all the repo are stored here.
/var/log/gitlab 包含 omnibus 版本 gitlab 所有组件的日志数据
/var/opt/gitlab/nginx/conf/ nginx.conf and gitlab-http.conf
official document is here
Following is my setting to use 163 NetEase’s SMTP service. But after I test for a while, most of GitLab emails were blocked by the service. So I change my setting to use mailgun.
# If your SMTP server does not like the default 'From: gitlab@localhost' you
# can change the 'From' with this setting.
# 网易服务器 smtp 机器要求身份验证帐号和发信帐号必须一致
# 如果用户在发送邮件时,身份验证帐号和发件人帐号是不同的,因此拒绝发送。
gitlab_rails['gitlab_email_from'] = 'username@163.com'
gitlab_rails['gitlab_email_reply_to'] = 'username@163.com'
#send gitlab notification via SMTP by 163.com
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.163.com"
gitlab_rails['smtp_port'] = 25
gitlab_rails['smtp_user_name'] = "username@163.com"
gitlab_rails['smtp_password'] = "smtp password"
gitlab_rails['smtp_domain'] = "163.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
This is my setting for mailgun
# Sending email via SMTP using mailgun, following is the config
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.mailgun.org"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "gitlab@domain.com created in the console of mailgun"
gitlab_rails['smtp_password'] = "password created in the console of mailgun"
gitlab_rails['smtp_domain'] = "your domian.com same as the @domain.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
##Ref
莫名奇妙的陪同学看了这场电影,看之前完全没有了解,只是听说这部电影是在他们那里拍摄的,其他的一无所知。而看之前也同样在豆瓣了解过,5.2的评分让我完全不抱希望,只是同学一再推荐就去了。
只是一部文艺电影,坐在电影院里我一再告诫自己,于是电影就开始了。开场部分大段大段的自白,缓慢的镜头,那个叫做公母寨的地方确实很美,其实整个故事很简单,一个下乡的青年遇到了曾经的初恋,发生了一段美好的故事,虽然结局很悲惨,但过程很美好。这是一个很美好的青春故事,夹杂着那个时代,那个地点特有的符号,特有的宁静,特有的风景,原本应该是一个既能看风景又能看颜值的美好爱情片,却分分钟让我出戏,太过文艺的对白,让我觉得整个过程就像是两个人在背书,虽然作为一个90后并不知道80年代人们的对话,但是总觉得如电影中那样的对话是不大会出现的,你能随口一句话就能引发人生无限思考还能保证押韵?其二就是无法忍受的慢镜头,虽然爱情片总该有那两个镜头能够让人感受到浪漫,但,但对我来说更多的是无聊的等待,当然也有一些记忆深刻的镜头,就比如那个两人坐在竹桥上彻夜谈天,男主吹口琴的瞬间让人感觉到了些许浪漫。其他的镜头和叙述真的很让人出戏。
不过还有些需要被提起的,乡长和老田真是片中最喜欢的两个角色了,在这样的怀旧爱情片中能够出现这样的小插曲还是挺好,一个就是男主和乡长同上厕所,一个就是男主女友来找老田在楼下扫地说,饭菜能准备,床没法准备,再一个就是乡长拿错男主写的情书的时候。也就这样的时候让人会心的一笑。
如果按照观影风向标的打分标准来说,我可以给的分数分别是剧情5分,表演4分,可以给乡长和老田5分,而娱乐性是2分,有一个好的故事却没有一个会讲故事的好导演,哎。
当然此类电影的出现本来就是值得赞扬的,电影院长期被小时代,匆匆那年等等青春爱情片占领的时候出现这样一部稍微文艺一点的爱情片的时候,也不能苛求过多,只是这部电影能让我记住的也就只有那山间的风景了,远眺满山的茶树,中间些许采茶人,也有一条或隐或现的小道,主人公走在这条小路上去找女主的爸爸。
而对比我们的邻居韩国,他们一向以爱情片为人所知,但当然他们什么类型片都能产出了的,但他们拍摄爱情片总让人不能忘却,我的野蛮女友已经过了十多年,我依然会为男女主角的美好爱情所感动,我脑海中的橡皮擦,这只是一部偶然间看过的电影却让我无法忘怀,假如某一天我失忆了,我的另一半会有这样的坚持,陪我重走一遍曾经走过的地方吗?而假如爱有天意,讲过去的爱情故事,其实和这部1980有着相同的背景,却拍出来完全不一样的感觉,这些韩国电影却总有一两个镜头让人无法忘却,总有一两首让人记忆犹新,而回想这部片子,我真的已经想不到什么了,那两首出现过的歌,真是让看得我无比的尴尬,那真的是那个时代人唱的歌嘛?
而更加让我无法接受的便是片尾追加的几十年过后,一次同学聚会,一次滚床单,一次拒绝,而后又是几十年的离别,最后男主想要回到那个宁静的山村的时候,女主却得绝症去世了。世上有这样巧的事情,真巧想到她的时候,她就不再了?虽然知道电影是由小说改编,可是这样的离奇巧合让我无法接受更让我无法接受的是女主嫁人,而丈夫车祸去世了,女主还得了绝症,这是再拍韩剧么?如果导演或者小说作者想要在最后营造悲伤氛围的话,这并不是最佳的方法,我们的眼泪并不会这么留下来,而在此过程中我看到的是男主作为一个男人无法承担起的责任,虽然女主怕步她母亲的后尘怕连累男主,而选择留在山村,如果说女主留在山村最后的目的只是照顾年老的父亲的话,那么父亲去世之后,她便没有了继续留着的理由,她也有理由追寻自己的梦想,追寻自己的理想,甚至是追寻自己的情人,虽然片中并没有对女主有太多的感情描写,但我坚信女主并不是不喜欢男主,不然何必几年前给的笔记本还留着,几年前给的口琴还留着,当然这也可能只是故事太过悲剧,我并不想接受而已啦,我只是尽可能的讲了我的感受,我并没有看过小说或者了解过作者和导演本身。
而最后片中浅尝辄止的历史背景,大家都知道77年恢复高考,78年改革开放,而之前是整整十年的浩劫,乡政府的老田,我倒是很愿意听一听老人家的故事,女主的建筑师父亲,我也愿意听一听您的故事,那是真真的爱情,虽然片中老田也说过了,他说他并不记恨他的妻子,但是他们有感情,虽然那可能并不是我们通常说的爱,而桥梁建筑师的爱情则更加让人惋惜,老人会后悔一辈子吗?电影中也没有交代,只是给了一个老人看着墙上妻子的照片久久不能走动的背影。或许是因为审查的关系亦或许导演或者作者想要说明什么,这世上的爱情并不是什么天长地久,而是就是远隔天涯也能默默的祝福彼此。