linux Bash中的Wrap/overwrite函数

oyxsuwqo  于 2023-11-17  发布在  Linux
关注(0)|答案(3)|浏览(189)

我如何重写echo来在我传递给它的任何东西之前打印一些字符?
我在想这样的事情,它不工作:

alias oldecho=echo
echo(){oldecho ==> $1}

字符串

j5fpnvbx

j5fpnvbx1#

近了

echo() { builtin echo "==>" "$@"; }

字符串
builtin强制命令的其余部分作为内置函数执行,这简化了内置函数的重新实现。
但是,您的问题在于没有引用>

t98cgbkg

t98cgbkg2#

我不太明白你的意思,但也许这会有帮助...
第一个月
.这里我假设==>是你总是想要前缀的字符。
(note反斜杠\,您需要防止>被解释为重定向。

jogvjijk

jogvjijk3#

受Python装饰器的启发,我写了一个函数来 Package bash函数、内置命令和对可执行文件的调用。

# bashwrap function: given a function name and code to run before and/or after,
# wrap the existing function with the code that comes before and after.  The
# before and after code is taken literally and eval'd, so it can do things like
# access "$@" and indeed change "$@" by using shift or set or similar.
bashwrap () {
    local command beforecode aftercode type unset_extglob n
    local innerfuncname innerfunccode
    local -n varname

    command="$1"
    beforecode="$2"
    aftercode="$3"

    # Check the current state of extglob: this code needs it to be set,
    # but it should be reset to avoid unexpected changes to the global
    # envirnoment.
    if ! shopt -q extglob; then
        unset_extglob=YesPlease
        shopt -s extglob
    fi

    # Tidy the before and after code: trim whitespace from the start and end,
    # and make sure they end with a single semicolon.
    for varname in beforecode aftercode; do
        varname="${varname##+([$'\n\t '])}"
        varname="${varname%%+([$'\n\t '])}"
        if [[ "$varname" ]]; then
            varname="${varname%%+(;)};"
        fi
    done

    # Now finished with extglob.
    if [[ "$unset_extglob" ]]; then shopt -u extglob; fi

    type="$(type -t "$command")"
    case "$type" in
        alias)
            printf "bashwrap doesn't (yet) know how to handle aliases\n" >&2
            return 69  # EX_UNAVAILABLE
            ;;
        keyword)
            printf 'bashwrap cannot wrap Bash keywords\n' >&2
            return 64  # EX_USAGE
            ;;
        builtin|file)
            eval "$command () { $beforecode command $command \"\$@\"; $aftercode }"
            ;;
        function)
            # Keep generating function names until we get to one that doesn't
            # exist.  This allows a function to be wrapped multiple times; the
            # original function will always have the name
            # _bashwrapped_0_<name>.
            n=0
            innerfuncname="_bashwrapped_${n}_$command"
            while declare -Fp -- "$innerfuncname" &>/dev/null; do
                innerfuncname="_bashwrapped_$((++n))_$command"
            done

            # Define a new function with the new function name and the old function
            # code.
            innerfunccode="$(declare -fp -- "$command")"
            eval "${innerfunccode/#$command /$innerfuncname }"

            # Redefine the existing function to call the new function, in
            # between the wrapper code.
            eval "$command () { $beforecode $innerfuncname \"\$@\"; $aftercode }"
            ;;
        '')
            printf 'Nothing called %q found to wrap\n' "$command" >&2
            return 64  # EX_USAGE
            ;;
        *)
            printf 'Unexpected object type %s\n' "$type" >&2
            return 70  # EX_SOFTWARE
            ;;
    esac
}

字符串
原始问题中的简单情况可以如下处理;使用command来避免echo调用我们正在创建的函数。

$ bashwrap echo 'command echo -n "==> "'
$ echo 'Hello, world!'
==> Hello, world!


您可以使用type来查看幕后发生的事情:

$ type echo
echo is a shell builtin
$ bashwrap echo 'command echo "==> "'
$ type echo
echo is a function
echo ()
{
    command echo "==> ";
    command echo "$@"
}


这也允许更复杂的 Package ,包括重复 Package 函数:

$ bashwrap echo 'command echo earlier' 'command echo later'
$ bashwrap echo 'command echo earliest'
$ bashwrap echo '' 'command echo latest'
$ echo 'Hello, world!'
earliest
earlier
Hello, world!
later
latest

相关问题