我们都知道如何使用<ctrl>-R
反向搜索历史,但你知道<ctrl>-S
如果你设置了你可以使用前向搜索stty stop ""
吗?另外,您是否尝试过运行 bind -p 来查看列出的所有键盘快捷键?默认情况下,Mac OS X 上有超过 455 个。
您最喜欢使用 bash 的一个不起眼的技巧、键盘快捷键或 shopt 配置是什么?
我们都知道如何使用<ctrl>-R
反向搜索历史,但你知道<ctrl>-S
如果你设置了你可以使用前向搜索stty stop ""
吗?另外,您是否尝试过运行 bind -p 来查看列出的所有键盘快捷键?默认情况下,Mac OS X 上有超过 455 个。
您最喜欢使用 bash 的一个不起眼的技巧、键盘快捷键或 shopt 配置是什么?
快速重命名/移动带有后缀的文件:
cp /home/foo/realllylongname.cpp{,-old}
这扩展为:
cp /home/foo/realllylongname.cpp /home/foo/realllylongname.cpp-old
cd -
它是后退按钮的命令行等效项(将您带到您所在的上一个目录)。
另一个最爱:
!!
重复上一个命令。最有用的形式:
sudo !!
我最喜欢的是 '^string^string2',它采用最后一个命令,用 string2 替换字符串并执行它
$ ehco foo bar baz
bash: ehco: command not found
$ ^ehco^echo
foo bar baz
改名
例子:
$ 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
th 论点”,如下所示:
$ 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
运行命令时,有时我会想使用前面的参数运行命令。为此,您可以使用以下快捷方式:
$ 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 ""
如何仅列出当前目录中的子目录?
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的 Advanced Bash-Scripting Guide 中有更多示例。
我最喜欢的命令是“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
进行搜索并立即执行。
我有一个秘密武器:shell-fu。
有数以千计的聪明技巧、酷技巧和有效的食谱,大多数时候都放在一条线上。
我喜欢的一个(但我有点作弊,因为我现在大多数 Unix 系统上都安装了 Python):
alias webshare='python -m SimpleHTTPServer'
现在每次键入“webshare”时,当前目录都将通过端口 8000 可用。当您想在本地网络上与朋友共享文件时,无需 USB 密钥或远程目录,这真是太好了。流媒体视频和音乐也可以。
当然还有经典的叉子炸弹,它完全没用,但仍然很有趣:
$ :(){ :|:& };:
不要在生产服务器中尝试...
您可以将 watch 命令与另一个命令结合使用来查找更改。这方面的一个例子是当我测试我的路由器时,我想获得关于信噪比等内容的最新数字。
watch --interval=10 lynx -dump http://dslrouter/stats.html
我喜欢用echo构造命令并将它们传送到 shell:
$ find dir -name \*~ | xargs echo rm
...
$ find dir -name \*~ | xargs echo rm | ksh -s
为什么?因为它允许我在做之前先看看要做什么。这样,如果我有一个可怕的错误(比如删除我的主目录),我可以在它发生之前抓住它。显然,这对于破坏性或不可撤销的行为最为重要。
type -a PROG
为了找到 PROG 可用的所有位置,通常在 ~/bin 中的某个位置,而不是 /usr/bin/PROG 中可能预期的位置。
下载大文件时,我经常这样做:
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
.
pushd
几乎popd
总是派上用场
当我在树层次结构中广泛分离的位置使用多个目录时,一种首选的导航方式是使用 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
$ echo !$ !-2^ *
Alt+ Ctrl+ e
$ echo aword someotherword *
Ctrl+ _
$ echo !$ !-2^ *
Ctrl+ 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 改变一个词。在您提出要更改的历史命令后特别有用。
使用&&命令将多个命令串在一起:
./run.sh && tail -f log.txt
或者
kill -9 1111 && ./start.sh
与上述许多类似,我目前最喜欢的是击键 [alt]。(Alt 和“.”键一起使用)这与 $! (插入上一个命令的最后一个参数)除了它是直接的并且对我来说更容易输入。(只是不能在脚本中使用)
例如:
mkdir -p /tmp/test/blah/oops/something
cd [alt].
重复文件查找器
这将从当前目录递归运行校验和,并返回所有相同校验和结果的文件名:
find ./ -type f -print0 | xargs -0 -n1 md5sum | sort -k 1,32 | uniq -w 32 -d --all-repeated=separate | sed -e 's/^[0-9a-f]*\ *//;'
当然,您可以更改路径。
也许将其放入函数或别名中,并将目标路径作为参数传入。
!
<命令的前几个字符> 将执行匹配的最后一个命令。
例子:
!b
将运行“构建任何 -O -p -t -i -on”
!.
将运行./a.out
它最适用于冗长且重复的命令,例如编译、构建、执行等。它在编码和测试时为我节省了很多时间。
我有很多我想快速访问的目录,CDPATH
变量是极大地加快我的工作流程的解决方案:
export CDPATH=.:/home/gadolin/sth:/home/gadolin/dir1/importantDir
现在cd
我可以跳转到任何子目录/home/gadolin/sth
或/home/gadolin/dir1/importantDir
不提供完整路径。也在<tab>
这里工作,就像我在那里一样!因此,如果有目录/home/gadolin/sth/1
/home/gadolin/sth/2
,我cd 1
在任何地方输入,我就在那里。
Ctrl+L通常会清除屏幕。在 Bash 提示符(显然)和GDB以及许多其他提示符下工作。
您应该能够将以下内容粘贴到 bash 终端窗口中。
显示 ANSI 调色板:
e="\033["
for f in 0 7 `seq 6`; do
no="" bo=""
for b in n 7 0 `seq 6`; do
co="3$f"; p=" "
[ $b = n ] || { co="$co;4$b";p=""; }
no="${no}${e}${co}m ${p}${co} ${e}0m"
bo="${bo}${e}1;${co}m ${p}1;${co} ${e}0m"
done
echo -e "$no\n$bo"
done
256色演示:
yes "$(seq 232 255;seq 254 -1 233)" |
while read i; do printf "\x1b[48;5;${i}m\n"; sleep .01; done
删除除 重要文件之外的所有内容:
# shopt -s extglob
# rm -rf !(important-file)
在zsh中相同:
# rm -rf *~important-file
之前我知道我必须将重要的字段移到另一个字典中,删除所有内容并再次将重要的字段移回。
使用历史替换字符!#
来访问当前命令行,结合^
,$
等。
例如,将带有“old-”前缀的文件移开:
mv file-with-long-name-typed-with-tab-completion.txt old-!#^
好吧,这可能有点跑题了,但是如果您是 Emacs 用户,我会说“emacs”是最强大的技巧...在您对此投反对票之前,请在 emacs 实例中尝试“Mx shell”...您在 emacs 中获得了一个 shell,并拥有 emacs 的所有功能以及 shell 的功能(有一些限制,例如在其中打开另一个 emacs,但在大多数情况下,它比 vanilla bash 提示更强大)。
我喜欢在我的提示中加入一点色彩:
export PS1="\[\033[07;31m\] \h \[\033[47;30m\] \W \[\033[00;31m\] \$ \[\e[m\]"
恐怕我没有关于它的截图,但它应该是这样的(全部在一条线上):
[RED BACK WHITE TEXT] Computer name
[BLACK BACK WHITE TEXT] Working Directory
[WHITE BACK RED TEXT] $
根据您喜欢看到的内容进行自定义:)
作为 CTRL-r 向后搜索的扩展,如果绑定“history-search-backward”,您可以使用历史记录自动完成当前输入。我通常将它绑定到它在 tcsh 中的相同键:ESC-p。您可以通过在 .inputrc 文件中添加以下行来执行此操作:
"\M-p": history-search-backward
例如,如果您之前执行过“make some_really_painfully_long_target”,您可以输入:
> make <ESC p>
它会给你
> make some_really_painfully_long_target
当你意识到你刚刚输入了错误的行时,要做的一件简单的事情就是按下 Ctrl+C;如果您想保留该行,但需要先执行其他操作,请以反斜杠 - \ 开始新行,然后按 Ctrl+C。该行将保留在您的历史记录中。
插入前几行最终参数
ALT-. 有史以来最有用的组合键,试试看,不知为何没人知道这个组合。
一次又一次地按下它以选择较旧的最后一个参数。
当您想对刚才使用的东西做其他事情时,这很棒。
花括号展开:
在运行./configure
带有很多选项的 a 时真的很方便:
./configure --{prefix=/usr,mandir=/usr/man,{,sh}libdir=/usr/lib64,\
enable-{gpl,pthreads,bzlib,lib{faad{,bin},mp3lame,schroedinger,speex,theora,vorbis,xvid,x264},\
pic,shared,postproc,avfilter{-lavf,}},disable-static}
这实际上是我对 ffmpeg 的配置设置。没有大括号,它是 409 个字符。
或者,甚至更好:
echo "I can count to a thousand!" ...{0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}...
我在别名中有各种印刷错误更正
alias mkae=make
alias mroe=less
“最后一个命令的最后一个参数”对我来说最简单的击键是!$
echo what the heck?
what the heck?
echo !$
heck?
$_
(美元下划线):上一个命令的最后一个单词。类似于,!$
除了它不会像它那样将它的替换放在你的历史记录!$
中。
不是很晦涩,但我绝对喜欢的功能之一是制表符补全。
当您在整个子树结构中导航时,或者当您使用一些晦涩或长命令时,它真的很有用!
CTRL+D退出外壳。
使用别名可以节省时间
alias myDir = "cd /this/is/a/long/directory; pwd"
我是 Bash作业控制的忠实粉丝,主要是使用Control-Z
and fg
,尤其是当我在终端中进行开发时。如果我打开了 emacs 并需要编译、部署等。我只是Control-Z
暂停 emacs,做我需要的,然后fg
将其恢复。这使所有 emacs 缓冲区保持完整,并且比重新启动我正在做的任何事情都容易得多。
alias ..='cd ..'
因此,在导航备份目录时,只需使用..<Enter>
SSH隧道:
ssh -fNR 1234:localhost:22 root@123.123.123.123
不是我最喜欢的,如果您使用复制和粘贴尝试任何其他答案,这将非常有帮助:
function $
{
"$@"
}
$
现在您可以粘贴在每行开头包含提示的示例。
bash 可以重定向到 TCP/IP 套接字。/dev/tcp/ 和 /dev/udp。
有些人认为这是一个安全问题,但这就是像 Solaris X 的监狱这样的操作系统级别的安全性。
正如 Will Robertson 所说,更改提示符以执行操作... print the command # for !nn 设置 Xterm 终端名称。如果它是一个旧的 Xterm,它不会嗅探流量来设置它的标题。
这实际上对我来说很关键:
设置-o vi
/艾伦
我一直很喜欢这个。将此添加到您的 /etc/inputrc 或 ~/.inputrc
"\e[A":history-search-backward "\e[B":history-search-forward
当您键入ls <up-arrow>
时,它将被最后一个以“ls”开头的命令或您输入的任何其他命令替换。
这可以防止更少(少即是多)在文件末尾清除屏幕:
export LESS="-X"
在两个单独的目录之间导航并来回复制文件时,我这样做:
cd /some/where/long
src=`pwd`
cd /other/where/long
dest=`pwd`
cp $src/foo $dest
command completion will work by expanding the variable, so you can use tab completion to specify a file you're working with.
<任何东西> | 排序 | 唯一的-c | 排序 -n
将为您提供 <anything> 的所有不同出现次数。
通常,awk、sed 或 cut 有助于解析 <anything> 中的数据。
杜-a | 排序-n | 尾-99
查找要清理的大文件(或文件目录)以释放磁盘空间。
几年前,我发现了p*命令或获取有关进程的信息:ptree、pgrep、pkill和pfiles。当然,它们的母亲都是ps,但是您需要将输出通过管道传输到less、grep和/或awk以了解重负载下的输出。 顶部(和变体)也有帮助。
想要获取日志文件的最后几行?
tail /var/log/syslog
想要密切关注日志文件何时发生变化?
tail -f /var/log/syslog
想从一开始就快速读取文件吗?
more /var/log/syslog
想要快速查找文件是否包含一些文本?
grep "find this text" /var/log/syslog
当您希望 TAB 完成忽略具有某些后缀的文件或文件夹时,FIGNORE 环境变量非常有用,例如:
export FIGNORE="CVS:.svn:~"
如果要定义除空格以外的项目分隔符,请使用 IFS 环境变量,例如:
export IFS="
"
这将使您能够在不执行任何魔术的情况下循环浏览带有空格的文件和文件夹,如下所示:
$ touch "with spaces" withoutspaces
$ for i in `ls *`; do echo $i; done
with
spaces
withoutspaces
$ IFS="
"
$ for i in `ls *`; do echo $i; done
with spaces
withoutspaces
适合对包含符号链接的目录进行精确的递归复制/备份(而不是像 cp 一样跟随它们或忽略它们):
$ mkdir new_dir
$ cd old_dir
$ tar cf - . | ( cd ../old_dir; tar xf - )
再次排名前 10 的命令(如ctcherry的帖子,只是更短):
history | awk '{ print $2 }' | sort | uniq -c |sort -rn | head
我是在 mac 上编程的新手,我想念能够从 bash 启动 gui 程序......所以我必须创建这样的函数:
function macvim
{
/Applications/MacVim.app/Contents/MacOS/Vim "$@" -gp &
}
while IFS= read -r line; do
echo "$line"
done < somefile.txt
这是逐行处理文件的好方法。需要清除 IFS 以获取行首或行尾的空白字符。需要“-r”来获取所有原始字符,包括反斜杠。
一些 Bash 掘金也在这里:
我最喜欢的 bash 技巧之一是“tar pipe”。当你有大量的文件要从一个目录复制到另一个目录时,如果文件数量太高并爆炸 bash globber,则执行“cp * /an/other/dir”将不起作用,因此,tar 管道:
(cd /path/to/source/dir/ ; tar cf - * ) | (cd /path/to/destination/ ; tar xf - )
...如果你有netcat,你甚至可以通过网络做“netcat tar pipe”!
在导航深度树结构时,我有一个非常愚蠢但非常有用的方法。把它放在 .bashrc (或类似的)中:
alias cd6="cd ../../../../../.."
alias cd5="cd ../../../../.."
alias cd4="cd ../../../.."
alias cd3="cd ../../.."
alias cd2="cd ../.."
在 Mac OS X 上,
ESC .
将循环浏览最近的论点。即:按下并释放ESC
,然后按下并释放.
(句点键)。在 Ubuntu 上,我认为它是ALT+.
.
您可以多次这样做,以回顾您最近的所有论点。有点像CTRL+ R,但仅用于参数。它也比!!
or更安全$!
,因为您在实际运行命令之前就看到了将要得到的结果。
sudo !!
以管理员权限运行最后一个命令。
Shell-fu是一个存储、调整和传播命令行提示和技巧的地方。有点像 StackOverflow,但仅适用于 shell。你会在那里找到很多这个问题的答案。
因为我总是需要这个for i in $(ls)
声明,所以我做了一个捷径:
fea(){
if test -z ${2:0:1}; then action=echo; else action=$2; fi
for i in $(ls $1);
do $action $i ;
done;
}
另一个是:
echo ${!B*}
它将打印以“B”开头的所有已定义变量的列表。
ctrl-u 删除所有写的东西
快速文本
我经常使用这些文本序列,所以我把它们的快捷方式放在了.inputrc
:
# redirection short cuts
"\ew": "2>&1"
"\eq": "&>/dev/null &"
"\e\C-q": "2>/dev/null"
"\eg": "&>~/.garbage.out &"
"\e\C-g": "2>~/.garbage.out"
$if term=xterm
"\M-w": "2>&1"
"\M-q": "&>/dev/null &"
"\M-\C-q": "2>/dev/null"
"\M-g": "&>~/.garbage.out &"
"\M-\C-g": "2>~/.garbage.out"
$endif
可编程完成:
没有什么花哨。当我使用 Knoppix 时,我总是禁用它,因为它经常妨碍我。只是一些基本的:
shopt -s progcomp
complete -A stopped -P '%' bg
complete -A job -P '%' fg jobs disown wait
complete -A variable readonly export
complete -A variable -A function unset
complete -A setopt set
complete -A shopt shopt
complete -A helptopic help
complete -A alias alias unalias
complete -A binding bind
complete -A command type which \
killall pidof
complete -A builtin builtin
complete -A disabled enable
不是真正的交互式 shell 技巧,但作为编写好脚本的技巧仍然有效。
getopts, 转移, $OPTIND, $OPTARG:
我喜欢制作可定制的脚本:
while getopts 'vo:' flag; do
case "$flag" in
'v')
VERBOSE=1
;;
'o')
OUT="$OPTARG"
;;
esac
done
shift "$((OPTIND-1))"
xargs(1):
我有一个三核处理器,喜欢运行对一组文件执行压缩或其他一些 CPU 密集型串行操作的脚本。xargs
我喜欢将其用作作业队列来加速它。
if [ "$#" -gt 1 ]; then
# schedule using xargs
(for file; do
echo -n "$file"
echo -ne '\0'
done) |xargs -0 -n 1 -P "$NUM_JOBS" -- "$0"
else
# do the actual processing
fi
这很像make -j [NUM_JOBS]
.
信号捕获:
您可以捕获发送到 shell 进程的信号,并让它们在各自的环境中静默运行命令,就像在命令行上键入一样:
# TERM or QUIT probably means the system is shutting down; make sure history is
# saved to $HISTFILE (does not do this by default)
trap 'logout' TERM QUIT
# save history when signalled by cron(1) script with USR1
trap 'history -a && history -n' USR1
对于纯粹的幽默因素,创建一个空文件“我自己”,然后:$ touch myself
扩展通配符:
rm !(foo|bar)
像*
没有foo
or一样展开bar
:
$ ls
foo
bar
foobar
FOO
$ echo !(foo|bar)
foobar FOO
GNU/Linux 的 pbcopy 和 pbpaste 别名
alias pbcopy='xclip -selection clipboard'
alias pbpaste='xclip -selection clipboard -o'
其他人在 Emacs 中推荐了“Mx shell RET”。我认为“Mx eshell RET”更好。
我在寻找一些音频和视频编辑工具时发现了一些有用的 mencoder 命令:
从 .xxx 到 .avi
mencoder movie.wmv -o movie.avi -ovc lavc -oac lavc
从视频中转储声音:
mplayer -ao pcm -vo null -vc dummy -dumpaudio -dumpfile fileout.mp3 filein.avi
我更喜欢在 vi 中阅读手册页,因此我的 .profile 或 .bashrc 文件中有以下内容
man () {
sought=$*
/usr/bin/man $sought | col -b | vim -R -c "set nonumber" -c "set syntax=man" -
}
alias mycommand = 'verylongcommand -with -a -lot -of -parameters'
alias grep='grep --color'
用 grep 查找多个单词:
netstat -c |grep 'msn\|skype\|icq'
您更改到一个新目录并希望将文件从新目录移动到旧目录。一举一动:mv file $OLDPWD
如果我正在搜索目录中的某些内容,但我不确定该文件,那么我只需通过以下方式 grep 目录中的文件:
find . -exec grep whatIWantToFind {} \;
alias -- ddt='ls -trFld'
dt () { ddt --color "$@" | tail -n 30; }
为您提供当前目录中的最新文件。我用它所有的时间...
为了能够快速编辑您知道位于 $PATH 中的 shell 脚本(不要尝试使用 ls...):
function viscr { vi $(which $*); }
恰当的历史——使用神秘的插入符号等并不完全直观。要打印包含给定字符串的所有历史记录项:
function histgrep { fc -l -$((HISTSIZE-1)) | egrep "$@" ;}
自定义选项卡完成(compgen 和完整的 bash 内置)
Tab Completion 很好,但能够将其应用于不仅仅是文件名也很棒。我用它来创建自定义函数来扩展我一直使用的命令的参数。例如,假设您经常需要将 FQDN 作为参数添加到命令(例如ping blah.really.long.domain.name.foo.com
)。您可以使用 compgen 和 complete 创建一个读取 /etc/hosts 文件以获取结果的 bash 函数,因此您只需键入:
ping blah.<tab>
它将显示您当前的所有匹配选项。
所以基本上任何可以返回单词列表的东西都可以用作函数。
当运行具有大量输出的命令时(比如一个大的“make”),我不仅要保存输出,还要查看它:
安装 2>&1 | tee E.make
作为一个快速计算器,比如说计算一个百分比:
$ date
Thu Sep 18 12:55:33 EDT 2008
$ answers=60
$ curl "http://stackoverflow.com/questions/68372/what-are-some-of-your-favorite-command-line-tricks-using-bash" > tmp.html
$ words=`awk '/class="post-text"/ {s = s $0} \
> /<\/div>/ { gsub("<[^>]*>", "", s); print s; s = ""} \
> length(s) > 0 {s = s $0}' tmp.html \
> | awk '{n = n + NF} END {print n}'`
$ answers=`awk '/([0-9]+) Answers/ {sub("<h2>", "", $1); print $1}' tmp.html`
最后:
$ echo $words words, $answers answers, $((words / $answers)) words per answer
4126 words, 60 answers, 68 words per answer
$
并不是说除法被截断,而不是四舍五入。但通常这对于快速计算来说已经足够了。
我总是将默认提示设置为“username@hostname:/current/path/name/in/full>”
PS1='\u@\h:\w> '
export PS1
当您处理许多不同的机器时,可以避免很多混乱。
find -iregex '.*\.py$\|.*\.xml$' | xargs egrep -niH 'a.search.pattern' | vi -R -
在所有 Python 文件和所有 XML 文件中搜索模式,并将结果通过管道传输到只读Vim会话中。
我最喜欢的两个是:
1)使制表符完成不区分大小写(例如,“cd /home/User”将您的命令行转换为:“cd /home/user”,如果后者存在而前者不存在。您可以使用“设置完成”打开它-ignore-case on”,或者通过将“set completion-ignore-case on”添加到您的 .inputrc 文件来永久添加它。
2) 内置的 'type' 命令类似于 "which" 但也知道别名。例如
$ type cdhome
cdhome is aliased to 'cd ~'
$ type bash
bash is /bin/bash
我喜欢设置一个提示,在 xterm 的窗口标题中显示当前目录。它还显示时间和当前目录。此外,如果 bash 想要报告后台作业已完成,则使用 ANSI 转义序列以不同的颜色报告。我使用的是黑底光控制台,所以如果你喜欢黑底光,我的颜色可能不适合你。
PROMPT_COMMAND='echo -e "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\007\033[1;31m${PWD/#$HOME/~}\033[1;34m"'
PS1='\[\e[1;31m\]\t \$ \[\e[0m\]'
确保您了解如何正确使用PS1 字符串\[
,\]
以便 bash 知道您的提示字符串在屏幕上实际呈现多长时间。这样当您超出单行命令时,它可以正确重绘您的命令行。
我想提一下我们如何使用它的批处理模式(-b)将顶级命令输出重定向到文件
$ top -b -n 1 > top.out.$(date +%s)
默认情况下,top 使用交互模式调用,其中 top 无限期运行并接受 keypress 以重新定义 top 的工作方式。
我写的一篇文章可以在这里找到
如何使用 find | 查找与文本匹配的文件 grep -H 在这个例子中,哪个 ruby 文件包含跳转字符串 -
寻找 。-name '*.rb' -exec grep -H jump {} \;
仅限 Mac。这很简单,但我真希望我几年前就知道这一点。
open ./
在 Finder 中打开当前目录。您还可以使用它通过其默认应用程序打开任何文件。也可用于 URL,但前提是您在 URL 前加上http://
,这限制了它打开偶尔随机站点的实用程序。
./mylittlealgorithm < input.txt > output.txt
# Batch extension renamer (usage: renamer txt mkd)
renamer() {
local fn
for fn in *."$1"; do
mv "$fn" "${fn%.*}"."$2"
done
}