[转载]天外飞仙级别的Linux Shell命令

本文编译自commandlinefu.com的系列文章Top Ten One-Liners from CommandLineFu Explained 。作为一个由用户推荐最有用shell命令的网站,其记录了数以万计的各色shell命令,其中不乏相当实用和有趣的,本文就要细数当中获投票最高的一些命令,从其中取材并加以细释,希望读者能从中受益。

编辑:@BOYPT 

本系列文章:

引言

Shell作为Unix系操作系统当中最有魅力且不可或缺的组件,经过数十载的洗礼不仅没有被淘汰,而且愈加变得成熟稳健,究其原因,大概因为它是个非常稳固的粘合剂,能够把大量功能强大的组件任意配搭,总能很好很快地完成用户的任务。

本文的一些命令很可能看起来是“雕虫小技”,我们只好仰慕一下Shell大牛了,但是有些细节我会稍加发掘加以说明,遇到有趣的地方希望能博您一笑了。

1.以sudo运行上条命令

1
$ sudo
 !!

大家应该都知sudo,不解释。但通常出现的情况是,敲完命令执行后报错才发现忘了sudo。这时候,新手用户就会:按上箭头,按左箭头,盯着光标回到开始处,输入sudo ,回车;高手用户就蛋定多了,按Ctrl-p ,按Ctrl-a ,输入sudo ,回车。

这里介绍这个是天外飞仙级别的,对,就直接sudo !!

当然这几种解决方式效果是完全一样的,只是款不一样,嗯,不解释。

两个感叹号其实是bash的一个特性,称为事件引用符(event designators)。!! 其实相当于!-1 ,引用前一条命令,当然也可以!-2!-50 。默认情况下bash会在~/.bash_history 文件内记录用户执行的最近500条命令,history 命令可以显示这些命令。

关于事件引用符的更多用法可以深入阅读The Definitive Guide to Bash Command Line History

2.以HTTP方式共享当前文件夹的文件

1
$ python -m
 SimpleHTTPServer

这命令启动了Python的SimpleHTTPServer模块,考虑到Python在绝大多数的Linux发行版当中都默认安装,所以这个命令很可能是最简单的跨平台传文件的方法。

命令执行后将在本机8000端口开放HTTP服务,在其他能访问本机的机器的浏览器打开ttp://ip:8000 即打开一个目录列表,点击即可下载。

3.在以普通用户打开的vim当中保存一个root用户文件

1
:w
 !
sudo
 tee
 %

这题目读起来纠结,其实是很常见的,常常忘记了sudo就直接用vim编辑/etc内的文件,(不过也不一定,vim发现保存的文件无法保存时候会提示)等编辑好了,保存时候才发现没权限。曲线方法是先保存个临时文件,退出后再sudo cp 回去。不过实际上在vim里面可以直接完成这个过程的,命令就是如此。

查阅vim的文档(输入:help :w ),会提到命令:w!{cmd} ,让vim执行一个外部命令{cmd} ,然后把当前缓冲区的内容从stdin传入。

tee是一个把stdin保存到文件的小工具。

而%,是vim当中一个只读寄存器的名字,总保存着当前编辑文件的文件路径。

所以执行这个命令,就相当于从vim外部修改了当前编辑的文件,好完工。

4.切换回上一个目录

1
$ cd
 -

应该不少人都知道这个,横杆- 代表上一个目录的路径。

实际上cd - 就是cd $OLDPWD 的简写,bash的固定变量$OLDPWD 总保存着之前一个目录的路径。

相对地,$PWD 总保存着当前目录的路径。这些变量在编写shell脚本时候相当有用。

5.替换上一条命令中的一个短语

1
$ ^foo^bar^

又是另外一个事件引用符(event designator),可以把上一条命令当中的foo替换成bar。

在需要重复运行调试一道长长的命令,需要测试某个参数时候,用这个命令会比较实用;但多数人会首先选择按上箭头提出上道命令,再移动光标去修改某参数,这样更直观,但效率上就不够使用引用符高,而且在脚本中用这个方法可以简化很多。

这道命令的原始样式应该是这样的:

1
!!
:s/
foo/
bar/

本文一开始介绍过!! ,后面的一段大家应该很熟悉,vim、sed的替换操作都是这样的语法。

关于事件引用符的更多用法可以深入阅读The Definitive Guide to Bash Command Line History

6.快速备份一个文件

1
$ cp
 filename{
,.bak}

这道命令把filename 文件拷贝成filename.bak ,大家应该在一些比较复杂的安装教程里面见过这样的用法。其原理就在于bash对大括号的展开操作,filename{,.bak} 这一段会被展开成filename filename.bak 再传给cp,于是就有了备份的命令了。

