Linux命令行的最佳实践和技巧?

我想打开一个会积累你的Linux命令行(CLI)最佳实践和技巧的讨论。

我已经search了这样的讨论分享下面的评论,但没有find一个,因此这个职位。

我希望大家都能从中吸取教训。

欢迎您分享您的Bash提示,grep,sed,AWK,/ proc以及所有其他相关的Linux / Unix系统pipe理,shell编程的最佳实践,以利于我们大家。

使用屏幕 ,由GNU项目开发的一个免费的terminal多路复用器,可以让你有一个terminal。

您可以开始一个会话,即使连接丢失,您的terminal也将被保存,因此您可以稍后或从家中恢复。

SSH!
SSH是上帝的命令 – 我认为这是最有价值的总体命令学习。 选项可以是相当艰巨的,但似乎我不断学习使用新的SSH命令行选项,我从来没有想过会是必要的。 在这一点上,我可能已经全部使用了它们。

你越多地使用它,你越了解它。 你可以使用它来做一些惊人的事情。

注意:除了使ssh服务器运行外,所有这些东西都可以远程执行,而不需要在服务器上进行设置。

通过互联网挂载一个文件系统

searchnetworkingSSHFS

转发命令

SVN + SSH协议是从远程客户端到运行NO DEAMON的服务器的Subversion! SVN命令通过ssh shell启动服务器,并通过现有的pipe道来回传递信息。 rsync程序执行相同的操作,通过SSH通过启动一个rsync来运行在没有rsync deamon的服务器上。 编写自己的bash文件来做类似的技巧是很容易的。

链通过防火墙

我一直使用这个function,通过我的Linux服务器在家里跳到我的Mac。

转发端口:
似乎只有适度的有用,直到你意识到你可以通过家庭防火墙弹跳,并在工作中configuration你的路由器在家里,就好像你在家里的networking一样)。

转发X请求:

这是另一个惊人的。 在远程系统上运行或不运行X服务器,您可以运行一个x-windows程序,该窗口将出现在您的本地屏幕上。 只要使用开关-X,就是这样!

由于您不需要在远程服务器上运行X服务器,所以CPU对服务器的影响是最小的,您可以使用TINY Linux服务器为运行Windows和Cygwin / X的强大游戏PC提供大型应用程序。

当然,VI和EMACS是通过SSH工作的,但是当我在家里跑步的时候,有时候我需要更多的东西。 我使用ssh -X来启动一个Eclipse的副本! 如果你的服务器比你的笔记本电脑更强大,那么你的graphics用户界面就在你的笔记本电脑上,但是编译是在你的服务器上完成的,所以不要担心系统负载。

在batch file中运行

(意思是在其他系统上运行一个本地的batch file):

两件事结合起来,使这个很酷。 一个是你可以通过使用(更安全的)encryption密钥来消除密码提示。 其次,您可以在SSH CLI上指定一个命令。 我用了一些有趣的方法 – 就像在远程服务器上编译失败一样,我将SSH放入我的电脑并播放声音文件)。

请记住,您可以redirect来自远程命令的输出,并在本地batch file中使用它,因此您也可以在本地拖放在您的服务器上运行的编译。

内置到Mac

服务器和客户端都内置到Mac和Linux。 在Mac和Ubuntu的情况下,启用服务器就像find正确的checkbox一样简单。

在PC上安装cygwin或cygwin / X(cygwin / X将允许您将您的Linux机器的x-window输出转发到Windows PC – 它会安装一个X服务器)

重要提示/configuration文件

切勿在防火墙上使用端口22。 你会得到很多黑客的尝试,这是不值得的。 只需让防火墙将不同的端口转发到您的服务器即可。

有广泛的configuration选项,可以让你显着简化你的SSH命令。 这是我工作中的一个例子:

Host home hostname billshome.hopto.org Port=12345 user=bill LocalForward=localhost:1025 mac:22 

当我input“ssh home”(没有别的)时,就好像我input了:

 ssh -p 12345 [email protected] 

