bash

来自百合仙子's Wiki
跳转到导航 跳转到搜索

命令行编辑

bash 的命令行编辑有很多和 zsh 的相同或类似,参见 zsh#命令行编辑

^X^E
使用默认编辑器编辑命令行

命令行选项

bash的命令行选项有很多和zsh的相同或类似,参见zsh#命令行选项。这些选项也可以使用set [+-]x这种方式开关。

-x
打印执行的命令
-e
在返回值非零的命令后以错误退出

重定向

Bash Redirections Cheat Sheet

特殊文件

/dev/tcp/host/port
打开到host:portTCP连接
/dev/udp/host/port
打开到host:portUDP连接

现在,此/dev/tcp/dev/udp设备实际并不存在,是由 bash 提供的虚拟文件(它们曾经是TLI/XTI interface的一部分)。[1]

PS1

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

[2]

代码片断

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 被设置为只读

可以使用 gdb 来删除这个变量:[5]

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 为执行最后一条命令进行优化时,会将忽略 SIGINTSIGQUIT 的行为遗传给该命令。比如

bash -c 'sleep 1000 &'

此 sleep 命令无法被 SIGINT 杀死。

zshdash 都不会这样。

默认正常退出时不发送 SIGHUP

bash 在正常退出时不会发送 SIGHUP。只有它收到 SIGHUP 时(比如终端消失),它才会给其任务发送 SIGHUP。[8]使用 shopt -s huponexit 来让其交互式登录 shell 退出时也发送 SIGHUP。

zsh 默认退出时会发送 SIGHUP 信号。使用 HUP 选项可以更改此行为。

参见

外部链接

解析和求值

  • Evalbot, an IRC bot that will safely evaluate arbitrary bash commands. 使用 qemu 来安全地运行 bash 脚本

安全相关

参考资料