shell常用知识

四月 02, 2022 [bash, 快捷键] #bash #快捷键

shell常用知识

shell基础

记录一些用到的shell知识

常用的cli的快捷键

ALT-? list complete ALT-* insert complete C-x * glob-expand-word M-# insert-comment (M-#) M-g glob-complete-word (M-g) C-x * glob-expand-word (C-x *) C-x g glob-list-expansions (C-x g) M-C-y yank-nth-arg (M-C-y) M-. yank-last-arg (M-., M-_) M-t transpose-words (M-t) M-u upcase-word (M-u) C-y yank (C-y) M-y yank-pop (M-y) C-@ set-mark (C-@, M-) C-x Backspace : backward-kill-line (C-x Rubout) 在Bash里面,快捷键可能会被写成八进制或者十六进制的形式(跟在转义符后面); 另外快捷键有个规律,Ctrl开头的快捷键一般是针对字符的,而Alt开头的快捷键一般是针对词的

查看当前选项的设置状态

set -o emacs 切到emacs模式
set -o vi 切到vi模式
set -o 查看当前选项的设置状态
shopt命令是set命令的一种替代,很多方面都和set命令一样,但它增加了很多选项可有使用“-p"选项来查看shopt选项的设置“-u"开关表示一个复位的选项,“-s"表示选项当前被设置
shopt -p

emacs模式快捷键

CTRL-A 将光标移到行首(在命令行下) CTRL-B 退格(非破坏性的),这个只是将光标位置往回移动一个位置 CTRL-C 中断,终结一个前台作业 CTRL-D "EOF"(文件结尾:end of file)它用于表示标准输入(stdin)的结束,在控制台或xterm窗口输入文本时,CTRL-D删除在光标下的字符,从一个shell中退出(类似于exit)如果没有字符存在,CTRL-D 则会登出该会话.在一个xterm窗口中,则会产生关闭此窗口的效果 CTRL-E 将光标移动到行尾(在命令行下) CTRL-F 将光标向前移动一个字符(在命令行下) CTRL-G BEL在一些老式打印机终端上,这会引发一个响铃,在xterm终端上可能是哔的一声 CTRL-H 擦除(Rubout)(破坏性的退格),在光标往回移动的时候,同时擦除光标前的一个字符 CTRL-I 水平制表符 CTRL-J 新行(换行[line feed]并到行首)在脚本中,也可能表示为八进制形式(\012)或十六进制形式(\x0a) CTRL-K 垂直制表符(Vertical tab),在控制台或xterm窗口输入文本时,CTRL-K会删除从光标所在处到行尾的所有字符在脚本中,也可能表示为八进制形式(\013)或十六进制形式(\x0b),在脚本中,CTRL-K可能会有不一样的行为,后面的例子给出其不一样的行为

一个CTRL-K垂直制表符的例子

var=$'/x0aBottom Line/x0bTop line/x0a'
echo "$var"
#使用col来过滤控制字符
echo "$var" | col