然后转发我的本地端口1025到我家系统“mac”。 原因是我在我的文件中有另一个条目:

 Host mac hostname localhost port=1025 

所以一旦我做了一个“ssh home”,并且仍然打开窗口,我可以input“ssh mac”,而在这里工作的计算机实际上会尝试连接到自己已经被转发到“mac: 22“,所以它会通过防火墙连接到我家里的Mac。

编辑 – 酷脚本!

我挖出了一个我刚刚喜欢的旧脚本 – 必须回来后张贴给任何可能感兴趣的人。 该脚本被称为“authMe”

 #!/bin/bash if [ ! -f ~/.ssh/id_dsa.pub ] then echo 'id_dsa.pub does not exist, creating' ssh-keygen -tdsa fi ssh $1 'cat >>.ssh/authorized_keys' <~/.ssh/id_dsa.pub 

如果你的主目录中有这个脚本,并且有一个主机可以连接(通过ssh),那么你可以input“./authMe hostName”。

如果有必要的话,它会为你创build一个公钥/私钥对,然后将ssh转移到另一个机器上并复制你的公钥(ssh命令会提示你input密码)

之后,SSH命令在连接到远程系统时不应再要求input密码,而是使用公钥/私钥对。

如果您的远程计算机不总是安全的,您应该考虑在出现提示时设置“密码”。

您可能还想configuration远端的ssh服务器,以便不允许使用文本密码(只有密钥)才能获得更高的安全性。

我喜欢用

 cd - 

切换到上一个目录。 很有用!

我最近发现了pv命令(pipe道查看器),就像猫一样,但有传输细节。

所以,而不是

 $ gzip -c access.log > access.log.gz 

您可以使用

 $ pv access.log | gzip > access.log.gz 611MB 0:00:11 [58.3MB/s] [=> ] 15% ETA 0:00:59 

所以,而不是不知道什么时候你的手术会完成,现在你会知道!

由Peteris Krumins提供

