bash
命令行编辑
bash 的命令行编辑有很多和 zsh 的相同或类似,参见 zsh#命令行编辑。
^X^E
- 使用默认编辑器编辑命令行
命令行选项
bash的命令行选项有很多和zsh的相同或类似,参见zsh#命令行选项。这些选项也可以使用set [+-]x
这种方式开关。
-x
- 打印执行的命令
-e
- 在返回值非零的命令后以错误退出
重定向
特殊文件
现在,此/dev/tcp
和/dev/udp
设备实际并不存在,是由 bash 提供的虚拟文件(它们曾经是TLI/XTI interface的一部分)。[1]
PS1
\u | 用户名 |
\h | 主机名 |
\t | 当前时间 |
\d | 当前日期 |
\s | 当前的shell环境 |
\W | 工作目录 |
\w | 工作目录的完整路径 |
\# | 当前的命令号,每输入一个新的命令,命令号就+1 |
脚本编程
字符串处理
令 file=/dir1/dir2/dir3/my.file.txt,有:
- ${file#*/}
- 拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt
- ${file##*/}
- 拿掉最后一条 / 及其左边的字符串:my.file.txt
- ${file#*.}
- 拿掉第一个 . 及其左边的字符串:file.txt
- ${file##*.}
- 拿掉最后一个 . 及其左边的字符串:txt
- ${file%/*}
- 拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3
- ${file%%/*}
- 拿掉第一条 / 及其右边的字符串:(空值)
- ${file%.*}
- 拿掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
- ${file%%.*}
- 拿掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my
代码片断
matrix[3]:
p(){printf "\033[%d;%dH\033[32m%c\033[m" $1 $2 "$3"};clear;N=20;for i in `seq 1 $N 2`; do x[$i]=$((RANDOM%LINES+1));y[$i]=$((RANDOM%COLUMNS+1));done;chars=({0..9} {a..z} {A..Z} '*' '&' '^' '%' '$' '#' '@' '~' '<' '>' '?' '+');while :; do for i in `seq $N`;do ran_char=${chars[$RANDOM % ${#chars[@]}]};p ${x[$i]} ${y[$i]} $ran_char;((x[$i]++));if [ ${x[$i]} -ge $LINES ]; then for j in `seq $LINES`;do p $j ${y[$i]} " ";done;x[$i]=$((RANDOM%LINES+1));y[$i]=$((RANDOM%COLUMNS+1));fi;done;sleep .02;done
所有非必须的内建命令(有相应的可执行文件的)[4]
$ for i in $(compgen -A builtin); do /usr/bin/which $i &>/dev/null && echo $i; done | sort | xargs
[ echo false kill printf pwd test true
问题处理
ssh 中 ~/.bashrc 的处理
ssh 会话中非交互程序非要 source ~/.bashrc (依然是交互式 shell)造成问题时,可以通过判断$TERM
变量来确定是哪种情况:
[[ $TERM = dumb ]] && return
TMOUT
被设置为只读
if ! unset TMOUT > /dev/null 2>&1; then
gdb <<EOF >/dev/null 2>&1
attach $$
call unbind_variable("TMOUT")
detach
quit
EOF
fi
奇怪的行为
执行不带 shebang 的可执行文件
bash 会 fork 之后直接 source 该文件,部分功能不会被重置(比如 history
命令可用)(而 zsh 会调用 /bin/sh
执行)。[6]
缓冲与 SIGPIPE
A fun Bash buffering bug (apparently on Linux only)
在脚本中执行交互式 bash
在终端中,在脚本中执行交互式 bash 时,第一个 bash 进程会将自己设为前台进程组,导致后来的进程收到 SIGTTIN
或者 SIGTTOU
。[7]
为子进程忽略信号
当 bash 为执行最后一条命令进行优化时,会将忽略 SIGINT
、SIGQUIT
的行为遗传给该命令。比如
bash -c 'sleep 1000 &'
此 sleep 命令无法被 SIGINT
杀死。
默认正常退出时不发送 SIGHUP
bash 在正常退出时不会发送 SIGHUP。只有它收到 SIGHUP 时(比如终端消失),它才会给其任务发送 SIGHUP。[8]使用 shopt -s huponexit
来让其交互式登录 shell 退出时也发送 SIGHUP。
zsh 默认退出时会发送 SIGHUP 信号。使用 HUP
选项可以更改此行为。
参见
- zsh
- shellcheck: lint 工具
外部链接
- bash中的快捷键
- shell字符串操作方法,以及实例
- Bash新手指南已失效,存档 (另一份编码有问题的 [1])
- 让你提升命令行效率的 Bash 快捷键 {完整版} — LinuxTOY
- Better Bash history | Arabesque
- [译] 如何防止丢失任何 bash 历史命令? | Felix's Blog
- Illustrated Redirection Tutorial [Bash Hackers Wiki]
- Bash Notes for Professionals book(PDF)
- 写给高年级小学生看的《Bash 指南》 - while(1) { } - SegmentFault 思否
- The curious pitfalls in shell redirections to $((i++)) – Vidar's Blog
- Shell startup scripts — flowblok’s blog
- shell-startup-actual.png: bash 和 zsh 不同条件下会读取的配置文件(流程图)
- s/bash/zsh/g: 对 bash 中的奇怪行为的吐槽
- akinomyoga/ble.sh: Bash Line Editor―a full-featured line editor written in pure Bash! Syntax highlighting, auto suggestions, vim modes, etc. are available in Bash interactive sessions!
解析和求值
安全相关
- Shellshock_Bash_Story_CVE-2014-6271.txt 关于环境变量中包含函数定义的漏洞的记录
- Tricking the tricksters with a next level fork bomb – Vidar's Blog
- Detecting the use of "curl | bash" server side | Application Security
参考资料
- ↑ c - /dev/tcp not present in Linux - Unix and Linux
- ↑ shell文件名处理技巧
- ↑ joolix.com: Bash matrix 脚本
- ↑ linux - bash: get list of commands starting with a given string - Stack Overflow
- ↑ Unset readonly variable in bash - Stack Overflow
- ↑ 使用./script和bash script执行脚本有没有区别?,依云的评论
- ↑ shell - unexpected SIGTTIN after `bash -ic "/bin/echo hello"` when bash scripting - Stack Overflow
- ↑ ssh - In which cases is SIGHUP not sent to a job when you log out? - Unix & Linux Stack Exchange