我想发起一个讨论,以积累您的 Linux 命令行 (CLI) 最佳实践和技巧。
我搜索了这样的讨论来分享以下评论,但没有找到,因此这篇文章。
我希望我们都能从中吸取教训。
欢迎您分享您的 Bash 技巧、grep、sed、AWK、/proc 和所有其他相关的 Linux/Unix 系统管理、shell 编程最佳实践,以造福我们所有人。
小智 101
SSH!
SSH 是神命令——我认为它是最有价值的总体命令。这些选项可能非常令人生畏,但似乎我一直在学习使用新的 SSH 命令行选项,而我从未认为这是必要的。在这一点上,我可能已经使用了它们。
您使用它的次数越多,您对它的了解就越多。你可以用它来做一些了不起的事情。
注意:除了运行 ssh 服务器之外,所有这些事情都可以远程进行,无需在您的服务器上进行设置。
通过 Internet 挂载文件系统
在网上搜索 SSHFS
转发命令。
SVN+SSH协议是从远程客户端到服务器的Subversion,上面没有运行DEAMON!SVN 命令通过 ssh shell 启动服务器,并通过现有管道来回传递信息。rsync 程序做同样的事情,通过 SSH 自己启动一个没有 rsync 守护进程的服务器运行。编写自己的 bash 文件来执行类似的技巧很容易。
链以通过防火墙
我一直使用它来通过我家里的 linux 服务器跳转到我的 mac。
转发端口:
直到您意识到您可以通过家庭防火墙反弹并在家中配置路由器,就像您在家庭网络中那样做之前,这似乎只是适度有用)。
转发 X 请求:
这是另一个惊人的。无论是否在远程系统上运行 X 服务器,您都可以运行 x-windows 程序,该窗口将出现在您的本地屏幕上。只需使用开关 -X,就可以了!
由于您不必在远程服务器上运行 X 服务器,因此对服务器的 CPU 影响很小,您可以拥有一台 TINY Linux 服务器,为运行 Windows 和 cygwin/X 的强大游戏 PC 提供大量应用程序。
当然 VI 和 EMACS 通过 SSH 工作,但是当我在家运行时,有时我想要更多。我使用 ssh -X 来启动 Eclipse 的副本!如果你的服务器比你的笔记本电脑更强大,你的 GUI 就在你的笔记本电脑上,但是编译是在你的服务器上完成的,所以不要担心系统负载。
在批处理文件中运行
(意思是运行一个在其他系统上“做事”的本地批处理文件):
两件事相结合,使这件事很酷。一种是您可以通过使用(更安全的)加密密钥来消除密码提示。第二个是您可以在 SSH CLI 上指定命令。我以一些有趣的方式使用了它——比如当远程服务器上的编译失败时,我会将它 SSH 连接到我的计算机并播放声音文件)。
请记住,您可以重定向远程命令的输出并在本地批处理文件中使用它,因此您也可以在本地拖尾在服务器上运行的编译。
内置于 Mac
服务器和客户端都内置在 mac 和 linux 中。对于 Mac 和 Ubuntu,启用服务器就像找到正确的复选框一样简单。
在 PC 上安装 cygwin 或 cygwin/X(cygwin/X 将允许您将 x-window 输出从 Linux 机器转发到您的 Windows PC——它安装了一个 X 服务器)
重要提示/配置文件
切勿在防火墙上使用端口 22。你会得到很多 hack 尝试,只是不值得。只需让您的防火墙将不同的端口转发到您的服务器即可。
有大量的配置选项可让您显着简化 ssh 命令。这是我在工作中的一个例子:
Host home
hostname billshome.hopto.org
Port=12345
user=bill
LocalForward=localhost:1025 mac:22
Run Code Online (Sandbox Code Playgroud)
当我输入“ssh home”(没有别的)时,它就像我输入了:
ssh -p 12345 bill@billshome.hopto.org
Run Code Online (Sandbox Code Playgroud)
然后将我的本地端口 1025 转发到我家里的系统“mac”。原因是我的文件中有另一个条目:
Host mac
hostname localhost
port=1025
Run Code Online (Sandbox Code Playgroud)
这样一旦我完成了“ssh home”并且仍然打开了窗口,我可以输入“ssh mac”,这里工作的计算机实际上会尝试连接到它自己的端口 1025,该端口已转发到“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
Run Code Online (Sandbox Code Playgroud)
如果你的主目录中有这个脚本并且有一个你可以连接到的主机(通过 ssh),那么你可以输入“./authMe hostName”。
如有必要,它将为您创建一个公钥/私钥对,然后它将通过 ssh 连接到另一台机器并复制您的公钥(ssh 命令将提示您输入密码...)
在此之后,SSH 命令在连接到该远程系统时不应再询问您的密码,它将使用公钥/私钥对。
如果您的远程计算机并不总是安全的,您应该考虑在出现提示时设置“密码”。
您可能还希望将远端的 ssh 服务器配置为不允许使用文本密码(仅密钥)以提高安全性。
小智 73
我喜欢用
cd -
Run Code Online (Sandbox Code Playgroud)
切换到上一个目录。很有用!
Nic*_*aux 69
我最近发现了pv类似于 cat 但带有传输详细信息的命令(管道查看器)。
所以代替
$ gzip -c access.log > access.log.gz
Run Code Online (Sandbox Code Playgroud)
您可以使用
$ pv access.log | gzip > access.log.gz
611MB 0:00:11 [58.3MB/s] [=> ] 15% ETA 0:00:59
Run Code Online (Sandbox Code Playgroud)
因此,与其不知道您的操作何时会完成,现在您就会知道了!
cod*_*ole 53
sudo !!
Run Code Online (Sandbox Code Playgroud)
以 root 身份重新运行上一个命令。
[站点http://www.commandlinefu.com上的当前顶级命令,该站点以该问题为主题。]
小智 45
命令行是一个有趣的东西。我认为您只能自己学习这么多,其余的都是通过使用命令行偶然看到其他人而学到的。
多年来,我一直在使用 shell 手工输入目录名称。有一天,我看到一个朋友在系统上乱搞,他一直按 Tab 键。我问“你为什么要打标签?”。答:它会尝试补全目录或文件名。谁能想到——制表符补全!输入一些文件或目录,点击 Tab,它会尝试完成你输入的内容(行为取决于哪个 shell)。
有一天,这位朋友在命令行上看着我,看着我输入如下内容:
coryking@cory ~/trunk/mozi $ pushd /etc
/etc ~/trunk/mozi
coryking@cory /etc $ popd
~/trunk/mozi
coryking@cory ~/trunk/mozi $
Run Code Online (Sandbox Code Playgroud)
谁能想到!?他从来不知道popd/ pushd。猜猜我们甚至...
Jon*_*nik 45
按Ctrl-R并开始输入命令(或其中的任何部分) - 它会搜索命令历史记录。再次按下 Ctrl-R 将跳转到下一个匹配项,输入执行当前显示的命令,右箭头(至少)将让您首先编辑它。
$ (reverse-i-search)`svn': svn status
Run Code Online (Sandbox Code Playgroud)
在学习这个之前,我已经使用 Linux 作为我的主要操作系统大约 7 年了,但现在我知道了,它非常方便。
小智 38
有时即使在您注销后让程序继续运行也很有用。我见过一些为此目的使用 nohup 甚至 screen 的解决方案。我所知道的最简单的是:
$ your_command_here & disown
Run Code Online (Sandbox Code Playgroud)
您还可以分离正在运行的程序:
$ your_command_here
# Press <Control-Z> to stop the program and bring it to background:
$ bg
$ disown
Run Code Online (Sandbox Code Playgroud)
mou*_*iel 38
当我想确保使用实际命令而不是别名时,我使用前导反斜杠:
\rm -rf ~/tmp
Run Code Online (Sandbox Code Playgroud)
小智 38
这个技巧会让你的 CLI 更舒服(至少对我来说是这样):
使用以下内容创建 ~/.inputrc 文件:
"\e[A": history-search-backward
"\e[B": history-search-forward
Run Code Online (Sandbox Code Playgroud)
重新加载 bash(例如通过键入“exec bash”)。当您键入命令的前缀并按向上箭头时,您将浏览以您的前缀开头的命令,例如,如果您键入 ssh,它将显示您以前与远程 shell 的连接。如果您的提示为空,则向上箭头将以正常方式浏览历史记录。
小智 36
一次执行多个命令时使用&&代替;。发生错误时停止,不执行其他命令。
经典例子:
./configure && make && make install
Run Code Online (Sandbox Code Playgroud)
Jon*_*ney 32
在 bash 的命令行上编写循环时,我经常在有风险的命令前加上“echo”命令。
for item in items; do echo something-risky; done
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我可以在承诺运行它之前完整地看到“有风险的东西”。当您的危险命令包括变量扩展和 globs 时有帮助。'set -x' 在编写 bash 脚本时非常有用。
'set -x' 启用调试。有关bash 调试的信息,请参阅http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html。
Max*_*ler 31
您需要测试两台服务器之间的最大带宽。
在SERVER1 上做:
nc -u -l 54321 > /dev/null
Run Code Online (Sandbox Code Playgroud)
在SERVER2 上做:
dd if=/dev/zero bs=1MB | nc -u SERVER1 54321 &
pid=$(pidof dd)
while (( 1 )); do kill -USR1 $pid; sleep 2; done
Run Code Online (Sandbox Code Playgroud)
您将看到如下输出:
182682000000 bytes (183 GB) copied, 1555.74 seconds, 117 MB/s
182920+0 records in
182919+0 records out
Run Code Online (Sandbox Code Playgroud)
117 MB/s是这里有趣的因素,它显示了实际的网络传输带宽。
说明:
当数据包开始在网络上流动时,您将能够看到 SERVER2 上的带宽统计数据,这是对 2 个服务器之间实际最大可能带宽的一个很好的估计。
通过 UDP 复制(以防止 TCP 开销)。
复制到从上SERVER1存储器(的/ dev /零)到从成为瓶颈存储器(的/ dev / null的)上SERVER2,因而防止磁盘I / O。
小智 23
查看颜色目录结构更容易。
alias ls="ls --color=tty"
Run Code Online (Sandbox Code Playgroud)
编辑
alias ls="ls --color=auto"
Run Code Online (Sandbox Code Playgroud)
Max*_*ler 20
关于日志查看的一些小提示:
小智 20
很久以前我从朋友那里学到了一个技巧,可以轻松更改文件的扩展名:
mv my_filename.{old,new}
Run Code Online (Sandbox Code Playgroud)
Shell 扩展会将其扩展为:
mv my_filename.old my_filename.new
Run Code Online (Sandbox Code Playgroud)
这也可以用于以其他方式重命名文件,例如在以下位置添加内容:
mv my_{,cool_}filename
Run Code Online (Sandbox Code Playgroud)
小智 17
安装 bash 完成包。它包含许多用于 shell 的预定义完成规则。如果您的发行版不适合您,请通过键入“source /etc/bash_completion”来启用它。然后,例如,每当您在 kpdf 之后完成时,您只会看到目录和 PDF 文件的列表。它就像在 scp ssh://server/XXX 之后完成远程文件一样聪明(如果您启用了无密码登录)。
Álv*_*aro 17
我经常使用这些
ALT-。(ESC+. 在某些终端中)复制最后使用的参数(超级有用)
CTRL-W 删除单词
CTRL-L 清除终端(类似于清除命令但速度更快)
ALT-B(某些终端中为 ESC+B)向后移动一个词
ALT-F(某些终端中为 ESC+F)向前移动一个词
CTRL-E 跳转到 EOL
CTRL-A 跳转到 BOL
CTRL-R 在历史中搜索
gpo*_*ojd 16
在 bash 中,我经常使用!$。它重复最后一个命令的最后一个参数:
ls /really/long/command/argument/that/you/dont/want/to/repeat.txt
vi !$
Run Code Online (Sandbox Code Playgroud)
它将运行ls,然后如果你想编辑它,你不必重新输入它,只需使用!$。这对于长路径/文件名非常有用。此外,!*重复所有先前命令的参数。我用得不多,但它看起来很有用。
我知道有人提到过它们,但我经常使用 vim、screen 和 cd。
我忘了 noclobber:
set -o noclobber
Run Code Online (Sandbox Code Playgroud)
从人 bash:
如果设置,bash 不会用 >、>& 和 <> 重定向运算符覆盖现有文件。在使用重定向运算符 >| 创建输出文件时,这可能会被覆盖。而不是>。
小智 14
从 bash 切换到zsh,并看到您的生产力提高:
谷歌会告诉你更多的好处。
Pau*_*lin 13
老派,将目录树从一个地方移动到另一个地方,保留符号链接、权限和所有好东西:
tar cBf - . | (cd /destination; tar xvBpf -)
Run Code Online (Sandbox Code Playgroud)
或通过网络
tar cBf - . | rsh foo.com "cd /destination; tar xvBpf -)
Run Code Online (Sandbox Code Playgroud)
新学校:
rsync -urltv . /destination
Run Code Online (Sandbox Code Playgroud)
或通过网络
rsync -urltv -e ssh . foo.com:/destination
Run Code Online (Sandbox Code Playgroud)
Max*_*ler 13
要求:您有一个包含要删除的大文件列表的目录。rm -r 会失败!
例子
find /var/spool/mqueue/ | wc -l
191545
rm -f /var/spool/mqueue/*
-bash: /bin/rm: Argument list too long
Run Code Online (Sandbox Code Playgroud)
解决方案:
find /var/spool/mqueue/ -xdev -exec command rm -f '{}' +
Run Code Online (Sandbox Code Playgroud)
说明:
编辑:在@ephemient 评论后修正解释。
find 将通过允许的最大参数为 rm 提供参数。这将允许 rm 批量删除文件,这是我所知道的最快的技术,而无需使用 find 本身的 -delete 操作。它相当于
find /var/spool/mqueue -xdev -print0 | xargs -0 rm -f
Run Code Online (Sandbox Code Playgroud)
如果您find不支持-exec ... +.
小智 11
我经常使用这两个技巧,所以我认为分享是个好主意:
!foo
Run Code Online (Sandbox Code Playgroud)
将启动历史文件中以“foo”开头的最后一个命令(!gcc例如,我经常在编译时使用它。)
另一个是键盘快捷键(Ctrl+O 而不是 Return),它将执行命令并显示历史文件中的下一个命令。例如,当我编译和测试一个文件时,我总是执行 3 或 4 个命令,make,cd 到测试的目录,运行测试,cd 到 makefile 的目录。使用 Ctrl+O 这使得这个任务更容易:)
希望这有帮助!
小智 10
如何在没有花哨的图形界面的帮助下在 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
Run Code Online (Sandbox Code Playgroud)
奇怪的是,这阻碍了许多开发人员使用 Linux。
Nor*_*sey 10
最容易被忽视的老式命令: find
昨天我修复了一个严重的权限错误:
for u in nr dias simonpj; do
sudo -u $u find . -type d -exec chmod g+s '{}' ';'
done
Run Code Online (Sandbox Code Playgroud)
小智 8
对于像bash和这样的shell ksh,你可以让命令行响应像你的文本编辑器这样的导航命令:
set -o emacs
Run Code Online (Sandbox Code Playgroud)
或者
set -o vi
Run Code Online (Sandbox Code Playgroud)
将允许您搜索您的历史记录并以您习惯于在文本文件中执行的方式在命令行中移动(例如,在 vi 模式下,按ESC然后键入/string将搜索您以前的命令以查找“字符串”-您可以使用n和N移动比赛之间)
小智 8
grep 是我的朋友。严重地。
列出.rb包含文本的文件class foo:
grep -l "class foo" .rb
Run Code Online (Sandbox Code Playgroud)
列出.rb的文件不包含文本class foo:
grep -L "class foo" *.rb
Run Code Online (Sandbox Code Playgroud)
列出.rb的文件不包含富或酒吧(你可以使用任何正则表达式与-e,但你需要躲避运营商):
grep -L -e "foo\|bar" *.rb
Run Code Online (Sandbox Code Playgroud)
小智 8
外壳替换是通过^以下方式执行的:
/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
Run Code Online (Sandbox Code Playgroud)
$_ 是上一个命令中最后一个参数的环境变量
所以如果我创建一个新目录
$ mkdir ~/newdir/
Run Code Online (Sandbox Code Playgroud)
进入我只是去
$ cd $_
Run Code Online (Sandbox Code Playgroud)
这对于复杂的大文本非常方便,例如 URL、目录、长文件名等。
您还可以使用以下命令引用上一个命令中的每个参数 !:{number}
$ echo !:0 !:1 !:2
Run Code Online (Sandbox Code Playgroud)
请注意,bash 会在您执行它之前展开它(查看此按钮以查看您的历史记录)。
$ touch one two three
$ ls !:1 !:2 !:3
Run Code Online (Sandbox Code Playgroud)
与$_which 是环境变量不同,这将扩展为“ls 一二三”,执行操作并将命令打印到 shell。这种方法比$_我更频繁使用的方法更难使用(在我看来)。
注意:您也可以使用 !$ 代替 $_ 但前者会扩展
小智 6
有一个关于使用pushd/popd记住目录的答案。如果你想临时访问某个目录,你可以使用cd -命令来保存输入,如下所示:
/home/eugene $ cd /etc
/etc $ cd -
/home/eugene $
Run Code Online (Sandbox Code Playgroud)
此外,我最喜欢的命令之一是xargs. 我经常将它与 一起使用find,但它在其他情况下也很方便。例如,要查找用于启动某个进程的命令行参数,您可以在 linux 上使用以下命令:
$ xargs -0 echo < /proc/[PID]/cmdline
Run Code Online (Sandbox Code Playgroud)
在某些情况下(尤其是在使用源代码时),ack比grep因为它自动递归搜索并忽略备份文件和版本控制目录(如 .svn、.hg)更方便。不再输入像find . -name \*.c | xargs grep 'frobnicate'.
我今天从朋友那里看到的一个很好的。
清理应用程序的日志(用于下次启动和合作)
> /var/log/appname.log
Run Code Online (Sandbox Code Playgroud)
(注意>是命令的一部分)。
这与执行以下操作相同:
echo '' > /var/log/appname.log
Run Code Online (Sandbox Code Playgroud)
cut和grep是管理纯文本文件的一种非常好的方式。你可以检索任何你想要的。cut允许您“垂直”拆分文件,并grep允许您“水平”拆分文件。
下面的句子将拆分所有行,;只返回 1 和 3。
$cut -d ';' -f 1,3 hello.txt
Run Code Online (Sandbox Code Playgroud)
使用grep(一个众所周知的命令),您可以对行执行相同的操作。以下句子将忽略您不感兴趣的行:
$grep error hello.txt
Run Code Online (Sandbox Code Playgroud)
grep 也可以用于反向:忽略与模式不匹配的行,您也可以使用正则表达式。
但两者中最强大的是使用管道。例如:
$grep error hello.txt | cut d ':' -f1,3 | cut -d' ' -f1
Run Code Online (Sandbox Code Playgroud)