Bash/函数

出自 ArchWiki

Bash 也支持函数。将函数添加到 ~/.bashrc,或从 ~/.bashrc source 的单独文件中。更多 Bash 函数示例可以在 BBS#30155 中找到。

显示错误代码

设置 trap 以拦截上次运行的程序的非零返回代码

EC() {
	echo -e '\e[1;33m'code $?'\e[m\n'
}
trap EC ERR

即时编译并执行 C 源代码

以下函数将(在 /tmp/ 目录中)编译并即时执行 C 源代码参数(并且执行将不带参数)。最后,在程序终止后,将删除已编译的文件。

# Compile and execute a C source on the fly
csource() {
	[[ $1 ]]    || { echo "Missing operand" >&2; return 1; }
	[[ -r $1 ]] || { printf "File %s does not exist or is not readable\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: file is unreadable: \`$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: unrecognized file extension: \`$i'" >&2
                   continue;;
        esac

        command "${c[@]}" "$i"
        ((e = e || $?))
    done
    return "$e"
}
注意: 确保 extglob 已启用:shopt -s extglob,通过将其添加到 ~/.bashrc(参见 gregswiki:glob#Options which change globbing behavior)。

另一种方法是安装专门的软件包,请参阅 Archiving and compression tools#Convenience tools

cd 和 ls 合二为一

通常,更改目录后会紧跟 ls 命令以列出其内容。因此,有一个函数可以一次完成这两件事会很有帮助。在此示例中,我们将其命名为 cl(更改列表),如果指定的目录不存在,则显示错误消息。

cl() {
	local dir="$1"
	local dir="${dir:=$HOME}"
	if [[ -d "$dir" ]]; then
		cd "$dir" >/dev/null; ls
	else
		echo "bash: cl: $dir: Directory not found"
	fi
}

当然,可以更改 ls 命令以满足您的需求,例如 ls -hall --color=auto

简易记事本

note () {
    # if file doesn't exist, create it
    if [[ ! -f $HOME/.notes ]]; then
        touch "$HOME/.notes"
    fi

    if ! (($#)); then
        # no arguments, print file
        cat "$HOME/.notes"
    elif [[ "$1" == "-c" ]]; then
        # clear file
        printf "%s" > "$HOME/.notes"
    else
        # add all arguments to file
        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 "Type a number to remove: " number
        sed -i ${number}d $HOME/.todo "$HOME/.todo"
    else
        printf "%s\n" "$*" >> "$HOME/.todo"
    fi
}

计算器

calc() {
    echo "scale=3;$@" | bc -l
}

IP 信息

通过 https://ipinfo.io 在 bash 中获取有关 IP 地址或主机名的详细信息

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 仅限于扩展正则表达式;此示例将 perl 正则表达式与 grep 一起使用。 [1]