我们都知道如何使用 <ctrl>-R 通过历史反向搜索,但你知道你可以使用 <ctrl>-S 如果您设置,则转发搜索 stty stop ""?另外,您是否尝试过运行 bind -p 来查看列出的所有键盘快捷键?Mac OS X 上默认有超过 455 个。

您最喜欢的晦涩难懂的技巧、键盘快捷键或使用 bash 的 shopt 配置是什么?

有帮助吗?

解决方案 7

运行命令时,有时我想使用前面的参数运行命令。为此,您可以使用以下快捷方式:

$ mkdir /tmp/new
$ cd !!:*

有时,如果我需要在文件列表上运行一堆命令,我会打破单行循环来代替使用 find。

for file in *.wav; do lame "$file" "$(basename "$file" .wav).mp3" ; done;

在我的 .bash_login (或 .bashrc)中配置命令行历史选项非常有用。以下是我在 Macbook Pro 上使用的一系列设置。

设置以下内容可以使 bash 删除历史记录中的重复命令:

export HISTCONTROL="erasedups:ignoreboth"

我也把我的历史记录调得很高。为什么不?它似乎并没有减慢当今微处理器的速度。

export HISTFILESIZE=500000
export HISTSIZE=100000

我做的另一件事是忽略我的历史记录中的一些命令。无需记住退出命令。

export HISTIGNORE="&:[ ]*:exit"

你肯定想设置 histappend。否则,退出时 bash 会覆盖您的历史记录。

shopt -s histappend

我使用的另一个选项是cmdhist。这使您可以将多行命令作为一条命令保存到历史记录中。

shopt -s cmdhist

最后,在 Mac OS X 上(如果您不使用 vi 模式),您需要将 <CTRL>-S 重置为滚动停止。这会阻止 bash 将其解释为正向搜索。

stty stop ""

其他提示

快速重命名/移动带有后缀的文件:
cp /home/foo/realllylongname.cpp{,-old}

这扩展到:
cp /home/foo/realllylongname.cpp /home/foo/realllylongname.cpp-old

cd -

它是相当于后退按钮的命令行(将您带到您所在的上一个目录)。

另一个最喜欢的:

!!

重复您的上一个命令。最有用的形式:

sudo !!

我最喜欢的是“^string^string2”,它接受最后一个命令,用 string2 替换 string 并执行它

$ ehco foo bar baz
bash: ehco: command not found
$ ^ehco^echo
foo bar baz

Bash 命令行历史指南

改名

例子:

$ 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

太有用了

我是 的粉丝 !$, !^!* 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

当你说时,这会派上用场 ls filea fileb, ,并想要编辑其中之一: vi !$ 或两者都: vimdiff !*. 。也可以概括为“ n第一个参数”就像这样:

$ echo foo bar baz
$ echo !:2
echo bar
bar

最后,使用路径名,您可以通过附加来获取路径的一部分 :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

如何列出 仅有的 当前目录中的子目录 ?

ls -d */

这是一个简单的技巧,但你不会知道我需要多少时间才能找到它!

ESC键.

插入最后一个 bash 命令的最后一个参数。它比你想象的更方便。

cp file /to/some/long/path

光盘 ESC键.

你当然可以 ”diff file1.txt file2.txt",但 Bash 支持 流程替代, ,这使您可以 diff 命令的输出。

例如,假设我想确保我的脚本提供我期望的输出。我可以将我的脚本包装在 <( ) 中并将其提供给 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
$

再举一个例子,假设我想检查两台服务器是否安装了相同的 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
$

在高级弹拨手指南中还有更多示例 http://tldp.org/LDP/abs/html/process-sub.html.

我最喜欢的命令是“ls -thor”

它召唤出 众神的力量 以方便可读的格式列出最近修改的文件。

更多的是新奇,但它很聪明......

最常用的 10 个命令:

$ history | awk '{print $2}' | awk 'BEGIN {FS="|"}{print $1}' | sort | uniq -c | sort -nr | head

示例输出:

 242 git
  83 rake
  43 cd
  33 ss
  24 ls
  15 rsg
  11 cap
  10 dig
   9 ping
   3 vi