CTRL-L 跳纸,换页(Formfeed),清空终端屏幕,在终端上,这个命令的作用和clear命令一样,但当这个命令发送到打印机时,Ctrl-L会直接跳到纸张(Paper sheet)的末尾 CTRL-M 回车(Carriage return) CTRL-N 擦除从history缓冲区召回的一行文本(在命令行下),如果当前输入是历史记录中选择的时候,这个是从这个历史记录开始,每按一次,是更接近的一条命令 CTRL-O 产生一个新行(在命令行下) CTRL-P 从history缓冲区召回上一次的命令(在命令行下)此快捷键召回的顺序是由近及远的召回,即按一次,召回的是前一次的命令,再按一次,是召回上一次之前的命令,这和CTRL-N都是以当前的输入为起点,但是两个命令操作刚好相反,CTRL-N是从起点开始由远及近(如果起点是历史命令的话) CTRL-Q Resume(XON),恢复/解冻,这个命令是恢复终端的stdin用的,可参见CTRL-S CTRL-R 回溯搜索(Backwards search)history缓冲区内的文本(在命令行下)注意:按下之后,提示符会变成(reverse-i-search)":输入的搜索内容出现在单引号内,同时冒号后面出现最近最匹配的历史命令 CTRL-S Suspend(XOFF),挂起这个是冻结终端的stdin要恢复可以按CTRL-Q CTRL-T 交换光标位置与光标的前一个位置的字符内容(在命令行下)比如:echo $var;,假设光标在a上,那么,按下C-T之后,v和a将会交换位置:echo$avr; CTRL-U 擦除从光标位置开始到行首的所有字符内容在某些设置下,CTRL-U会不以光标位置为参考而删除整行的输入 CTRL-V 在输入文本的时候,按下C-V之后,可以插入控制字符比如:echo -e '/x0a';和echo ;这两种效果一样这点功能在文本编辑器内非常有效 CTRL-W 当在控制台或一个xterm窗口敲入文本时, CTRL-W 会删除从在光标处往后(回)的第一个空白符之间的内容在某些设置里, CTRL-W 删除光标往后(回)到第一个非文字和数字之间的字符 CTRL-X 在某些文字处理程序中,这个控制字符将会剪切高亮的文本并且将它复制到剪贴板中 CTRL-Y 将之前已经清除的文本粘贴回来(主要针对CTRL-U或CTRL-W) CTRL-Z 暂停一个前台的作业;在某些文本处理程序中也作为替换操作;在MSDOS文件系统中作为EOF(End-of-file)字符 CTRL-/ 退出和CTRL-C差不多,也可能dump一个"core"文件到你的工作目录下(这个文件可能对你没用) CTRL-/ 撤消操作,Undo CTRL-_ 撤消操作 CTRL-xx 在行首和光标两个位置间进行切换,此处是两个"x"字符 ALT-B 光标往回跳一个词,词以非字母为界(跳动到当前光标所在词的开头) ALT-F 光标往前跳一个词(移动到光标所在词的末尾) ALT-D 删除光标所在位置到光标所在词的结尾位置的所有内容(如果光标是在词开头,则删除整个词) ALT-BASKSPACE 删除光标所在位置到词开头的所有内容 ALT-C 将光标所在位置的字母转为大写(如果光标在一个词的起始位置或之前,则词首字母大写) ALT-U 将光标所在位置到词尾的所有字母转为大写 ALT-L 将光标位置到词尾的所有字母转为小写 ALT-R 取消所有变更,并将当前行恢复到在历史记录中的原始状态(前提是当前命令是从历史记录中来的,如果是手动输入,则会清空行) ALT-T 当光标两侧都存在词的时候,交换光标两侧词的位置如:abc bcd -> bcd abc ALT-. 使用前一次命令的最后一个词(命令本身也是一个词,参见后一篇的Bang命令中的词指示符概念) ALT-_ 同ALT-. ALT-数值 这个数值可以是正或者是负,这个键单独没有作用,必须后面再接其他内容,如果后面是字符,则表示重复次数如:[ALT-10,k]则光标位置会插入10个k字符(负值在这种情况下无效);如果后面接的是命令,则数字会影响后面命令的执行结果,如:[ALT--10,CTRL-D]则向CTRL-D默认方向相反(负数)的方向执行10次操作 ALT-< 移动到历史记录中的第一行命令 ALT-> 移动到历史的最后一行,即当前正在输入的行(没有输入的情况下为空) ALT-P 从当前行开始向前搜索,有必要则向"上"移动,移动时,使用非增量搜索查找用户提供的字符串 ALT-N 从当前行开始向后搜索,如果有必要向"下"移动,移动时,使用非增量搜索查找用户提供的字符串 ALT-CTRL-Y 在标志点上插入前一个命令的第一个参数(一般是前一行的第二个词)如果有参数n,则插入前一个命令的第n个词(前一行的词编号从0开始,见历史扩展)负的参数将插入冲前一个命令的结尾开始的第n个词参数n通过M-No.的方式传递,如:[ALT-0,ALT-CTRL-Y]插入前一个命令的第0个词(命令本身) ALT-Y 轮询到删除环,并复制新的顶端文本只能在yank[CTRL-Y]或者yank-pop[M-Y]之后使用这个命令 ALT-? 列出能够补全标志点前的条目 ALT-* 把能够补全[ALT-?]命令能生成的所有文本条目插入到标志点前 ALT-/ 试图对标志点前的文本进行文件名补全[CTRL-X,/]把标志点前的文本当成文件名并列出可以补全的条目 ALT-~ 把标志点前的文本当成用户名并试图进行补全[CTRL-X,~]列出可以作为用户名补全标志点前的条目 ALT-$把标志点前的文本当成Shell变量并试图进行补全[CTRL-X,$]列出可以作为变量补全标志点前的条目 ALT-@ 把标志点前的文本当成主机名并试图进行补全[CTRL-X,@]列出可以作为主机补全标志点前的条目 ALT-! 把标志点前的文本当成命令名并试图进行补全进行命令名补全时会依次使用别名、保留字、Shell函数、shell内部命令,最后是可执行文件名[CTRL-X,!]把标志点前的文本当成命令名并列出可补全的条目 ALT-TAB 把标志点前的文本与历史记录中的文本进行比较以寻找匹配的并试图进行补全 ALT-{ 进行文件名补全,把可以补全的条目列表放在大括号之间,让shell可以使用

