Bash/函數 - Arch Linux 中文维基

跳至內容

# Bash/函數

出自 Arch Linux 中文维基
< Bash
翻譯狀態：

- 本文（或部分內容）譯自 Bash/Functions，最近一次同步於 2023-2-12，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 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 源參數（並且執行過程將不帶參數）。最後，在程序終止後，將刪除已編譯的文件。

    # 动态编译和执行 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]
分類：​

- 命令行解釋器

Bash/函數
新增話題