^R反向搜索。按 ^R,键入要匹配的上一个命令的片段,然后按 ^R 直到找到所需的命令。这样我就不必记住仍然在我的历史记录中的最近使用的命令。不仅是 bash,还包括:^E 表示行尾,^A 表示行首,^U 和 ^K 分别删除光标之前和之后的内容。

我经常使用 vi、ls 等别名。但有时你想转义别名。只需在前面的命令中添加一个反斜杠即可:

例如:

$ alias vi=vim
$ # To escape the alias for vi:
$ \vi # This doesn't open VIM

很酷,不是吗?

以下是一些配置调整:

~/.inputrc:

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

这与以下操作相同 ^R 但改用箭头键。这意味着我可以输入(例如) cd /media/ 然后按向上箭头转到我的最后一件事 cd到里面 /media/ 文件夹。

(我使用 Gnome 终端,您可能需要更改其他终端模拟器的转义码。)

Bash 补全也非常有用,但它是一个更微妙的补充。在 ~/.bashrc:

if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
fi

这将启用每个程序的制表符完成功能(例如当命令行以以下字符开头时尝试制表符补全 evince 只会显示 evince 可以打开的文件,并且还会使用制表符完成命令行选项)。

也可以很好地与此配合使用 ~/.inputrc:

set completion-ignore-case on
set show-all-if-ambiguous on
set show-all-if-unmodified on

我经常使用以下内容:

:p 修改器打印历史结果。例如。

!!:p

将打印最后一个命令,以便您可以在再次运行之前检查它是否正确。只需输入 !! 来执行它。

与此相类似:

!?foo?:p

将在您的历史记录中搜索包含字符串“foo”的最新命令并打印它。

如果不需要打印的话

!?foo

进行搜索并立即执行。

我有一个秘密武器: 贝壳福。

有数千个聪明的技巧、酷炫的技巧和高效的食谱,大多数时候都可以在一行中找到。

我喜欢的一个(但我有点作弊,因为我现在大多数 Unix 系统上都安装了 Python):

alias webshare='python -m SimpleHTTPServer'

现在,每次您键入“webshare”时,都可以通过端口 8000 访问当前目录。当您想与本地网络上的朋友共享文件而无需 USB 密钥或远程目录时,这真的很好。流媒体视频和音乐也可以。

当然还有经典的叉子炸弹,它完全没用,但仍然很有趣:

$ :(){ :|:& };:

不要在生产服务器中尝试这样做......

您可以将 watch 命令与另一个命令结合使用来查找更改。一个例子是,当我测试路由器时,我想获得信噪比等方面的最新数据。

watch --interval=10 lynx -dump http://dslrouter/stats.html
type -a PROG

为了找到所有可用的prog的地方,通常在〜/bin的某个地方,而不是预期的/usr/bin/preg中的一个。

我喜欢用以下方式构建命令 回声 并将它们通过管道传输到 shell:

$ find dir -name \*~ | xargs echo rm
...
$ find dir -name \*~ | xargs echo rm | ksh -s

为什么?因为它可以让我在做之前先看看要做什么。这样,如果我遇到可怕的错误(例如删除我的主目录),我可以在它发生之前捕获它。显然,这对于破坏性或不可撤销的行为最为重要。

下载大文件时我经常这样做:

while ls -la <filename>; do sleep 5; done

然后当我完成后只需按 ctrl+c (或者如果 ls 返回非零)。它类似于 watch 程序,但它使用 shell,因此它可以在没有 watch.

另一个有用的工具是 netcat,或者 nc. 。如果你这样做:

nc -l -p 9100 > printjob.prn

然后,您可以在另一台计算机上设置打印机,但使用运行 netcat 的计算机的 IP 地址。当发送打印作业时,它被运行 netcat 的计算机接收并转储到 printjob.prn.

pushdpopd 几乎总是派上用场

当我在树层次结构中广泛分散的位置使用多个目录时,一种首选的导航方式是使用 acf_func.sh(如下所列)。一旦定义,你可以做

光盘 -