大括号在bash里面是一个排列的意义,可以试试这个:

1
$ echo
 {
a,b,c}
{
a,b,c}
{
a,b,c}

将输出三个集合的全排列:

aaa aab aac aba abb abc aca acb acc
baa bab bac bba bbb bbc bca bcb bcc
caa cab cac cba cbb cbc cca ccb ccc

关于shell当中的集合操作,可深入阅读“Set Operations in the Unix Shell”

7.免密码ssh登录主机

1
$ ssh-copy-id remote-machine

这个命令把当前用户的公钥串写入到远程主机的~/.ssh/authorized_keys 内,这样下次使用ssh登录的时候,远程主机就直接根据这串密钥完成身份校验,不再询问密码了。前提是你当前用户有生成了公钥,默认是没有的,先执行ssh-keygen 试试吧!

这个命令如果用手工完成,是这样的:

1
2
3
your-machine$ scp
 ~/
.ssh/
identity.pub remote-machine:
your-machine$ ssh remote-machine
remote-machine$ cat identity.pub >> ~/ .ssh/ authorized_keys

如果你想删掉远程主机上的密钥,直接打开authorized_keys,搜索你的用户名,删除那行,即可。

8.抓取Linux桌面的视频

1
$ ffmpeg
 -f
 x11grab -s
 wxga -r
 25
 -i
 :0.0
 -sameq
 /
tmp/
out.mpg

我们在一些视频网站上看到别人的3D桌面怎么怎么酷的视频,通常就是这么来的,ffmpeg可以直接解码X11的图形,并转换到相应输出格式。

ffmpeg的通常用法是,根据一堆参数,输出一个文件,输出文件通常放最后,下面解析下几个参数:

-f x11grab 指定输入类型。因为x11的缓冲区不是普通的视频文件可以侦测格式,必须指定后ffmpeg才知道如何获得输入。

-s wxga 设置抓取区域的大小。wxga是1366*768的标准说法,也可以换成-s 800×600的写法。

-r 25 设置帧率,即每秒抓取的画面数。

-i :0.0 设置输入源,本地X默认在0.0

-sameq 保持跟输入流一样的图像质量,以用来后期处理。

至于其他ffmpeg的用法,可以参考下面两篇文章:

后记

说Shell是一种编程语言,可能有些尴尬,虽然很多人每天都在用Shell,但从来没见它荣登TIOBE编程语言排行榜之类的,可以说毫无名分, 因为很多用户没意识到它是一种语言,只当做这是一个能够很好完成任务的工具,基本得理所当然,就好像GUI程序的菜单、按钮一样。

掌握Shell,通常能够让任务在数秒钟内完成,这就让Shell跟C、Perl、Python这些语言区别开来,没人否认后者更能胜任更多的任 务,但是他们是在不同的层面上去做,Shell依赖大量的系统组件黏合调用,而后者依赖各种库,各所擅长不同的应用领域,比喻就是,Shell是混凝土, 可以很方便地粘合一些建筑组件而成为稳固的高楼大厦;但同样是粘合剂,粘玻璃窗、粘书报、粘皮鞋,混凝土是绝对不合适的,Shell并不擅长一些细致操 作,比如它连浮点运算都不支持,更别提什么图形运算什么的。但这并不妨碍Shell来帮我们完成很多粗重任务。

Shell的工作方式,大多数入门用户会觉得枯燥难学,而所谓的经典教材也离不开《Advanced Bash-Scripting》、《Bash Guide for Beginners》,但类似本文这样的一些“雕虫小技”因为难登大雅之堂绝不会收录进去。这情况如果象国外一些unix用户比较多的地方会有很好改善, 即使是新手,偶尔看看别人的操作都能“偷师”一手,我编译本系列文章其实也就希望稍微改善一下这个状况。

Related posts:

  1. Ubuntu 10.10 打算不把 gnome-shell 列为默认界面 Ubuntu 社区暂时决定,在下一个版本 10.10 将不会启用 gnome-shell 作为默认界面。 其实原因很简单,gnome-shell 虽然看上去很美好很强大,但是实际上成熟度依然很低。外观重新设计过,界面完全更改了用法,无论对开发者还是对普通用户都是一个挑战,因为需要改变很多习 惯以适应新界面。这还不算是最大的问题。最难解决的是 gnome-shell 效能问题。因为...
  2. 快速安装 KVM 内核虚拟机 KVM 是 Linux 下一款性能强劲的虚拟机软件。与其他虚拟化技术寄生在系统上不同,这个虚拟机是直接放置在内核,从而拥有更加强劲的性能。 首先是安装,在 Fedora 下安装十分简单,仅仅需要一条命令就可以了: sudo yum install...
  3. 自己制作 linux-kbuild 的 deb 包 我之前写过一篇牢骚文发泄对 Debian 不出 linux-kbuild 的不满,后来在 Debian Wiki 找到了帮助,自行解决了 linux-kbuild 的问题。...

