Bash/函数
< Bash
(重定向自Bash/Functions)Bash 也支持函数。将函数添加到 ~/.bashrc
,或从 ~/.bashrc
source 的单独文件。更多 Bash 函数示例可以在 BBS#30155 中找到。
显示错误代码[编辑 | 编辑源代码]
要设置 trap
以拦截上次运行的程序的非零返回代码,请执行以下操作:
EC() {
echo -e '\e[1;33m'code $?'\e[m\n'
}
trap EC ERR
动态编译和执行 C 源代码[编辑 | 编辑源代码]
下面的函数将编译(在 /tmp/
目录中)并动态执行 C 源参数(并且执行过程将不带参数)。最后,在程序终止后,将删除已编译的文件。
# 动态编译和执行 C 源代码
csource() {
[[ $1 ]] || { echo "缺少操作数" >&2; return 1; }
[[ -r $1 ]] || { printf "文件 %s 不存在或不可读\n" "$1" >&2; return 1; }
local output_path=${TMPDIR:-/tmp}/${1##*/};
gcc "$1" -o "$output_path" && "$output_path";
rm "$output_path";
return 0;
}
提取[编辑 | 编辑源代码]
下面的函数将提取各种压缩文件类型。将其与语法 extract <file1> <file2> ...
一起使用
extract() {
local c e i
(($#)) || return
for i; do
c=''
e=1
if [[ ! -r $i ]]; then
echo "$0: 文件不可读: \`$i'" >&2
continue
fi
case $i in
*.t@(gz|lz|xz|b@(2|z?(2))|a@(z|r?(.@(Z|bz?(2)|gz|lzma|xz|zst)))))
c=(bsdtar xvf);;
*.7z) c=(7z x);;
*.Z) c=(uncompress);;
*.bz2) c=(bunzip2);;
*.exe) c=(cabextract);;
*.gz) c=(gunzip);;
*.rar) c=(unrar x);;
*.xz) c=(unxz);;
*.zip) c=(unzip);;
*.zst) c=(unzstd);;
*) echo "$0: 无法识别的文件扩展名: \`$i'" >&2
continue;;
esac
command "${c[@]}" "$i"
((e = e || $?))
done
return "$e"
}
注意: 确保
extglob
已启用:shopt -s extglob
,方法是将其添加到 ~/.bashrc
中(参见 gregswiki:glob#Options which change globbing behavior)。另一种方法是安装专门的软件包,请参阅归档与压缩#便利工具。
cd 与 ls 合二为一[编辑 | 编辑源代码]
通常更改到一个目录之后会使用 ls
命令来列出它的内容。因此,让第二个函数同时执行这两个操作是很有帮助的。
在这个例子中,我们将它命名为 cl
(change list),如果指定的目录不存在,则显示一条错误消息。
cl() {
local dir="$1"
local dir="${dir:=$HOME}"
if [[ -d "$dir" ]]; then
cd "$dir" >/dev/null; ls
else
echo "bash: cl: $dir: 找不到目录"
fi
}
当然,可以修改 ls 命令以满足您的需要,例如 ls -hall --color=auto
。
简单的记录者[编辑 | 编辑源代码]
note () {
# 若文件不存在,则创建它
if [[ ! -f $HOME/.notes ]]; then
touch "$HOME/.notes"
fi
if ! (($#)); then
# 无参数,印出文件
cat "$HOME/.notes"
elif [[ "$1" == "-c" ]]; then
# 清除文件
printf "%s" > "$HOME/.notes"
else
# 添加所有参数到文件
printf "%s\n" "$*" >> "$HOME/.notes"
fi
}
简单的任务实用程序[编辑 | 编辑源代码]
灵感来自#简单的记录者
todo() {
if [[ ! -f $HOME/.todo ]]; then
touch "$HOME/.todo"
fi
if ! (($#)); then
cat "$HOME/.todo"
elif [[ "$1" == "-l" ]]; then
nl -b a "$HOME/.todo"
elif [[ "$1" == "-c" ]]; then
> $HOME/.todo
elif [[ "$1" == "-r" ]]; then
nl -b a "$HOME/.todo"
eval printf %.0s- '{1..'"${COLUMNS:-$(tput cols)}"\}; echo
read -p "键入要删除的数字: " number
sed -i ${number}d $HOME/.todo "$HOME/.todo"
else
printf "%s\n" "$*" >> "$HOME/.todo"
fi
}
计算器[编辑 | 编辑源代码]
calc() {
echo "scale=3;$@" | bc -l
}
Kingbash[编辑 | 编辑源代码]
Kingbash - 菜单驱动的自动完成(参见 BBS#101010)。
从 AUR 安装 kingbash-gb-gitAUR,然后将以下内容插入你的 ~/.bashrc
:
function kingbash.fn() {
echo -n "KingBash> $READLINE_LINE" #其中 "KingBash> " 看起来最像你的 PS1,至少在长度上是这样的。
OUTPUT=$(/usr/bin/kingbash "$(compgen -ab -A function)")
READLINE_POINT=$(echo "$OUTPUT" | tail -n 1)
READLINE_LINE=$(echo "$OUTPUT" | head -n -1)
echo -ne "\r\e[2K"
}
bind -x '"\t":kingbash.fn'
IP 信息[编辑 | 编辑源代码]
有关 bash 中的 IP 地址或主机名的详细信息,通过 https://ipinfo.io 查询:
ipif() {
if grep -P "(([1-9]\d{0,2})\.){3}(?2)" <<< "$1"; then
curl ipinfo.io/"$1"
else
ipawk=($(host "$1" | awk '/address/ { print $NF }'))
curl ipinfo.io/${ipawk[1]}
fi
echo
}
注意: Bash 仅限于扩展正则表达式;此示例在 grep 中使用 perl 正则表达式。[1]