Answers:
这!!
在此答案中提到的技巧上有所扩展。实际上,有一堆与历史相关的命令往往会被忘记(人们倾向于刺破Up100次,而不是寻找他们知道自己键入的命令)。
history
命令将显示最近运行的命令列表,左侧带有事件指示符!N
将替换与事件指示符关联的命令 N
!-N
将替代N
日最近的命令; 例如!-1
将替换最近的命令,!-2
第二个最近的命令,等等。!!
是的缩写!-1
,可以快速替代最后一个命令!string
将替换以开头的最新命令 string
!?string?
将替换包含以下内容的最新命令 string
可以将单词指示符添加到!
历史记录命令上以修改结果。冒号将事件和单词标记分开,例如!!:0
。事件指示符!!
可以缩写为仅!
在使用单词指示符时使用,因此!!:0
等效于!:0
。
!:0
将获取已执行的命令!:1
将获得第一个参数(!:2
第二个参数,依此类推)!:2-3
将获得第二个和第三个参数!:^
是获得第一个论点的另一种方法。!:$
将获得最后!:*
将获取所有参数(而不是命令)修饰符也可以附加到!
历史命令后面,每个修饰符都以冒号作为前缀。可以堆叠任何数字(例如!:t:r:p
)。
h
-排队到基本文件名t
-仅基础文件名r
-排列文件扩展名e
-仅文件扩展名s/search/replacement
-替换第一次出现search
与replacement
gs/search/replacement
-更换所有出现的search
与replacement
!-#
。我确实!string
会运行最后一个以string开头的命令,但是通常我会先使用Tab键完成命令(zsh),以确保运行正确的命令
!N
将运行命令...”的描述太狭窄;实际上,!N
将由命令...代替。对于答案中的所有说明,依此类推。更正确,打开更多有用的可能性!例如,提到的sudo !!
。
bash
;在Emacs中,要浏览输入命令和值(用于Mx或其他读取值)的历史,请改用Meta-R(eshell
Emacs中也使用了Meta-R )。所以我经常把它们弄乱。
bash-插入前一行的最终参数
alt- . 有史以来最有用的组合键,尝试一下,看看,由于某种原因,没人知道这一组合。
反复按它以选择较旧的最后一个参数。
如果您想对刚才使用的参数/文件做更多的事情,那就太好了。
alt
- .
它将转到上一个命令并从中拉出最后一个参数。因此,如果您想从三个命令之前获取最后一个参数,只需点击alt
- .
三遍即可。
yank-last-arg
readline命令的默认键绑定,因此它应与任何与readline链接的程序一起使用,而不仅仅是BASH或ZSH。
我最喜欢的是
man 7 ascii
简单,所以非常有用。
Oct Dec Hex Char Oct Dec Hex Char
────────────────────────────────────────────────────────────────────────
000 0 00 NUL '\0' (null character) 100 64 40 @
001 1 01 SOH (start of heading) 101 65 41 A
002 2 02 STX (start of text) 102 66 42 B
003 3 03 ETX (end of text) 103 67 43 C
004 4 04 EOT (end of transmission) 104 68 44 D
005 5 05 ENQ (enquiry) 105 69 45 E
006 6 06 ACK (acknowledge) 106 70 46 F
007 7 07 BEL '\a' (bell) 107 71 47 G
010 8 08 BS '\b' (backspace) 110 72 48 H
011 9 09 HT '\t' (horizontal tab) 111 73 49 I
012 10 0A LF '\n' (new line) 112 74 4A J
013 11 0B VT '\v' (vertical tab) 113 75 4B K
014 12 0C FF '\f' (form feed) 114 76 4C L
015 13 0D CR '\r' (carriage ret) 115 77 4D M
016 14 0E SO (shift out) 116 78 4E N
017 15 0F SI (shift in) 117 79 4F O
020 16 10 DLE (data link escape) 120 80 50 P
021 17 11 DC1 (device control 1) 121 81 51 Q
022 18 12 DC2 (device control 2) 122 82 52 R
023 19 13 DC3 (device control 3) 123 83 53 S
024 20 14 DC4 (device control 4) 124 84 54 T
025 21 15 NAK (negative ack.) 125 85 55 U
026 22 16 SYN (synchronous idle) 126 86 56 V
027 23 17 ETB (end of trans. blk) 127 87 57 W
030 24 18 CAN (cancel) 130 88 58 X
031 25 19 EM (end of medium) 131 89 59 Y
032 26 1A SUB (substitute) 132 90 5A Z
033 27 1B ESC (escape) 133 91 5B [
034 28 1C FS (file separator) 134 92 5C \ '\\'
035 29 1D GS (group separator) 135 93 5D ]
036 30 1E RS (record separator) 136 94 5E ^
037 31 1F US (unit separator) 137 95 5F _
040 32 20 SPACE 140 96 60 `
041 33 21 ! 141 97 61 a
042 34 22 " 142 98 62 b
043 35 23 # 143 99 63 c
044 36 24 $ 144 100 64 d
045 37 25 % 145 101 65 e
046 38 26 & 146 102 66 f
047 39 27 ' 147 103 67 g
050 40 28 ( 150 104 68 h
051 41 29 ) 151 105 69 i
052 42 2A * 152 106 6A j
053 43 2B + 153 107 6B k
054 44 2C , 154 108 6C l
055 45 2D - 155 109 6D m
056 46 2E . 156 110 6E n
057 47 2F / 157 111 6F o
060 48 30 0 160 112 70 p
061 49 31 1 161 113 71 q
062 50 32 2 162 114 72 r
063 51 33 3 163 115 73 s
064 52 34 4 164 116 74 t
065 53 35 5 165 117 75 u
066 54 36 6 166 118 76 v
067 55 37 7 167 119 77 w
070 56 38 8 170 120 78 x
071 57 39 9 171 121 79 y
072 58 3A : 172 122 7A z
073 59 3B ; 173 123 7B {
074 60 3C < 174 124 7C |
075 61 3D = 175 125 7D }
076 62 3E > 176 126 7E ~
077 63 3F ? 177 127 7F DEL
看看这个网站commandlinefu.com。
您还可以在Peteris Krumins的博客上查看这四篇文章
不确定这是否算作“技巧”,但是人们似乎并不了解标准的readline热键。在shell中特别有用:
Ctrl+L
对应于FormFeed ascii字符。它通常会在带有屏幕窗口(例如vim,less,mc等)的文本应用程序中重绘屏幕。如果屏幕已被另一个程序的某些输出“污染”,那就很好。
CTRLRBASH中的+ ,用于搜索/激活先前执行的命令(〜/ .bash_history的内容)。
这通常非常有帮助。运行此别名将通过端口8000上的HTTP(索引)为PWD提供服务:
alias webserver="python -m SimpleHTTPServer"
而且由于我一直都在运行make,并且输出速度太快并且输入速度太快,这些别名可能是我最常用的(严重):
alias maek=make
alias mkae=make
alias meak=make
alias amka=make
alias akme=make
也许我最常用的BASH片段是一个称为上载的简单脚本。我用它来将任何种类的内容复制到我的Linode中,并将生成的HTTP URL复制到我的剪贴板中(单击中键)。对于将内容粘贴到IRC中的人非常有用:
scp -r $* $user@$host:public_html && {
URL="http://$host/~$user/$(basename $1)"
echo "$URL"
xselection -replace PRIMARY "$URL"
}
只是一对 我以后可以发表更多文章,必须重新工作!
alias mk=make
打字速度更快,更不会出错。或使用热键从编辑器进行编译...
alias m=make
,甚至m=make -j6
或相似-除了我已经使用alias m=mutt
☺
括号扩展:
括号扩展是一种可以生成任意字符串的机制。
它可以让您替换乏味的行,例如:
mv loong/and/complex/file/name loong/and/complex/file/name.bacukup
实例较短
mv loong/and/complex/file/name{,backup}
其他用途
# to display the diff between /etc/rc.conf and /etc/rc.conf.pacsave
diff /etc/rc.conf{,.pacsave}
# to list files in both /usr/share and /usr/local/share
ls /usr/{,local}/share
算术扩展:
算术扩展允许对算术表达式进行求值并替换结果。算术扩展的格式为:
$((expression))
将该表达式视为在双引号内,但括号内的双引号没有被特殊对待。表达式中的所有标记都经过参数扩展,字符串扩展,命令替换和引用删除。算术扩展可以嵌套。
$ a=1
$ b=2
$ echo $(( a+(b*2) ))
5
foo[123]
将扩展为foo1 foo2 foo3
,但在这种情况下,它们必须是文件名才能工作
这通常在我的启动脚本中(.bashrc,.profile等)
shopt
天哪,请查看以下评论:
shopt -s cdspell # try to correct typos in path
shopt -s dotglob # include dotfiles in path expansion
shopt -s hostcomplete # try to autocomplete hostnames
一个别名保存按键:
mkdir
和cd
到它:
mkcd () { mkdir -p "$@" && cd "$@"; }
最后但并非最不重要的一点是,我放弃了记住tar语法,因此:
extract () {
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar xjf $1 ;;
*.tar.gz) tar xzf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) rar x $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xf $1 ;;
*.tbz2) tar xjf $1 ;;
*.tgz) tar xzf $1 ;;
*.zip) unzip $1 ;;
*.Z) uncompress $1 ;;
*) echo "'$1' cannot be extracted via extract()" ;;
esac
else
echo "'$1' is not a valid file"
fi
}
mkcd
只不过我命名为id md
。但是,使用“ $ @”作为cd的参数没有任何意义,因为您不能将cd到一个以上的目录中。“$ @”会为MKDIR打工,但那时你为的mkdir和CD不同处理参数,所以我宁愿建议md () { mkdir -p "$1"; cd "$1" }
两项重击功能为我节省了许多按键。
在每次成功刻录CD之后自动执行ls:
function cd {
builtin cd "$@" && ls
}
上n个级别:
# Usage .. [n]
function .. (){
local arg=${1:-1};
local dir=""
while [ $arg -gt 0 ]; do
dir="../$dir"
arg=$(($arg - 1));
done
cd $dir #>&/dev/null
}
builtin foo
绕开定义函数的步伐cd
; 我一直在使用chdir
我的功能。得心应手
cd() { builtin cd -- "$@" && { [ "$PS1" = "" ] || ls -hrt --color; }; }
由于我通常想搜索之前进入命令行(bash中的CTRL-R),因此我的.bashrc中包含以下内容
bind '"\e[A"':history-search-backward
bind '"\e[B"':history-search-forward
这意味着,如果我键入cd,然后按向上/向下键,则可以看到我已进行cd操作的所有选项。基本上,我将其用于常用的目录。像“ cd w”一样,我最终要遍历我使用很多的所有工作区。
节省我很多时间的一件事是push / popd命令。这些家伙使您可以创建一堆目录并减少大量输入:
/foobar/ > pushd /src/whatever/foo/test
/foobar/src/whatever/foo/test > make run
/foobar/src/whatever/foo/test > popd
/foobar/ > make
u
和o
站在这里?
setopt autopushd
所有目录更改,自动更改
该screen
命令。基本上,它保存了您回来时的命令行会话。它有点像一个终端管理器,就像一个窗口管理器。这样,在单个终端会话中,您可以拥有多个虚拟终端。非常酷
如果使用screen
,则此shell函数(将其放入.bashrc
)非常有用:
function scr {
if screen -ls | grep -q Main; then
# reattach to Main:
screen -xr Main
else
# name session "Main":
screen -S Main
fi
}
键入时scr
,它将检查您的主会话是否存在并将附加到主会话。否则它将创建它。
如果您是快速打字员,这些将派上用场:
alias grpe='grep --color=tty'
alias gpre='grep --color=tty'
alias rgep='grep --color=tty'
alias gerp='grep --color=tty'
此宏可帮助您计算一列输出的总数:文件大小,字节,数据包,您所要做的就是指定要添加的列:
total ()
{
if [ x$1 = x ]; then set `echo 1`; fi
awk "{total += \$$1} END {print total}"
}
例如,您像这样使用它,不带任何参数,它将添加第一列的总数:
du | total
如果提供该参数,它将对该列求和,例如,这将为您提供/ tmp中所有C#文件使用的字节总数:
ls -l /tmp/*cs | total 5
有时由于不小心查看了二进制文件(例如,cat / bin / ls)而导致控制台混乱,您可以使用以下shell函数恢复终端:
restaura ()
{
perl -e 'print "\e)B";'
}
我喜欢我的ls使用字符来区分文件的类别,并隐藏由编辑器生成的备份文件(备份文件以〜字符结尾):
alias ls='ls -FB'
s/fast/sloppy/
reset
你用的地方restaura
。
alias s='sudo'
alias r='rake' # i'm a ruby developer
alias ..='cd ..' # although with autocd feature for zsh this comes packed.
当我忘记我的最爱之一s
:
$ s !! # last command with super user priviledges
bindkey -s '\e[12~' "sudo !!\n"
绑定(在这种情况下)F2来运行该命令的操作。我具有这种约束力,所以当我运行某些命令并看到“您忘记了'sudo',傻瓜”错误消息时,我可以烦恼地刺入F2
如果命令使用stdin输入,则可以使用从文件中读取输入<filename
。它可以出现在命令中的任何位置,因此这些行是等效的:
cat filename
cat <filename
<filename cat
这对于grep尤其有用,因为它允许您将表达式放在行的末尾,因此您可以通过点击来快速修改它的grep命令Up,而无需向左滚动即可跳过文件名:
<filename grep 'expression'
<input foo | bar | baz >output
,但是如果您尝试在诸如while
或for
之中的一些shell循环原语中进行混合,则它不起作用。所以我放弃了,只是按照惯例将其放在最后。
您可以CDPATH
用来建立等效的目录PATH
;如果尝试这样做cd foo
并且foo
当前目录中没有该目录,则Shell将检查每个目录CDPATH
以foo
在其中查找,然后切换到它找到的第一个目录:
export CDPATH="/usr"
cd bin # switches to 'bin' if there is one in the current directory, or /usr/bin otherwise
vi `which scriptname`
因为当您不知道某物在哪里居住时,您也不在乎。
which
自动调用,因此vi =scriptname
$(scriptname)
该符号。它将命令放在后台,因此您可以继续输入。
$> sudo updatedb &
一起工作,一段时间后,您会看到:
[1] 17403
您的过程完成了!非常适合不需要等待它们终止的事情。
&!
后台作业并将其从外壳中删除!
bash
。
nohup
完成此操作。
制表符完成。如果您必须输入每个路径的所有字符,将有多糟糕?
rm -fr /
。是的,Tab的完成非常重要……
ls /usr/lib/game-d*/rott*
rm -rf /
在大多数Linux系统中都没有禁用吗?
上次安装的设备数量:
mount /media/whatever
...
u!mo
!mo
扩展到最后一个以mo
(至少在bash中)开始的命令。有时一个人mv
在中间,所以u!m
不会经常工作。
我的.bashrc中有这个
#shortcut for CTRL+C and CTRL+V
alias c-c='xclip -sel clip'
alias c-v='xclip -o -sel clip'
function find-all() {
python -c "import re
import sys
for i in re.findall('$1', sys.stdin.read()):
if type(i) == type(''):
print i
else:
print i[0]"
}
当我在剪贴板中有html源代码并想找到我使用的所有链接时
c-v | find-all 'href="([^"]*)"' | c-c
我在剪贴板中有所有网址
我也有这个功能
function lsq(){
ls -lh $@ | tr -s ' ' | cut -d' ' -f5,8
}
显示大小(可读)和文件名。
alias temp='cat /proc/acpi/thermal_zone/THRM/temperature'
该别名用于显示温度
function separate() {
python -c "import sys,re; print '$1'.join(re.split('\s*', sys.stdin.read().strip()))";
}
使用此函数,我可以计算乘积或参数总和。
alias sum='separate + | bc'
alias product='separate * | bc'
function split-join() {
python -c "import sys,re; print '$2'.join(re.split('$1', sys.stdin.read().strip()))";
}
这是有用的功能,它将由正则表达式分隔的标准输入分割开,然后合并结果。
function factorial() {
seq -s* $1 | bc
}
阶乘函数
function wiki() { dig +short txt $1.wp.dg.cx; }
此功能通过DNS显示Wiki文本
我也有三种颜色功能
function blue() {
echo -e "\x1b[34m\x1b[1m"$@"\x1b[0m";
}
function green() {
echo -e "\x1b[32m\x1b[1m"$@"\x1b[0m";
}
function red() {
echo -e "\x1b[31m\x1b[1m"$@"\x1b[0m";
}
function md5check() {
test `md5sum $2 | cut -d' ' -f1` = "$1" && green [OK] || red [FAIL]
}
此功能验证文件md5哈希。
这将显示给定代码的错误消息
function strerror() { python -c "import os; print os.strerror($1)"; }
您可以使用以下命令打印所有消息
alias all-errors='for i in `seq 131`; do echo -n "$i: "; strerror $i; done'
ZSH的另一个有用技巧:
将命令的输出视为文件:
emacs =(hg cat -r 100 somefile)
这将在emacs中打开Mercurial跟踪文件的旧版本,以进行语法突出显示。不这样做,我会更动hg revert
,hg archive
或明确地发送hg cat
输出到一个临时文件。
当然,这适用于打开文件的任何程序以及可打印到标准输出的任何程序。
具体ZSH特征是后缀的别名,通过给设置alias
的-s
标志:
alias -s ext=program
如果给定扩展名具有后缀别名,则可以直接执行具有该扩展名的文件,并且ZSH将启动给定程序并将文件名作为参数传递。因此,如果上述别名有效,则这些行是等效的:
/path/to/foo.ext
program /path/to/foo.ext
我一直以来最喜欢的ZSH功能之一是命名目录。您可以导出具有给定名称的变量,其值指向某个路径:
export foo=/usr/bin
现在,您可以~foo
在命令中使用来引用/usr/bin
:
cd ~foo
~foo/ls
cat ~foo/filename
看到这个问题。
运行时ps ax | grep string
:
[steve@sage-arch ~]$ ps ax | grep 'openbox'
3363 ? Ss 0:00 /usr/bin/openbox
3382 ? Ss 0:00 /usr/bin/ssh-agent -- /usr/bin/openbox-session
3386 ? S 0:00 /bin/sh /usr/bin/openbox-session
3388 ? S 0:00 /bin/sh /usr/bin/openbox-session
3389 ? S 0:00 /bin/sh /usr/bin/openbox-session
3390 ? S 0:00 /bin/sh /usr/bin/openbox-session
5100 pts/0 S+ 0:00 grep openbox
最后一行包含grep
一些烦人的东西
您可以通过运行ps ax | grep '[s]tring'
以下命令摆脱自己:
[steve@sage-arch ~]$ ps ax | grep '[o]penbox'
3363 ? Ss 0:00 /usr/bin/openbox
3382 ? Ss 0:00 /usr/bin/ssh-agent -- /usr/bin/openbox-session
3386 ? S 0:00 /bin/sh /usr/bin/openbox-session
3388 ? S 0:00 /bin/sh /usr/bin/openbox-session
3389 ? S 0:00 /bin/sh /usr/bin/openbox-session
3390 ? S 0:00 /bin/sh /usr/bin/openbox-session
更新:或只是运行pgrep string
'[o]penbox'
)引用openbox 。方括号将像glob一样起作用,因此,如果您的目录中有openbox(例如您位于/usr/bin
),bash将仅使用openbox,这将防止grep技巧。
在什么都不做的命令:
,如
while :; do :; done
括号扩展与for循环结合使用:
for c in {1..3}; do :; done
!
操作员和短路操作员||
以及&&
[ -d /tmp/dir ] || mkdir /tmp/dir
if ! ping 34.41.34.1; then :; fi
使用子shell代替pop / push(在脚本中方便使用)
~$ ( cd /tmp; echo $PWD )
/tmp
~$
来样的东西,是命令type
~$ type type
type is a shell builtin
~$ type ls
ls is aliased to `ls --color=auto'
~$ f(){ :; }
~$ type f
f is a function
f ()
{
:
}
也很好:这里字符串
~$ cat <<<"here $PWD"
here /home/yourname
~$
和我最喜欢的:在命令列表上重定向
{ w; ps; ls /tmp; } 2>/dev/null |less
我喜欢把尽可能多的东西塞进我的PS1中。一些有用的事情要记住:
\e[s
并分别\e[u
保存和取消保存光标位置。我用它在屏幕顶部创建了一个“信息栏”,该行长几行,可以容纳更多东西。例:
PS1='\[\e[s\e[7m\e[1;1H\]\w\n\t \j / \! / \#\[\e[u\e[0m\e[33;1m\][\u@\h \[\e[34m\]\W]\[\e[0m\]\$ '
与结合alias clear='echo -e "\e[2J\n"'
。试试看!
另外,该PROMPT_COMMAND
变量定义每次都要在PS1之前执行的命令。
另一个是bg
命令。如果忘记放在&
命令末尾,只需按^Z并键入bg
,它就会在后台运行。
bg
,当我有一个程序在后台运行并且不小心按下时,fg
我不知道如何将其推回:D
PS1
的东西,所以我把大部分想要的东西放到了屏幕的最底端……