以上关联文章由 Yet Another Related Posts Plugin 提供支持。

 

 

 

 

I love working in the shell. Mastery of shell lets you get things done in seconds, rather than minutes or hours, if you chose to write a program instead.

In this article I'd like to explain the top one-liners from the commandlinefu.com . It's a user-driven website where people get to choose the best and most useful shell one-liners.

But before I do that, I want to take the opportunity and link to a few of my articles that I wrote some time ago on working efficiently in the command line:

Update: Russian translation now available.

And now the explanation of top one-liners from commandlinefu.

#1. Run the last command as root

$ sudo !!

We all know what the sudo command does - it runs the command as another user, in this case, it runs the command as superuser because no other user was specified. But what's really interesting is the bang-bang !! part of the command. It's called the event designator . An event designator references a command in shell's history. In this case the event designator references the previous command. Writing !! is the same as writing !-1 . The -1 refers to the last command. You can generalize it, and write !-n to refer to the n-th previous command. To view all your previous commands, type history .

This one-liner is actually really bash-specific, as event designators are a feature of bash.

I wrote about event designators in much more detail in my article "The Definitive Guide to Bash Command Line History ." The article also comes with a printable cheat sheet for working with the history.

#2. Serve the current directory at http://localhost:8000/

$ python -m SimpleHTTPServer

This one-liner starts a web server on port 8000 with the contents of current directory on all the interfaces (address 0.0.0.0), not just localhost. If you have "index.html " or "index.htm " files, it will serve those, otherwise it will list the contents of the currently working directory.

It works because python comes with a standard module called SimpleHTTPServer . The -m argument makes python to search for a module named SimpleHTTPServer.py in all the possible system locations (listed in sys.path and $PYTHONPATH shell variable). Once found, it executes it as a script. If you look at the source code of this module, you'll find that this module tests if it's run as a script if __name__ == '__main__' , and if it is, it runs the test() method that makes it run a web server in the current directory.

To use a different port, specify it as the next argument:

$ python -m SimpleHTTPServer 8080

This command runs a HTTP server on all local interfaces on port 8080.

#3. Save a file you edited in vim without the needed permissions

:w !sudo tee %

This happens to me way too often. I open a system config file in vim and edit it just to find out that I don't have permissions to save it. This one-liner saves the day. Instead of writing the while to a temporary file :w /tmp/foobar and then moving the temporary file to the right destination mv /tmp/foobar /etc/service.conf , you now just type the one-liner above in vim and it will save the file.

Here is how it works, if you look at the vim documentation (by typing :he :w in vim), you'll find the reference to the command :w !{cmd} that says that vim runs {cmd} and passes it the contents of the file as standard input. In this one-liner the {cmd} part is the sudo tee % command. It runs tee % as superuser. But wait, what is % ? Well, it's a read-only register in vim that contains the filename of the current file! Therefore the command that vim executes becomes tee current_filename , with the current directory being whatever the current_file is in. Now what does tee do? The tee command takes standard input and write it to a file! Rephrasing, it takes the contents of the file edited in vim, and writes it to the file (while being root)! All done!

#4. Change to the previous working directory

$ cd -

Everyone knows this, right? The dash "- " is short for "previous working directory." The previous working directory is defined by $OLDPWD shell variable. After you use the cd command, it sets the $OLDPWD environment variable, and then, if you type the short version cd - , it effectively becomes cd $OLDPWD and changes to the previous directory.

To change to a directory named "- ", you have to either cd to the parent directory and then do cd ./- or do cd /full/path/to/- .

#5. Run the previous shell command but replace string "foo" with "bar"

$ ^foo^bar^

This is another event designator. This one is for quick substitution. It replaces foo with bar and repeats the last command. It's actually a shortcut for !!:s/foo/bar/ . This one-liner applies the s modifier to the !! event designator. As we learned from one-liner #1, the !! event designator stands for the previous command. Now the s modifier stands for substitute (greetings to sed ) and it substitutes the first word with the second word.

Note that this one-liner replaces just the first word in the previous command. To replace all words, add the g modifer (g for global):

$ !!:gs/foo/bar

This one-liner is also bash-specific, as event designators are a feature of bash.

Again, see my article "The Definitive Guide to Bash Command Line History ." I explain all this stuff in great detail.