查看最近的目录列表,带有数字菜单

光盘-2

转到第二个最近的目录。

使用非常方便,非常方便。

这是代码:

# do ". acd_func.sh"
# acd_func 1.0.5, 10-nov-2004
# petar marinov, http:/geocities.com/h2428, this is public domain

cd_func ()
{
  local x2 the_new_dir adir index
  local -i cnt

  if [[ $1 ==  "--" ]]; then
    dirs -v
    return 0
  fi

  the_new_dir=$1
  [[ -z $1 ]] && the_new_dir=$HOME

  if [[ ${the_new_dir:0:1} == '-' ]]; then
    #
    # Extract dir N from dirs
    index=${the_new_dir:1}
    [[ -z $index ]] && index=1
    adir=$(dirs +$index)
    [[ -z $adir ]] && return 1
    the_new_dir=$adir
  fi

  #
  # '~' has to be substituted by ${HOME}
  [[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}"

  #
  # Now change to the new dir and add to the top of the stack
  pushd "${the_new_dir}" > /dev/null
  [[ $? -ne 0 ]] && return 1
  the_new_dir=$(pwd)

  #
  # Trim down everything beyond 11th entry
  popd -n +11 2>/dev/null 1>/dev/null

  #
  # Remove any other occurence of this dir, skipping the top of the stack
  for ((cnt=1; cnt <= 10; cnt++)); do
    x2=$(dirs +${cnt} 2>/dev/null)
    [[ $? -ne 0 ]] && return 0
    [[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
    if [[ "${x2}" == "${the_new_dir}" ]]; then
      popd -n +$cnt 2>/dev/null 1>/dev/null
      cnt=cnt-1
    fi
  done

  return 0
}

alias cd=cd_func

if [[ $BASH_VERSION > "2.05a" ]]; then
  # ctrl+w shows the menu
  bind -x "\"\C-w\":cd_func -- ;"
fi

在按下可怕的回车键之前展开复杂的线条

  • 替代+控制键+eshell 扩展行 (可能需要使用 Esc键, 控制键+e 在你的键盘上)
  • 控制键+_撤消
  • 控制键+X, *全局扩展字

$ echo !$ !-2^ * 替代+控制键+e
$ echo aword someotherword * 控制键+_
$ echo !$ !-2^ * 控制键+X, *
$ echo !$ !-2^ LOG Makefile bar.c foo.h

&C。

我一直偏向:

ctrl-E # move cursor to end of line
ctrl-A # move cursor to beginning of line

我也用 shopt -s cdable_vars, ,然后您可以为公共目录创建 bash 变量。因此,对于我公司的源代码树,我创建了一堆变量,例如:

export Dcentmain="/var/localdata/p4ws/centaur/main/apps/core"

然后我可以通过更改到该目录 cd Dcentmain.

pbcopy

这将复制到 Mac 系统剪贴板。您可以通过管道向它发送命令...尝试:

pwd | pbcopy

$ touch {1,2}.txt
$ ls [12].txt
1.txt  2.txt
$ rm !:1
rm [12].txt
$ history | tail -10
...
10007  touch {1,2}.txt
...
$ !10007
touch {1,2}.txt
$ for f in *.txt; do mv $f ${f/txt/doc}; done

从命令行使用“set -o vi”,或者更好的是在 .bashrc 中使用,可以使您在命令行上进入 vi 编辑模式。您从“插入”模式开始,这样您就可以像平常一样键入和退格,但如果您犯了“大”错误,您可以按 esc 键,然后使用“b”和“f”像在 vi 中一样移动。CW 改变一个词。在您调出要更改的历史命令后特别有用。

与上面的许多类似,我目前最喜欢的是按键 [alt]。(Alt 和“.”键一起)这与 $ 相同!(插入上一个命令的最后一个参数)除了它是立即的并且对我来说更容易键入。(只是不能在脚本中使用)

例如:

mkdir -p /tmp/test/blah/oops/something
cd [alt].

使用将多个命令串在一起 && 命令:

./run.sh && tail -f log.txt

或者

kill -9 1111 && ./start.sh
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top