按下Ctrl-R并开始input命令(或其中的任何部分) – 它search命令历史logging。 再次点击Ctrl-R会跳到下一个匹配项,input执行当前显示的命令,右箭头(至less)会让你先编辑它。

 $ (reverse-i-search)`svn': svn status 

在学习这个之前,我已经用了7年的Linux作为我的主要操作系统,但现在我知道了,它非常方便。

命令行是一个有趣的事情。 我认为,你只能靠自己学习,而其他的学习则是通过命令行来看别人。

我多年来一直在使用这个shell,用手工input目录名称。 有一天,我正在看一个朋友在一个系统上乱七八糟,他一直在按Tab键。 我问“你为什么打标签?”。 答:它会尝试完成目录或文件名。 谁会猜到 – 制表符完成! input一些文件或目录,点击选项卡,它会尝试完成你input的内容(行为取决于哪个shell)。

有一天,朋友在命令行上看着我,看着我键入如下内容:

 coryking@cory ~/trunk/mozi $ pushd /etc /etc ~/trunk/mozi coryking@cory /etc $ popd ~/trunk/mozi coryking@cory ~/trunk/mozi $ 

谁会猜到!? 他从来不知道popd / pushd 。 猜猜我们甚至…

学习Vim。

它(可以说)是最好的编辑器,但是最好的编辑器可以在一个裸机上运行。

即使退出之后,程序仍然运行有时会很有用。 我已经看到了一些使用nohup甚至屏幕的解决scheme。 我所知道的最简单的是:

 $ your_command_here & disown 

您也可以分离正在运行的程序:

 $ your_command_here # Press <Control-Z> to stop the program and bring it to background: $ bg $ disown 

当我想确保我使用实际的命令而不是一个别名,我使用一个前导反斜杠:

 \rm -rf ~/tmp 

这个技巧会使你的CLI更加舒适(至less这对我来说):

用以下内容创build〜/ .inputrc文件:

 "\e[A": history-search-backward "\e[B": history-search-forward 

重新加载bash(例如,通过input“exec bash”)。 当你键入一个命令的前缀,然后按向上箭头,你将浏览以你的前缀开始的命令,例如,如果你键入ssh,它将显示你以前的连接与远程shell。 如果你的提示是空的,那么向上的箭头将以正常的方式浏览历史。

&&代替; 当一次执行多个命令时。 发生错误时停止,不执行其他命令。

经典例子:

 ./configure && make && make install 

在bash命令行编写循环时,我经常在“echo”命令前加冒险的命令。

 for item in items; do echo something-risky; done 

这样我就可以在承诺运行之前全面地看到“有风险的东西”。 帮助您的风险命令包括variables扩展和globs。 在编写bash脚本时,“set -x”非常有用。

“set -x”启用debugging。 有关bashdebugging的信息,请参阅http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html

需求

您需要testing两台服务器之间的最大带宽。


SERVER1上做:

 nc -u -l 54321 > /dev/null 

SERVER2上做:

 dd if=/dev/zero bs=1MB | nc -u SERVER1 54321 & pid=$(pidof dd) while (( 1 )); do kill -USR1 $pid; sleep 2; done 

你会看到如下输出:

 182682000000 bytes (183 GB) copied, 1555.74 seconds, 117 MB/s 182920+0 records in 182919+0 records out 

这里有117 MB / s是有趣的因素,它显示了实际的networking传输带宽。

说明

当数据包开始stream经networking时,您将能够看到SERVER2上的带宽统计数据,这是对两个服务器之间的实际最大可能带宽的相当好估计。

通过UDP复制(防止TCP开销)。

将SERVER1上的内存(/ dev / zero)复制到SERVER2上的内存(/ dev / null),从而防止磁盘I / O成为瓶颈。

看到彩色目录结构更容易。

 alias ls="ls --color=tty" 

编辑

 alias ls="ls --color=auto" 

一些关于日志查看的小指针:

  1. 可以使用tail -F在截断日志之后继续观察日志(例如log4j)。
  2. 您可以使用less:less打开,单击SHIFT + F来模拟尾部行为。 同样有用的组合是-S来禁用换行。 更less的将使您能够在日志中search。

我很久以前就从朋友那里学到了一个很简单的方法来改变一个文件的扩展名:

 mv my_filename.{old,new} 

壳牌扩张将扩大到:

 mv my_filename.old my_filename.new 

这也可以用于以其他方式重命名文件,例如添加以下内容:

 mv my_{,cool_}filename 

使用“tar xf”来提取压缩的档案。 j的bzip2和z的gzip是没有必要的,因为焦油将检测您的档案文件types。 论点之前也没有“ – ”号。 你会节省很多时间(超过千年;-))。

更好的是,使用一个命令而不使用任何不必要的参数来取消任何存档。

安装bash完成包。 它包含许多shell的预定义完成规则。 如果你的发行版没有为你做,你可以input“source / etc / bash_completion”来启用它。 那么,例如,当你在kpdf之后完成时,你将只能看到目录和PDF文件的列表。 在scp ssh:// server / XXX(如果您启用了无密码login)后完成远程文件同样聪明。

我经常使用这些

ALT-。 (ESC +。在某些terminal中)复制上次使用的参数(超级有用)

CTRL-W删除单词

CTRL-L清除terminal(如清除命令,但更快)

ALT-B(某些terminal的ESC + B)向后移动一个字

ALT-F(某些terminal的ESC + F)前进一个单词

CTRL-E跳转到EOL

CTRL-跳转到BOL

CTRL-R在历史中search

在bash中,我使用!$很多。 它重复了最后一个命令的最后一个参数:

 ls /really/long/command/argument/that/you/dont/want/to/repeat.txt vi !$ 

它会运行ls,然后如果你想编辑它,你不必重新键入它,只需使用!$。 这对长path/文件名非常有用。 另外, !*重复所有前面的命令的参数。 我不那么用,但看起来很有用。

我知道他们已经被提及,但我使用vim,screen和cd – 很多。

我忘记了noclobber:

 set -o noclobber 

男人bash

如果设置,bash不会用>,>&和<>redirect操作符覆盖现有的文件。 通过使用redirect操作符> |创build输出文件时,可能会覆盖此选项 而不是>。

从bash切换到zsh ,并查看您的生产力提高:

  • 真的很聪明,可脚本化的标签完成。 它不仅完成了命令行,还完成了所有选项,手册页名称,软件包名称(用于apt-get / emerge等)以及你有什么。 并在完成期间提供有用的解释。 所有这一切都没有使用任何回滚空间后的命令已经发出。
  • Tab键完成通配符; 写入cat * .txt,按下tab键,然后在与expression式匹配的文件中进行select。
  • 切换目录只需键入他们的名字。
  • 几个线路编辑器模式。 可以performance得像vi或emacs如果你想要的话。
  • 可定制的键绑定来做你想做的任何事情。
  • 可提示的提示,包括将提示信息放在屏幕的右侧,并在input长命令时自动隐藏

谷歌会告诉你更多的好处。

老学校,将目录树从一个地方移动到另一个地方,保留符号链接,权限和所有好东西:

 tar cBf - . | (cd /destination; tar xvBpf -) 

或通过networking

 tar cBf - . | rsh foo.com "cd /destination; tar xvBpf -) 

新学校:

 rsync -urltv . /destination 

或通过networking

 rsync -urltv -e ssh . foo.com:/destination 

要求 :你有一个包含你想要删除的大文件列表的目录。 rm -r会失败!

 find /var/spool/mqueue/ | wc -l 191545 rm -f /var/spool/mqueue/* -bash: /bin/rm: Argument list too long 

解答

 find /var/spool/mqueue/ -xdev -exec command rm -f '{}' + 

说明

编辑:修复@ephemient评论后的解释。

find将通过允许的最大参数为rm提供参数。 这将允许rm批量删除文件,这是我知道的最快的技术,而不使用find的删除操作。 这相当于

 find /var/spool/mqueue -xdev -print0 | xargs -0 rm -f 

如果您的find不支持-exec ... + ,您可能会发现它有用。

我经常使用这两个技巧,我认为这是一个好主意,分享:

 !foo 

将启动以“foo”开头的历史文件中的最后一个命令(我经常在编译时使用它,例如!gcc )。

另一个是键盘快捷键(Ctrl + O而不是Return),这将执行命令并显示历史文件中的下一个命令。 例如,当我编译和testing文件时,我总是执行3或4个命令,make,cd到testing目录,运行testing,cd到makefile的目录。 使用Ctrl + O这使得这个任务更容易:)

希望这个帮助!

如何在没有可能无法使用的花哨graphics界面的帮助下在Linux中使用Subversion。

 svn co <repo-url> . # Checks out project into current folder svn update # Get latest changes from server svn status # Shows what files have changed locally svn add <path/filename> # Add some file to the repo svn commit # Commit your changes to the repo 

这让很多使用Linux的开发人员感到奇怪。

最容易忽视的老校命令: find

昨天我修复了一个严重的权限错误:

 for u in nr dias simonpj; do sudo -u $u find . -type d -exec chmod g+s '{}' ';' done 

对于像bashksh这样的shell,你可以让命令行像你的文本编辑器一样响应导航命令:

 set -o emacs 

要么

 set -o vi 

将允许您search您的历史logging,并以您习惯于在文本文件中进行的方式移动命令行(例如,在vi模式下,按ESC然后键入/string将search您以前的命令“string”) – 您可以使用nN之间移动的比赛)

grep是我的朋友。 认真。

列出包含文本class foo .rb文件:

 grep -l "class foo" .rb 

列出包含文本class foo .rb文件:

 grep -L "class foo" *.rb 

列出包含foo或bar的.rb文件(您可以使用任何带-e的正则expression式,但是您需要转义运算符):

 grep -L -e "foo\|bar" *.rb 

壳牌replace是用^执行的:

 /home/eugene $ ls foo.txt foo.txt /home/eugene $ ^ls^rm rm foo.txt /home/eugene $ ls foo.txt ls: cannot access foo.txt: No such file or directory