#6. Quickly backup or copy a file

$ cp filename{,.bak}

This one-liner copies the file named filename to a file named filename.bak . Here is how it works. It uses brace expansion to construct a list of arguments for the cp command. Brace expansion is a mechanism by which arbitrary strings may be generated. In this one-liner filename{,.bak} gets brace expanded to filename filename.bak and puts in place of the brace expression. The command becomes cp filename filename.bak and file gets copied.

Talking more about brace expansion, you can do all kinds of combinatorics with it. Here is a fun application:

$ echo {a,b,c}{a,b,c}{a,b,c}

It generates all the possible strings 3-letter from the set {a, b, c} :

aaa aab aac aba abb abc aca acb acc
baa bab bac bba bbb bbc bca bcb bcc
caa cab cac cba cbb cbc cca ccb ccc

And here is how to generate all the possible 2-letter strings from the set of {a, b, c} :

$ echo {a,b,c}{a,b,c}

It produces:

aa ab ac ba bb bc ca cb cc

If you liked this, you may also like my article where I defined a bunch of set operations (such as intersection, union, symmetry, powerset, etc) by using just shell commands. The article is called "Set Operations in the Unix Shell ." (And since I have sets in the shell, I will soon write articles on on "Combinatorics in the Shell " and "Algebra in the Shell ". Fun topics to explore. Perhaps even "Topology in the Shell" :))

#7. mtr - traceroute and ping combined

$ mtr google.com

MTR, bettern known as "Matt's Traceroute" combines both traceroute and ping command. After each successful hop, it sends a ping request to the found machine, this way it produces output of both traceroute and ping to better understand the quality of link. If it finds out a packet took an alternative route, it displays it, and by default it keeps updating the statistics so you knew what was going on in real time.

#8. Find the last command that begins with "whatever," but avoid running it

$ !whatever:p

Another use of event designators. The !whatever designator searches the shell history for the most recently executed command that starts with whatever . But instead of executing it, it prints it. The :p modifier makes it print instead of executing.

This one-liner is bash-specific, as event designators are a feature of bash.

Once again, see my article "The Definitive Guide to Bash Command Line History ." I explain all this stuff in great detail.

#9. Copy your public-key to remote-machine for public-key authentication

$ ssh-copy-id remote-machine

This one-liner copies your public-key, that you generated with ssh-keygen (either SSHv1 file identity.pub or SSHv2 file id_rsa.pub) to the remote-machine and places it in ~/.ssh/authorized_keys file. This ensures that the next time you try to log into that machine, public-key authentication (commonly referred to as "passwordless authentication.") will be used instead of the regular password authentication.

If you wished to do it yourself, you'd have to take the following steps:

your-machine$ scp ~/.ssh/identity.pub remote-machine:
your-machine$ ssh remote-machine
remote-machine$ cat identity.pub >> ~/.ssh/authorized_keys

This one-liner saves a great deal of typing. Actually I just found out that there was a shorter way to do it:

your-machine$ ssh remote-machine 'cat >> .ssh/authorized_keys' < .ssh/identity.pub

#10. Capture video of a linux desktop

$ ffmpeg -f x11grab -s wxga -r 25 -i :0.0 -sameq /tmp/out.mpg

A pure coincidence, I have done so much video processing with ffmpeg that I know what most of this command does without looking much in the manual.

The ffmpeg generally can be descibed as a command that takes a bunch of options and the last option is the output file. In this case the options are -f x11grab -s wxga -r 25 -i :0.0 -sameq and the output file is /tmp/out.mpg .

Here is what the options mean:

  • -f x11grab makes ffmpeg to set the input video format as x11grab. The X11 framebuffer has a specific format it presents data in and it makes ffmpeg to decode it correctly.
  • -s wxga makes ffmpeg to set the size of the video to wxga which is shortcut for 1366x768. This is a strange resolution to use, I'd just write -s 800x600 .
  • -r 25 sets the framerate of the video to 25fps.
  • -i :0.0 sets the video input file to X11 display 0.0 at localhost.
  • -sameq preserves the quality of input stream. It's best to preserve the quality and post-process it later.

You can also specify ffmpeg to grab display from another x-server by changing the -i :0.0 to -i host:0.0 .

If you're interested in ffmpeg, here are my other articles on ffmpeg that I wrote while ago:

PS. This article was so fun to write, that I decided to write several more parts. Tune in the next time for "The Next Top Ten One-Liners from CommandLineFu Explained" :)

Have fun. See ya!

PSS. Follow me on twitter for updates .

This article was sponsored by:

Contact me , if you wish to sponsor any other of my existing posts or future posts!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值