几个快捷键的例子

##不用快捷键
cat >>/tmp/test<<EOF
##这里是内容
EOF

##使用快捷键
cat >>/tmp/test
##这里输入内容
##输入完毕之后,直接[CTRL-D]结束
##有的时候我们需要创建一个文件,而后对这个文件进行操作:

touch /tmp/a-test-file-from-blog.useasp.net

##不使用快捷键,文件名要重新输入
chmod u+x /tmp/a-test-file-from-blog.useasp.net

##使用快捷键
chmod u+x <ALT-.>
## 快捷键[M-.]自动会将上面的最后一个参数附加

inputrc

如果你想自己的Bash有那么一些不同,你也可以自己自定义快捷键,使用bind命令即可,Bash中的快捷键其实是Readline来提供的,因此,这里快捷键的设置其实就是配置Readline,Readline中分两种快捷键,一种是Readline内部的函数快捷键,另外一种是执行Shell命令,设置的时候稍有不同:

##查看Readline中可以使用的函数名称
bind -l
##查看当前绑定的案件配置与其对应的功能
bind -v
##已经绑定的快捷键
bind -p

绑定快捷键

##绑定自定义执行命令shell命令的快捷键
bind -x '"\C-x\C-l":ls -al'
## 绑定后,按[C-x,C-L]就能执行ls -al

## 绑定内置函数功能
bind "\C-x":backword-delte-char
##这个是这行Readline库中的函数backword-delte-char

这种设置只是针对当前的会话有效,一旦会话丢失,这样设置的快捷键就会丢失,为了能够让设置的快捷键永久有效,我们就需要将快捷键的配置写入文件在Linux系统中,能永久保存快捷键的地方有两个, 全局和用户的配置文件,全局的是/etc/inputrc,而用户的是在用户的根目录下~/.inputrc,全局的会影响所有的用户,而用户根目录下的只会对相应的用户产生影响inputrc文件的大概样子像下面这样:

本例来自CentOS6.4的默认配置文件

$if mode=emacs

# for linux console and RH/Debian xterm
"\e[1~": beginning-of-line
"\e[4~": end-of-line
# commented out keymappings for pgup\pgdown to reach begin\end of history
#"\e[5~": beginning-of-history
#"\e[6~": end-of-history
"\e[5~": history-search-backward
"\e[6~": history-search-forward
"\e[3~": delete-char
"\e[2~": quoted-insert
"\e[5C": forward-word
"\e[5D": backward-word
"\e[1;5C": forward-word
"\e[1;5D": backward-word

# for rxvt
"\e[8~": end-of-line
"\eOc": forward-word
"\eOd": backward-word

# for non RH/Debian xterm, can't hurt for RH/DEbian xterm
"/eOH": beginning-of-line
"/eOF": end-of-line

# for freebsd console
"/e[H": beginning-of-line
"/e[F": end-of-line
$endif

说明:

在配置文件中,\C代表CTRL,\M代表ALT,\e代表ESC,\是反斜杠,'是单引号,"是双引号; \C- control prefix \M- meta prefix \e an escape character \ backslash " literal ", a double quote \’ literal ’, a single quote 如果要查看某一个功能键的字符序列可以通过[CTRL-V]来实现,或者输入cat后回车,进入编辑中,直接按快捷键 配置文件中可能会使用八进制或者十六进制来表示字符 如果我们针对常用的操作设置成适当的快捷键,无疑将会大大的提高我们的工作效率!

获取脚本目录

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/" && pwd )"
# DIR=$( cd "$( dirname ${BASH_SOURCE[0]} )/" && pwd )
# DIR=`cd $( dirname ${BASH_SOURCE[0]} )/ && pwd`

当在a.sh中source b.sh时: a.sh中的$0和BASH_SOURCE $0 --> “a.sh" ${BASH_SOURCE[0]} -> “a.sh"

b.sh中的$0和BASH_SOURCE $0 --> “a.sh" ${BASH_SOURCE[0]} -> “b.sh" ${BASH_SOURCE[1]} -> “a.sh"