原文发于个人独立博客:经过《The Linux Command Line》入门linux命令行php
此书网站:The Linux Command Line ,它是免费的。css
它有中文版,并且还有一个好听的名字:快乐的 Linux 命令行html
学习有两种方法,一种是系统的学,一种是根据实际需求来学。两种各有优缺点,前一种,知识不会有缺漏,对往后的融会贯通和举一反三有好处,可是这样慢,并且有可能不如针对性学习的精神集中。后一种,只找需求的学,可以任务完成就行,这样快,它的缺点就是前一种的优势。显然通看整本书属于第一种。node
做者写的很好,娓娓道来,讲的很清楚,就像一本故事书同样。我很喜欢这样的书。做者比较幽默,一些用词看了会让人发笑。linux
这本书的内容很浅,真的只是入门。nginx
正如做者所说,这是一场linux的journey(旅行),就把看书当旅行吧。git
如下是随手记的,只适合本身看。github
date
cal
-calendardf
-current amount of free space on your disk drivesfree
-display the amount of free memoryexit
-closing the terminal emulator windowpwd
- Print name of current working directorycd
- Change directorycd home directory
cd - previous working directory
cd ~user_name home directory of user
. 点号表明当前文件夹
ls
- List directory contentsls -a all files
ls -l long format
ls -lt sort the result by the file's modification time
ls -lt --reverse
file
– Determine file typesql
less
– View file contentsshell
和cat的区别?参考
cp
若是文件已经存在,直接覆盖,没有提示,要提示用-i
mv
move (rename) files
mkdir
mkdir dir1 dir2
rm
– Remove Files And Directoriesrm -r playground # 递归删除
ln
– Create Linksln myfile hard # hard link
ln -s myfile soft # symbolic link
软连接”和“硬连接”的区别:硬连接指向磁盘区块,软连接指向绝对路径。
hard links的缺点:
1.cannot span physical devices.
2.cannot reference directories, only files.
type
– Indicate how a command name is interpretedtsc@tsc:~$ type ls
ls is aliased to `ls --color=auto' # alias
tsc@tsc:~$ type cd
cd is a shell builtin # builtin
tsc@tsc:~$ type cp
cp is /bin/cp # executable program
which
– Display An Executable’s Locationtsc@tsc:~$ which cp
/bin/cp
只用于exe
help
– Get help for shell builtins
注意是shell builtin
tsc@tsc:/bin$ help cd
cd: cd [-L|[-P [-e]] [-@]] [dir]
Change the shell working directory.
理解注释:[]
是可选,|
是互斥。
--help
– Display Usage Informationtsc@tsc:~$ mkdir --help
man
– Display a command’s manual page没有example
tsc@tsc:~$ man ls
apropos
– Display a list of appropriate commandsinfo
– Display a command’s info entrywhatis
– Display a very brief description of a commandalias
– Create an alias for a command起别名前先检查是否存在,用type
:
tsc@tsc:~$ type test
test is a shell builtin
使用:
alias name='string' # name后不能有空格
tsc@tsc:~$ alias foo='cd /usr; ls; cd -'
tsc@tsc:~$ foo
终端关闭后做用就消失了。
去除:
tsc@tsc:~$ unalias foo
command1; command2; command3...
tsc@tsc:~$ cd /usr; ls
help最简单,info最详细,man在二者之间。
cat
- Concatenate filescat file1 # 输出文件到屏幕,没有分页
cat > file.txt # cat没有参数时接受stdin
this is test.
# ctrl+d 结束
# < 接受文件输入
tsc@tsc:~$ cat < lazy_dog.txt
sort
- Sort lines of textuniq
- Report or omit repeated lines# -d 显示重复的
tsc@tsc:~$ ls /bin /usr/bin | sort | uniq -d | less
grep
- Print lines matching a pattern“global regular expression print”,find功能。
tsc@tsc:~$ ls /bin /usr/bin | sort | uniq | grep zip
wc
- Print newline, word, and byte counts for each file联合使用看条目个数:
tsc@tsc:~$ ls /bin /usr/bin | sort | uniq | wc -l
head
- Output the first part of a filetail
- Output the last part of a filetee
- Read from standard input and write to standard output and files这个名字颇有意思,tee有三通管的意思,配合pipe使用,它的做用是从stdin读入,复制到stdout和文件。
# 一方面输出到ls.txt,一方面传给grep
tsc@tsc:~$ ls /usr/bin/ | tee ls.txt | grep zip
I/O redirection 的做用
I/O redirection allows us to change where output goes and where input comes from.
>
重定向
tsc@tsc:~$ ls -l /usr/bin/ > ls-output.txt
tsc@tsc:~$ > ls-output2.txt # 建立一个空文件
要注意重复>
时,原来的文件会被清空。
>>
追加tsc@tsc:~$ ls -l /usr/bin >> ls-output2.txt
文件不存在会新建。
tsc@tsc:~$ ls -l /bin/usr 2> ls-error.txt
个人问题:在不知道有没有error的状况下,>
和2>
要如何同时执行?
有两种方法:
# 1.老版本
# 顺序很重要
tsc@tsc:~$ ls -l /bin/usr > ls-output.txt 2>&1
# 2.新,用&>
tsc@tsc:~$ ls -l /bin/usr &> ls-output.txt
tsc@tsc:~$ ls -l /bin/usr &>> ls-output.txt # 追加
tsc@tsc:~$ ls -l /usr/bin | less
千万不要把>
用成|
,否则有些后果很严重。
tsc@tsc:~$ ls /bin /usr/bin | sort | less
这节讲expansion, 就是*
、~
之类的,本质就是变量。
echo
– Display a line of textIt prints out its text arguments on standard output
tsc@tsc:~$ echo this is a test
this is a test
tsc@tsc:~/playground$ echo ~
/home/tsc
形式:
$((expression))
tsc@tsc:~/playground$ echo $((2+2))
4
brace expansion
括号中间不能有空格。
用途:批量建立有顺序的文件。
Parameter Expansion
Command Substitution
command的结果也能够做为expansion
echo $(ls)
Double Quotes
“$”, “\” (backslash), and “`” (backquote) 失效,可是parameter expansion, arithmetic expansion, and command substitution 仍有效。
注意区别:
echo $(cal)
echo "$(cal)"
空格、tab、换行符都被用来分割,双引号则抑制。因此前一个命令不会换行,后一个会。
Single Quotes
抑制全部expansions
escape character
和双引号一块儿使用,抑制部分符号
这节讲键盘技巧,提升效率。主要是command line和history的技巧。command line的:移动,删除。history的上下一个命令。
clear
– Clear the screen
history
– Display the contents of the history list
Cursor Movement
completion
补全
history
history expansion-使用history中1209行的命令:
tsc@tsc:~$ !1209
思考:多用户为何存在?想一想计算中心。
多用户存在要解决的问题:
1.一个用户的错误操做不能使计算机crash
2.一个用户不能影响其余用户
/etc/passwd
User accounts .
/etc/group
groups
/etc/shadow
user's password
Owner Group World
id
– Display user identity$ id
uid=1000(tsc) gid=1000(tsc) groups=1000(tsc),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)
# root
# id
uid=0(root) gid=0(root) groups=0(root)
chmod
– Change File Mode$ chmod 600 foo.txt
umask
– Set Default Permissions
su
– Run A Shell With Substitute User And Group IDs
默认是superuser
$ su -
exit
sudo
– Execute A Command As Another User
纠正本身的认识,su,sudo是改变用户的,不必定是super,默认才是。
chown
– Change File Owner And Group
chgrp
– Change Group Ownership
passwd
- change user password
进程
Processes are how Linux organizes the different programs waiting for their turn at the CPU.
ps
- report a snapshot of the current processes.
top
- display Linux processes
&
- Putting A Process In The Background
jobs
- list the jobs that have been launched from our terminal.
fg
- Returning A Process To The Foreground
为何要回到前台来?后台的程序不受terminal的控制。
Ctrl-z
- Stopping (Pausing) A Process
注意和ctrl-c的区别,c是结束。
bg
- resume the program’s execution in the background
kill
- “kill” processes
killall
- kill processes by name
halt
poweroff
reboot
shutdown
什么是environment?
configuration的做用:store program settings
printenv
- print all or part of environment# 全部environment
tsc@tsc:~$ printenv | less
# 某一个environment
tsc@tsc:~$ printenv USER
tsc@tsc:~$ echo $HOME
printenv
显示的一些常见变量:
SHELL
PATH # 全部的,最新的
set
will show both the shell and environment variables
printenv
和set
的区别
printenv
只显示environment variables,set
显示shell和environment variables.
追加
PATH=$PATH:$HOME/bin
export
tells the shell to make the contents of PATH available to child processes of this shell.
启动顺序
Login Shell Sessions :
/etc/profile # global
~/.bash_profile
~/.bash_login # 若是上面那个不存在,读这个
~/.profile # 若是上面那个不存在,读这个
.profile
文件中有PATH,而且将$HOME/bin
添加上了,因此启动系统后$HOME/bin
中的命令是直接能够用的。$HOME
是用户目录。
Non-Login Shell Sessions :
/etc/bash.bashrc # global
~/.bashrc # user's
Login和Non-Login的区别?
参考,
PATH的做用
命令从中找。
改环境变量时改哪一个文件?
.profile
:
add directories
define additional environment variables
.bashrc
:
everything else
有两种:
1.graphical :gedit
2.text based :nano, vi, emacs
ctrl-x : exit
ctrl-o : save, write out
# : comments
.bashrc
生效首先要知道原理,启动流程,在session一开始才会read .bashrc
,因此须要重启terminal才会生效。固然,能够强行重读.bashrc
,用source
命令:
source .bashrc
why vi?
always available
lightweight and fast
vi 操做
:q
:q! # 强制退出
i # insert
esc # to command mode
:w # save ,有:的命令叫ex command
# move
h, j, k, l
ctrl-f/b
numberG
gg # 第一个字符
G last line of the file
0 (zero) 行首
^ To the first non-whitespace character on the current line.
$ end of current line
w beginning of next word or punctuation
W ignoring punctuation
b beginning of previous word or punctuation
B ignoring punctuation
# edit
u # undo last change
i # insert
# append
a # append, i是前插
A # 直接到最后append
# opening a line
o # 新建一行在下面
O # 新建一行在上面
# delete
x # current character
3x
dd # current line,d有cut的做用
dw #
dW # ignoring punctuation
d$ # current cursor to end
d0 # current cursor to beginning
dG # current cursor to end of file
d20G # current cursor to 20 line,不是要删除20行
5dd # 5行
# Cutting, Copying, And Pasting
p # 小写粘贴在后一行(dd),普通在光标前
P # 大写粘贴在前一行(dd),普通在光标后
p # paste after cursor
P # upper case, paste before cursor
# copy
yy # copy current line
5yy # copy 5 line
yW # ignoring punctuation
yw #
y$ # current cursor to end of line
y0 # current cursor to beginning of line
y^ # current cursor to first non-whitespace char
yG # current cursor to last line of file
y20G # current cursor to 20th line
# redo,undo
u # undo
ctrl+r # redo
J # join line
# search, replace
fa # 行内搜索a,按;继续搜索
/ # 文件内搜索,n继续
:%s/line/Line/g # 替换
:%s/line/Line/gc # 有提醒的替换
%表明对全部内容进行操做
:1,2s/line/Line/gc # 对1-2行进行操做
Ctrl-e, Ctrl-y # Scroll down and scroll up
The leading tilde characters (”~”) indicate that no text exists on that line.
modal editor
command mode
You can change the case of text:
Toggle case “HellO” to “hELLo” with g~
then a movement.
Uppercase “HellO” to “HELLO” with gU
then a movement.
Lowercase “HellO” to “hello” with gu
then a movement.
Alternatively, you can visually select text then press ~
to toggle case, or U
to convert to uppercase, or u
to convert to lowercase.
# 到行尾
$ 反:0
A 反:I
Word movement: w, e, b
Linux vi and vim editor: Tutorial and advanced features
就是这个:
tsc@tsc:~$
更改它:
tsc@tsc:~$ PS1="<\u@\h \w>\$ "
<tsc@tsc ~>$
\u # username of the current user.
\h # Hostname of the local machine minus the trailing domain name.
\w # Name of the current working directory.
\$ # This displays a “$” character unless we have superuser privileges. In that case, it displays a “#” instead.
改颜色:
经过escape code 实现,escape code 的开头是八进制的033 ,例子:
\033[0;30m
\033是开头
0 是optional character attribute,0表明text color是normal,1是bold
30m 是instruction
tsc@tsc:~$ PS1="\[\033[0;31m\]<\u@\h \w>\$\[\033[0m\] " \033[0m # 表明结束修改
要知道package是什么,如何install, remove, update
linux的哪一个发行版才是最好的?考虑的因素不是界面,而是:
1.packaging system
2.vitality of the distribution’s support community
Debian “.deb” camp
Red Hat “.rpm” camp
Packaging System Distributions (Partial Listing)
Debian Style (.deb) Debian, Ubuntu, Linux Mint, Raspbian
Red Hat Style (.rpm) Fedora, CentOS, Red Hat Enterprise Linux, OpenSUSE
package files
shared libraries
软件都是有依赖的,被依赖的就放在这里
dependency
package tool
分为high, low-level两种,
high:metadata search, dependency
low-level: installing, removing
Red Hat系列使用同一low-lvel program(rpm), high-level则不一样,yum使用者:Fedora, Red Hat Enter, CentOS.
Distributions | Low-Level Tools | High-Level Tools |
---|---|---|
Debian-Style | dpkg | apt-get, aptitude |
Fedora, Red Hat, Enterprise Linux, CentOS | rpm | yum |
- 查找和安装package的方法
- What is the difference between apt-get update and upgrade?
attaching the device to the file system tree.
mount
– Mount a file system 没有参数时,显示已经mounted的文件系统。
如何看?device on mount_point type file_system_type (options).
free
- Display amount of free and used memory in the system
partition number 是什么?
Unable to enumerate USB device under virtualbox
usb3.0插的3.0的口上在vm中读不出来,改插在2.0的口上就能够,真是。。。
磁盘、分区及Linux文件系统 [Disk, Partition, Linux File System]
inode的做用:实现文件存储的关键。
tail
的妙用
# ubuntu
tail -f /var/log/syslog
实时观察系统在作什么。
fsck
- check and repair a Linux filesystemIP Addresses, Host Names, and Domain Names
明白host name与domain name的区别。
ping
, ping6
- send ICMP ECHO_REQUEST to network hosts
traceroute
- print the route packets trace to network host
ip
- show / manipulate routing, devices, policy routing and tunnels
DHCP (Dynamic Host Configuration Protocol)
netstat
- Print network connections, routing tables, interface statistics, masquerade connections, and multicast memberships
ftp
— Internet file transfer program
ftp是明文传输。
Wget
- The non-interactive network downloader.
ssh
rlogin and telnet 和ftp有同样的缺陷。
ssh解决了两大问题:First, it authenticates that the remote host is who it says it is (thus preventing so-called “man in the
middle” attacks), and second, it encrypts all of the communications between the local and
remote hosts.
ssh root@ip -p 端口号
windows下的ssh软件
PuTTY
找文件。
locate
- find files by name
locate查找的数据库是如何更新的?由updatedb 程序更新,能够手动更新。
find
- search for files in a directory hierarchy
$ find ~ -type f | wc
# 文件名有jpg,大小大于1M
$ find ~ -type f -name "*.jpg" -size +1M | wc -l
$ find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)
顺序很重要。
把查找的结果做为命令的输入参数
$ find ~ -type f -name 'foo*' -exec ls -l '{}' ';'
$ find ~ -type f -name 'foo*' -exec ls -l '{}' +
$ find ~ -type f -name 'foo*' -print | xargs ls -l
{} is a symbolic representation of the current pathname
semicolon is a required delimiter indicating the end of the command.
+
:the system only has to execute the ls command once
$ find ~ -type f -name '*.jpg' -print0 | xargs --null ls -l
touch
- change file timestamps
文件不存在时会建立。
stat
- display file or file system status
which is a kind of souped-up version of ls.
管理大量的文件-压缩。
本节讲3个内容:
compression
archiving
synchronization
gzip, gunzip, zcat
- compress or expand filesgzip
压缩,gunzip
解压。
gzip
会替换原来的文件。
zcat
- equivalent to gunzip
with the -c
optionbzip2, bunzip2
- a block-sorting file compressortar
-tape archive
.tar or .tgz, which indicate a “plain” tar archive and a gzipped archive, respectively.
# c create
$ tar cf playground.tar playground
# t list
$ tar tf playground.tar
# x extract
$ tar xf ../playground.tar
# r append
# extract a single file
$ tar xf archive.tar pathname
注意区分mode与option,c是mode,f是option。
mode要先写。
studout或者stdin就能够用减号(-)来替代
使用zcat
能够查看*.gz
文件内容,使用bzcat
能够直接查看*.bz2
文件.
$ ssh root@xxx.xxx.xx.xx -p 端口号 'tar cf - filename' | tar xf -
root@xxx.xxx.xx.xx's password:
先tar,传回来再导出。
zip
- 既压缩也归档zip
,unzip
的做用是交换indows文件,linux用tar
,gzip
rsync
- 备份与同步rsync options source destination
$ rsync -av playground foo
后面几章都是关于文字处理的。先讲regular expression.
metacharacters是^ $ . [ ] { } - ? * + ( ) | \
,其他就是literal characters。
就是点号,the dot or period character
The caret (^
) (只匹配行首出来的)and dollar sign ($
) (只匹配行尾出现的)
$ grep -h '^zip' dirlist*.txt
$ grep -h 'zip$' dirlist*.txt
$ grep -h '^zip$' dirlist*.txt
$ grep -h '.zip' dirlist*.txt
$ grep -i '^..j.r$' /usr/share/dict/words
[]
用来只匹配一个字符。
$ grep -h '[bg]zip' dirlist*.txt
^ : negation,只在第一个位置时有效
$ grep -h '[^bg]zip' dirlist*.txt # 注意出现的位置,表示取反
- : range
$ grep -h '^[A-Za-z0-9]' dirlist*.txt
# 要匹配-(短横线),就把它放到第一位
$ grep -h '[A-Z]' dirlist*.txt
$ grep -h '[-AZ]' dirlist*.txt
出现的缘由:posix和ASCII不同。
[]
是单个,它(|
)是string
$ echo "AAA" | grep -E 'AAA|BBB|CCC'
$ grep -Eh '^(bz|gz|zip)' dirlist*.txt
匹配的个数
?
- Match An Element Zero Or One Time ,一个字符出现的次数,和word里面的?不一样,word里面表明任意一个字符,这里的?不能单独使用,要跟在一个字符后面。
$ echo "(555) 123-4567" | grep -E '^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$'
*
- Match An Element Zero Or More Times
$ echo "This works." | grep -E '[[:upper:]][[:upper:][:lower:] ]*\.'
和?同样,前面要有字符。
+
- Match An Element One Or More Times
至少出现一次。
$ echo "This that" | grep -E '^([[:alpha:]]+ ?)+$'
{ }
- Match An Element A Specific Number Of Times
$ echo "(555) 123-4567" | grep -E '^\(?[0-9]{3}\)? [0-9]{3}-[0-9]{4}$'
find
使用reg$ find . -regex '.*[^-_./0-9a-zA-Z].*'
# 反 0-无穷个字符
$ locate --regex 'bin/(bz|gz|zip)'
注意它们的区别,在vi中reg是basic
# less
/^\([0-9]{3}\) [0-9]{3}-[0-9]{4}
# vi
/([0-9]\{3\}) [0-9]\{3\}-[0-9]\{4\}
真是一切皆文件。
$ cat -A foo.txt # 显示全部符号,包括控制符
$ cat -ns foo.txt # n显示行号,s抑制多余的空行
$ sort > foo.txt
c
b
a
# 多个文件
$ sort file1.txt file2.txt file3.txt > final_sorted_list.txt
du
- estimate file space usage
$ du -s /usr/share/* | head # 显示前10个
$ du -s /usr/share/* | sort -nr | head # 大到小排序后显示前10个
按指定列排序(k):
$ ls -l /usr/bin | sort -nr -k 5 | head
多个key排序:
$ sort --key=1,1 --key=2n distros.txt
# 一个field内多个排序:
$ sort -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt
指定分割符:
$ sort -t ':' -k 7 /etc/passwd | head
$ sort foo.txt | uniq
# 取第3列
$ cut -f 3 distros.txt
每一个field的长度可能不一样,若是要取全部行中时间中的年,就不可能用字符位置去表示。而先把field取出来,就规整了。
$ cut -f 3 distros.txt | cut -c 7-10
$ expand distros.txt | cut -c 23-
$ cut -d ':' -f 1 /etc/passwd | head
adds one or more columns of text to a file
$ sort -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt > distros-by-date.txt
$ cut -f 1,2 distros-by-date.txt > distros-versions.txt
$ cut -f 3 distros-by-date.txt > distros-dates.txt
$ paste distros-dates.txt distros-versions.txt
It joins data from multiple files based on a shared key field.
$ join distros-key-names.txt distros-key-vernums.txt | head
$ comm file1.txt file2.txt
# -n 抑制列
$ comm -12 file1.txt file2.txt
$ diff file1.txt file2.txt
# context format 看两个各自都有什么,没有什么
$ diff -c file1.txt file2.txt
# unified format 看从旧到新的变化
$ diff -u file1.txt file2.txt
apply changes to text files
用来更新文件,好比代码。
$ diff -Naur file1.txt file2.txt > patchfile.txt
$ patch < patchfile.txt
转换
$ echo "lowercase letters" | tr a-z A-Z
LOWERCASE LETTERS
# 多对一的转换
$ echo "lowercase letters" | tr [:lower:] A
# squeeze
$ echo "aaabbbccc" | tr -s ab
abccc
stream editor
# search-and-replace
$ echo "front" | sed 's/front/back/'
# 谁跟在command后面就是delimiter
$ echo "front" | sed 's_front_back_'
# 指定要处理的行数
$ echo "front" | sed '1s/front/back/'
# p:打印出来
# -n: not to print every line by default
$ sed -n '1,5p' distros.txt
$ sed -n '/SUSE/p' distros.txt
$ sed -n '/SUSE/!p' distros.txt
# 通常出输出到屏幕,用i原地
$ sed -i 's/lazy/laxy/; s/jumped/jimped/' foo.txt
$ sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)$/\3-\1-\2/' distros.txt
$ echo "aaabbbccc" | sed 's/b/B/'
$ echo "aaabbbccc" | sed 's/b/B/g'
拼写检查
$ aspell check foo.txt
# -H (HTML) checking-mode option
$ aspell -H check foo.txt
改完了会产生一个bak文件,存在原来的文本。
讲文本输出格式。
显示行号
$ nl distros.txt | head
# 和cat -n 同样
$ sort -k 1,1 -k 2n distros.txt | sed -f distros-nl.sed | nl
$ echo "The quick brown fox jumped over the lazy dog." | fold -w 12
# 不打断单词
$ echo "The quick brown fox jumped over the lazy dog." | fold -w 12 -s
it fills and joins lines in text while preserving blank lines and indentation.
$ fmt -w 50 fmt-info.txt | head
$ fmt -cw 50 fmt-info.txt
# 一行若是不足50个字符,会把第二行的补过来
# 只对'# '开头的行操做
$ fmt -w 50 -p '# ' fmt-code.txt
used to paginate text.
# l:page length
# w:width
$ pr -l 15 -w 65 distros.txt
首尾会有空行。
“print formatted”
使用:printf “format” arguments
$ printf "I formatted the string: %s\n" foo
$ printf "%d, %f, %o, %s, %x, %X\n" 380 380 380 380 380 380
Multiple optional components :
%[flags][width][.precision]conversion_specification
tex后来取代了troff.
$ zcat /usr/share/man/man1/ls.1.gz | head
$ man ls | head
$ zcat /usr/share/man/man1/ls.1.gz | groff -mandoc -T ascii | head
# 存为postscript到桌面
$ zcat /usr/share/man/man1/ls.1.gz | groff -mandoc > ~/Desktop/foo.ps
# ps转pdf
$ ps2pdf ~/Desktop/foo.ps ~/Desktop/ls.pdf
介绍了ps的由来。
CUPS (Common Unix Printing System) :provides print drivers and print-job management
Ghostscript: a PostScript interpreter, acts as a RIP.
pr is used to adjust text to fit on a specific page size, with optional page headers and margins.
# 3列
$ ls /usr/bin | pr -3 -w 65 | head
CUPS 有两种printing,lpr, lp.
$ ls /usr/bin | pr -3 | lpr
lpr: Error - no default destination available.
# 查看printer
$ lpstat -a
lpstat: No destinations added.
“Anything to PostScript.”
$ ls /usr/bin | pr -3 -t | a2ps -o ~/Desktop/ls.ps -L 66 -R
# 查询printer状态
$ lpstat -a
$ lpstat -a
$ lpq
PDF is ready
no entries
compile
linker,解决共享问题,用共享库。
$ which gcc
/usr/bin/gcc
$ mkdir src
$ cd src
$ ftp ftp.gnu.org
Name (ftp.gnu.org:me): anonymous
ftp> cd gnu/diction
ftp> ls
ftp> get diction-1.11.tar.gz
ftp> bye
$ tar xzf diction-1.11.tar.gz
# 先查看是否是在一个文件夹里,以避免解压散开
$ tar tzvf diction-1.11.tar.gz | less
共享的头文件在/usr/include
,The header files in this directory were installed when we installed the compiler.
通常须要两步。
# 因为script不在默认的目录,须要./告诉shell它在当前目录
$ ./configure
config.status: creating Makefile
config.status: creating diction.1
config.status: creating diction.texi
config.status: creating diction.spec
config.status: creating style.1
config.status: creating test/rundiction
config.status: creating config.h
Makefile is a configuration file that instructs the make program exactly how to build the program. Without it, make will refuse to run.
$ make
$ sudo make install
#!
shebang,指明interpreter,每一个script开头都应该加这行。
$ chmod 755 hello_world
owner的权限是x就能够了。755全部人能够执行,700只有owner能够执行。必须是可读的。
$ ./hello_world
必需要加上./
,由于文件位置的问题。自动识别的命令的目录都写在了PATH中,能够查看它:
$ echo $PATH
在.bashrc
(它在~
中)中添加:
# 把~/bin添加在PATH的前面
export PATH=~/bin:"$PATH"
# 在当前terminal中生效
$ . .bashrc
# 或者
$ source .bashrc
~/bin : 本身用
/usr/local/bin : 同一个系统多人用
/usr/local/sbin: 系统管理员用
/usr/local: locally supplied software,
就是\
:syntax on
:set hlsearch
:set tabstop=4
:set autoindent
永久:
写在~/.vimrc,没有就建立
shell是动态语言
uppercase letters to designate constants and lower case
letters for true variables.
$ vim ~/bin/sys_info_page
$ chmod 755 ~/bin/sys_info_page
$ sys_info_page
$ sys_info_page > sys_info_page.html
$ firefox sys_info_page.html
uppercase letters to designate constants and lower case letters for true variables.
Note that in an assignment, there must be no spaces between the variable name, the equals sign, and the value.
a=z # Assign the string "z" to variable a.
b="a string" # Embedded spaces must be within quotes.
c="a string and $b" # Other expansions such as variables can be
# expanded into the assignment.
d="$(ls -l foo.txt)" # Results of a command.
e=$((5 * 7)) # Arithmetic expansion.
f="\t\ta string\n" # Escape sequences such as tabs and newlines.
大括号的做用
$ filename="myfile"
$ touch "$filename"
$ mv "$filename" "$filename1"
mv: cannot move 'myfile' to '': No such file or directory
$ mv "$filename" "${filename}1"
command << token
text
token
# shell example
cat << _EOF_
<HTML>
<HEAD>
<TITLE>$TITLE</TITLE>
</HEAD>
</HTML>
_EOF_
# terminal example
$ cat << _EOF_
> $foo
> "$foo"
> '$foo'
> \$foo
> _EOF_
讲程序设计的思想。
两种形式:
function name {
commands
return
}
and the simpler (and generally preferred) form:
name () {
commands
return
}
in order for function calls to be recognized as shell functions and not interpreted as the names of external programs, shell function definitions must appear in the script before they are called.
要加local
funct_1 () {
local foo # variable foo local to funct_1
foo=1
echo "funct_1: foo = $foo"
}
shell的if语句挺复杂的。
if commands; then
commands
[elif commands; then
commands...]
[else
commands]
fi
x=5
if [ "$x" -eq 5 ]; then
echo "x equals 5."
else
echo "x does not equal 5."
fi
程序结果后返回给系统的。查询:
$ ls -d /usr/bin
$ echo $?
true
- do nothing, successfully
false
- do nothing, unsuccessfully
语法:
test expression
and the more popular:
[ expression ]
expression是true时返回0,不然返回1
test和[
本质上是同样的。
使用:
#!/bin/bash
# test-file: Evaluate the status of a file
FILE=~/.bashrc
if [ -e "$FILE" ]; then
if [ -f "$FILE" ]; then
echo "$FILE is a regular file."
fi
if [ -d "$FILE" ]; then
echo "$FILE is a directory."
fi
if [ -r "$FILE" ]; then
echo "$FILE is readable."
fi
if [ -w "$FILE" ]; then
echo "$FILE is writable."
fi
if [ -x "$FILE" ]; then
echo "$FILE is executable/searchable."
fi
else
echo "$FILE does not exist"
exit 1
fi
exit # ?
When a script “runs off the end” (reaches end of file), it terminates with an exit status of the last command executed.
#!/bin/bash
# test-string: evaluate the value of a string
ANSWER=maybe
if [ -z "$ANSWER" ]; then
echo "There is no answer." >&2
exit 1
fi
if [ "$ANSWER" = "yes" ]; then
echo "The answer is YES."
elif [ "$ANSWER" = "no" ]; then
echo "The answer is NO."
elif [ "$ANSWER" = "maybe" ]; then
echo "The answer is MAYBE."
else
echo "The answer is UNKNOWN."
fi
[[]]
# 检验是否是数
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
(( ))
- Designed For Integers$ if ((1)); then echo "It is true."; fi
It is true.
if ((INT == 0));
if ((INT < 0));
if (( ((INT % 2)) == 0));
Operation test [[ ]] and (( ))
AND -a &&
OR -o ||
NOT ! !
例子:
# [[]]
if [[ "$INT" -ge "$MIN_VAL" && "$INT" -le "$MAX_VAL" ]];
# test
if [ "$INT" -ge "$MIN_VAL" -a "$INT" -le "$MAX_VAL" ];
The &&
(AND) and ||
(OR)
$ mkdir temp && cd temp
$ [[ -d temp ]] || mkdir temp
[]
和[[]]
的区别[[]]
和[]
同样,不过有两个新特性,:
string1 =~ regex
== operator
[[]]
和表达式之间要有空格[[ "$count" -gt 5 ]]
[[ "$count" -gt 5]] # 会报错,执行起来会很可怕
read a single line of standard input.
read [-options] [variable...]
# -n option,suppresses the trailing newline on output
echo -n "Please enter an integer -> "
read int
read var1 var2 var3 var4 var5 # 多个
# -p prompt
read -p "Enter one or more values > "
# -t seconds
# -s Silent mode.
if read -t 10 -sp "Enter secret passphrase > " secret_pass;
Internal Field Separator
file_info=$(grep "^$user_name:" $FILE)
# 写在一行,IFS只改变跟在后面的 command
IFS=":" read user pw uid gid name home shell <<< "$file_info"
The <<<
operator indicates a here string.
就像函数与子函数,凡是这一类都不能pip。
就是提示和if。
那应该如何作?
有3各loop
语法:
while commands; do commands; done
#!/bin/bash
# while-count: display a series of numbers
count=1
while [[ "$count" -le 5 ]]; do
echo "$count"
count=$((count + 1))
done
echo "Finished."
break
continue
和while相反
count=1
until [[ "$count" -gt 5 ]]; do
echo "$count count=$((count + 1)) done echo "Finished.
#!/bin/bash
# while-read
while read distro version release; do
printf "distro: %s\tversion: %s\treleased: %s\n" \
"$distro" \
"$version" \
"$release"
done < distros.txt
讲错误的处理。
引号不对称
特定符号缺失
意外的expansion
是否报错取决于expansion的值。
双引号的做用
# number为空时会报错
number=
if [ $number = 1 ]; then
# 这样就不会了 “”=1
[ "$number" = 1 ]
Multi-word string也应该用双引号括起来。
因此,老是用双引号把变量括起来。
/
, null character(a zero byte)
uppercase letters A-Z, lowercase letters a-z, numerals 0-9, period (.), hyphen (-), and underscore(_).
利用echo输出
在更改的地方加注释,方便恢复。
case要反映edge and corner
commenting out :部分注释
tracing :在一些关键点增长输出,查看是否执行到这里了
能够在script的第一行加入x option:
#!/bin/bash -x
也能够用set设置部分tracing
set -x # turn on
...
set +x # turn off
case
1 #!/bin/bash
2
3 # case-menu
4
5 clear
6 echo " 7 please select: 8 9 1. display system information 10 2. display disk space 11 3. display home space utilization 12 0. quit 13 "
14 read -p "enter selection [0-3] > "
15
16 case "$REPLY" in
17 0) echo "program terminated"
18 exit
19 ;;
20 1) echo "hostname: $HOSTNAME"
21 uptime
22 ;;
23 2) df -h
24 ;;
25 3) if [[ "$(id -u)" -eq 0 ]]; then
26 echo "home space utilization (all users)"
27 du -sh /home/*
28 else
29 echo "home space utilization ($USER)"
30 du -sh "$HOME"
31 fi
32 ;;
33 *) echo "invalid entry" >&2
34 exit 1
35 ;;
36 esac
讲处理command的option
$0
是当前命令的路径。
注意它的含义:
Note that $0 always contains the full pathname of the first item on the command line (i.e., the name of the program) and does not contain the name of the shell function as we might expect.
是整个路径,不是命令的名字。
大于9时用大括号括起来。
$#
让$1
下次变成$2
,全部参数都移动,$#
减1
去除文件名前面的字符,只要文件名。
positional parameter也能够用在function中
Difference between echo -e “” and echo $“”
e的意思就是扩展,支持转义,e和$
支持的符号部分不相同。
$*
和$@
的区别
不加双引号时是同样的,遇到空格就拆分,加双引号时不同,$*
会将全部参数放到一个字符串中,$@
会将每一个输入的参数分别看成参数,也就是不区分输入时的空格。
$@
常常用。
讲for
# 两种风格
for variable [in words]; do
commands
done
# c语言的
for (( expression1; expression2; expression3 )); do
commands
done
例子:
[me@linuxbox ~]$ for i in A B C D; do echo $i; done
Create list:
itscs-MacBook-Pro:~ itsc$ for i in {A..D}; do echo $i; done
# 文件列表 pathname expansion
itscs-MacBook-Pro:learnCommandLine itsc$ for i in dis*.txt; do echo "$i"; done
变量是其中的一种
$a
${a}
a="foo"
echo "${a}_file" # 和其它字符相连时防止造成不存在的变量
parameter为空或者不存在就用word,存在就用它本身。
${parameter:-word}
和上面基本同样,区别:要赋值。
${parameter:=word}
unset和empty就发发送word到error
${parameter:?word}
${parameter:+word}
${#parameter} # 换成长度
$ foo="This string is long."
$ echo "'$foo' is ${#foo} characters long. 'This string is long.' is 20 characters long ${parameter:offset} ${parameter:offset:length} [me@linuxbox ~]$ foo="This string is long." [me@linuxbox ~]$ echo ${foo:5} string is long. [me@linuxbox ~]$ echo ${foo:5:6} string 删除一部分 ${parameter#pattern} ${parameter##pattern} [me@linuxbox ~]$ foo=file.txt.zip [me@linuxbox ~]$ echo ${foo#*.} txt.zip [me@linuxbox ~]$ echo ${foo##*.} zip 反着删除 ${parameter%pattern} ${parameter%%pattern} [me@linuxbox ~]$ foo=file.txt.zip [me@linuxbox ~]$ echo ${foo%.*} file.txt [me@linuxbox ~]$ echo ${foo%%.*} file 替换 ${parameter/pattern/string} ${parameter//pattern/string} ${parameter/#pattern/string} ${parameter/%pattern/string}
能够用来作什么?好比数据库的查找,匹配的时候把输入和数据库中的都统一大小写。
itscs-MacBook-Pro:learnCommandLine itsc$ echo $((3.3+4.2))
-bash: 3.3+4.2: syntax error: invalid arithmetic operator (error token is ".3+4.2")
解决:perl, awk.书里用最简单的bc
为何连浮点运算都不支持?真是麻烦。
Single value
[me@linuxbox ~]$ a[1]=foo
[me@linuxbox ~]$ echo ${a[1]}
foo
[me@linuxbox ~]$ declare -a a
# assign
name[subscript]=value
name=(value1 value2 ...)
[me@linuxbox ~]$ days=(Sun Mon Tue Wed Thu Fri Sat)
[me@linuxbox ~]$ days=([0]=Sun [1]=Mon [2]=Tue [3]=Wed [4]=Thu [5]=Fri [6]=Sat)
[me@linuxbox ~]$ animals=("a dog" "a cat" "a fish")
[me@linuxbox ~]$ for i in ${animals[*]}; do echo $i; done
[me@linuxbox ~]$ for i in ${animals[@]}; do echo $i; done
[me@linuxbox ~]$ for i in "${animals[*]}"; do echo $i; done
[me@linuxbox ~]$ for i in "${animals[@]}"; do echo $i; done
因此须要有方法知道哪些位置上有值
[me@linuxbox ~]$ foo=([2]=a [4]=b [6]=c)
[me@linuxbox ~]$ for i in "${foo[@]}"; do echo $i; done
a
b
c
[me@linuxbox ~]$ for i in "${!foo[@]}"; do echo $i; done
2
4
6
$ foo=(a b c)
$ foo[100]=e
$ echo ${foo[@]}
a b c e
$ foo+=(k l)
$ echo ${foo[@]}
a b c e k l
$ for i in "${foo[@]}"; do echo $i; done
a
b
c
e
k
l
$ for i in "${!foo[@]}"; do echo $i; done
0
1
2
100
101
102
subscript不是连续的
下标能够是字符
讲一些不经常使用的,在特定场景下使用的
Group command:
{ command1; command2; [command3; ...] }
Subshell:
(command1; command2; [command3;...])
它们是作什么的?
manage redirection
{ ls -l; echo "Listing of foo.txt"; cat foo.txt; } > output.txt
(ls -l; echo "Listing of foo.txt"; cat foo.txt) > output.txt
结合pip
{ ls -l; echo "Listing of foo.txt"; cat foo.txt; } | lpr
due to the way bash implements
group commands, the braces must be separated from the commands by a space and the
last command must be terminated with either a semicolon or a newline prior to the closing brace.
subshell和它的名字同样,返回时enviroment会丢失,因此通常状况下用group.
echo "foo" | read
echo $REPLY # 这就是subshell的例子,reply是空的
commands in pipelines are always executed in subshells
用来解决subshell的问题
read < <(echo "foo")
echo $REPLY
举个打电话的例子:
阻塞/同步:打一个电话一直到有人接为止
非阻塞:打一个电话没人接,每隔10分钟再打一次,知道有人接为止
异步:打一个电话没人接,转到语音邮箱留言(注册),而后等待对方回电(call back)看起来异步是最高效,充分利用资源,能够想像整个系统能支持大规模并发。但问题是调试很麻烦,不知道何时call back。
create a connection between two processes and can be
used just like other types of files.
named pipe是一个文件起着pipe的做用
[me@linuxbox ~]$ mkfifo pipe1
[me@linuxbox ~]$ ls -l pipe1
prw-r--r-- 1 me me 0 2009-07-17 06:41 pipe1
# terminal 1
[me@linuxbox ~]$ ls -l > pipe1
# terminal2
[me@linuxbox ~]$ cat < pipe1
[[:upper:]]
哪一节的?
每一个文件夹下的.
和..
的做用?为何必需要有它们?
它们表明当前和前一级目录,这个你们都知道,能够为何要有它们?设计原理是什么?
参考:SO,只说了有,没有说什么为何。
shell中各类括号[]、[[]]的做用与区别?
参考。
磁盘、分区及Linux文件系统 [Disk, Partition, Linux File System]
IDE、SATA、SCSI、SAS、FC、SSD硬盘类型介绍
Understand synopsis in manpage
能够直接在命令man man
中看。
vi color
cd ~
vi .vimrc
syntax on
colorscheme desert
添加到vimrc中即永久:
set tabstop=4
标准错误输出>&2
输出到哪了?
屏幕。
vim color
/usr/share/vim/vim74/colors/
我以为还不错的:
koehler
industry
murphy
ron
How to make ls sort by file extension and then name?
ls -lX
Reveal the line numbers:
:set number
then
:5,$s/^/#/g comment
or this:
:5,$s/^/#/ uncomment
Vim: copy selection to OS X clipboard still fail to work
To check if your Vim has clipboard support: vim --version | grep -i clipboard
. You should see +clipboard
. If you see -clipboard
your Vim was compiled without clipboard support…
itscs-MacBook-Pro:learnCommandLine itsc$ vim --version | grep -i clipboard
-clipboard +job +path_extra +user_commands
+eval -mouse_dec +statusline -xterm_clipboard
个人是减号,说明不支持。
Getting Vim with +clipboard
support
要先装Homebrew,装完后的vim在 /usr/local/bin/vim,原来的在/usr/bin
,也存在,只不过PATH中,local的在前面,命令会先用它。
echo $1
echo "$1"
echo '$1'
$ ./longest words
words
words
$1
双引号与无引号在这里是同样的,双引号的做用体如今字符串为空的时候,为空的时候是空字符串,能够判断,而无引号就麻烦了,好比等号,一边为空会报错,说等号是个二元操做符两边都要有值。单引号的做用就是禁止转义,所有为字符串。
$#
添加到Shell的参数个数
$! shell parameter, which will always contain the process ID of the
last job put into the background.