使用 Bash 时您最喜欢的命令行技巧是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/68372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is your single most favorite command-line trick using Bash?
提问by hoyhoy
We all know how to use <ctrl>-R
to reverse search through history, but did you know you can use <ctrl>-S
to forward search if you set stty stop ""
? Also, have you ever tried running bind -p to see all of your keyboard shortcuts listed? There are over 455 on Mac OS X by default.
我们都知道如何使用<ctrl>-R
反向搜索历史记录,但是您知道<ctrl>-S
如果设置可以使用正向搜索stty stop ""
吗?另外,您是否尝试过运行 bind -p 来查看列出的所有键盘快捷键?默认情况下,Mac OS X 上有超过 455 个。
What is your single most favorite obscure trick, keyboard shortcut or shopt configuration using bash?
使用 bash 时,您最喜欢的晦涩技巧、键盘快捷键或 shopt 配置是什么?
采纳答案by hoyhoy
When running commands, sometimes I'll want to run a command with the previous ones arguments. To do that, you can use this shortcut:
运行命令时,有时我想运行一个带有前面参数的命令。为此,您可以使用此快捷方式:
$ mkdir /tmp/new
$ cd !!:*
Occasionally, in lieu of using find, I'll break-out a one-line loop if I need to run a bunch of commands on a list of files.
有时,如果我需要在文件列表上运行一堆命令,我会中断单行循环而不是使用 find。
for file in *.wav; do lame "$file" "$(basename "$file" .wav).mp3" ; done;
Configuring the command-line history options in my .bash_login (or .bashrc) is really useful. The following is a cadre of settings that I use on my Macbook Pro.
在我的 .bash_login(或 .bashrc)中配置命令行历史选项非常有用。以下是我在 Macbook Pro 上使用的一组设置。
Setting the following makes bash erase duplicate commands in your history:
设置以下内容会使 bash 擦除历史记录中的重复命令:
export HISTCONTROL="erasedups:ignoreboth"
I also Hyman my history size up pretty high too. Why not? It doesn't seem to slow anything down on today's microprocessors.
我也将我的历史记录大小设置得相当高。为什么不?在今天的微处理器上,它似乎并没有减慢任何速度。
export HISTFILESIZE=500000
export HISTSIZE=100000
Another thing that I do is ignore some commands from my history. No need to remember the exit command.
我做的另一件事是忽略我历史上的一些命令。无需记住退出命令。
export HISTIGNORE="&:[ ]*:exit"
You definitely want to set histappend. Otherwise, bash overwrites your history when you exit.
你肯定想设置 histappend。否则,bash 会在您退出时覆盖您的历史记录。
shopt -s histappend
Another option that I use is cmdhist. This lets you save multi-line commands to the history as one command.
我使用的另一个选项是 cmdhist。这使您可以将多行命令作为一个命令保存到历史记录中。
shopt -s cmdhist
Finally, on Mac OS X (if you're not using vi mode), you'll want to reset <CTRL>-S from being scroll stop. This prevents bash from being able to interpret it as forward search.
最后,在 Mac OS X 上(如果您不使用 vi 模式),您需要重置 <CTRL>-S 使其不再滚动停止。这可以防止 bash 将其解释为前向搜索。
stty stop ""
回答by user10765
Renaming/moving files with suffixes quickly:cp /home/foo/realllylongname.cpp{,-old}
快速重命名/移动带有后缀的文件:cp /home/foo/realllylongname.cpp{,-old}
This expands to:cp /home/foo/realllylongname.cpp /home/foo/realllylongname.cpp-old
这扩展为:cp /home/foo/realllylongname.cpp /home/foo/realllylongname.cpp-old
回答by Mark Biek
cd -
It's the command-line equivalent of the back button (takes you to the previous directory you were in).
它是与后退按钮等效的命令行(将您带到您所在的上一个目录)。
回答by amrox
Another favorite:
另一个最爱:
!!
Repeats your last command. Most useful in the form:
重复你的最后一个命令。最有用的形式:
sudo !!
回答by seth
My favorite is '^string^string2' which takes the last command, replaces string with string2 and executes it
我最喜欢的是 '^string^string2' 它接受最后一个命令,用 string2 替换 string 并执行它
$ ehco foo bar baz
bash: ehco: command not found
$ ^ehco^echo
foo bar baz
回答by Jiaaro
rename
改名
Example:
例子:
$ ls
this_has_text_to_find_1.txt
this_has_text_to_find_2.txt
this_has_text_to_find_3.txt
this_has_text_to_find_4.txt
$ rename 's/text_to_find/been_renamed/' *.txt
$ ls
this_has_been_renamed_1.txt
this_has_been_renamed_2.txt
this_has_been_renamed_3.txt
this_has_been_renamed_4.txt
So useful
太有用了
回答by Alex M
I'm a fan of the !$
, !^
and !*
expandos, returning, from the most recent submitted command line: the last item, first non-command item, and all non-command items. To wit (Note that the shell prints out the command first):
我是!$
,!^
和!*
expandos的粉丝,从最近提交的命令行返回:最后一个项目、第一个非命令项目和所有非命令项目。即(注意 shell 先打印出命令):
$ echo foo bar baz
foo bar baz
$ echo bang-dollar: !$ bang-hat: !^ bang-star: !*
echo bang-dollar: baz bang-hat: foo bang-star: foo bar baz
bang-dollar: baz bang-hat: foo bang-star: foo bar baz
This comes in handy when you, say ls filea fileb
, and want to edit one of them: vi !$
or both of them: vimdiff !*
. It can also be generalized to "the n
th argument" like so:
当您说ls filea fileb
,并且想要编辑其中之一:vi !$
或两者时,这会派上用场:vimdiff !*
。它也可以推广到“ n
th 参数”,如下所示:
$ echo foo bar baz
$ echo !:2
echo bar
bar
Finally, with pathnames, you can get at parts of the path by appending :h
and :t
to any of the above expandos:
最后,使用路径名,您可以通过将:h
和添加:t
到上述任何扩展中来获取路径的一部分:
$ ls /usr/bin/id
/usr/bin/id
$ echo Head: !$:h Tail: !$:t
echo Head: /usr/bin Tail: id
Head: /usr/bin Tail: id
回答by edomaur
How to list onlysubdirectories in the current one ?
如何仅列出当前目录中的子目录?
ls -d */
It's a simple trick, but you wouldn't know how much time I needed to find that one !
这是一个简单的技巧,但你不会知道我需要多少时间才能找到那个!
回答by amrox
ESC.
ESC.
Inserts the last arguments from your last bash command. It comes in handy more than you think.
插入最后一个 bash 命令的最后一个参数。它比你想象的更有用。
cp file /to/some/long/path
cd ESC.
光盘 ESC.
回答by Philip Durbin
Sure, you can "diff file1.txt file2.txt
", but Bash supports process substitution, which allows you to diff
the output of commands.
当然,您可以“ diff file1.txt file2.txt
”,但 Bash 支持进程替换,它允许您diff
输出命令。
For example, let's say I want to make sure my script gives me the output I expect. I can just wrap my script in <( ) and feed it to diff
to get a quick and dirty unit test:
例如,假设我想确保我的脚本提供我期望的输出。我可以将我的脚本包装在 <( ) 中并将其提供给它diff
以获得快速而肮脏的单元测试:
$ cat myscript.sh
#!/bin/sh
echo -e "one\nthree"
$
$ ./myscript.sh
one
three
$
$ cat expected_output.txt
one
two
three
$
$ diff <(./myscript.sh) expected_output.txt
1a2
> two
$
As another example, let's say I want to check if two servers have the same list of RPMs installed. Rather than sshing to each server, writing each list of RPMs to separate files, and doing a diff
on those files, I can just do the diff
from my workstation:
再举一个例子,假设我想检查两台服务器是否安装了相同的 RPM 列表。而不是 SSH 到每个服务器,将每个 RPM 列表写入单独的文件,并diff
在这些文件上执行,我可以diff
从我的工作站执行:
$ diff <(ssh server1 'rpm -qa | sort') <(ssh server2 'rpm -qa | sort')
241c240
< kernel-2.6.18-92.1.6.el5
---
> kernel-2.6.18-92.el5
317d315
< libsmi-0.4.5-2.el5
727,728d724
< wireshark-0.99.7-1.el5
< wireshark-gnome-0.99.7-1.el5
$
There are more examples in the Advanced Bash-Scripting Guide at http://tldp.org/LDP/abs/html/process-sub.html.
在http://tldp.org/LDP/abs/html/process-sub.html的 Advanced Bash-Scripting Guide 中有更多示例。