linux 使用bash脚本创建类和对象

n8ghc7c1  于 2023-01-25  发布在  Linux
关注(0)|答案(5)|浏览(264)

我尝试使用bash脚本来使脚本像电话簿一样工作,所以我尝试创建类和对象,但不幸的是我找不到这样做的方法!所以我问如何使用bash脚本创建类?

n7taea2i

n7taea2i1#

你可以试着这样做
example.sh

#!/bin/bash

# include class header
. obj.h
. system.h

# create class object
obj myobject

# use object method
myobject.sayHello

# use object property
myobject.fileName = "file1"

system.stdout.printString "value is"
system.stdout.printValue myobject.fileName

obj.h

obj(){
    . <(sed "s/obj/$1/g" obj.class)
}

obj.class

# Class named "obj" for bash Object

# property
obj_properties=()

# properties IDs
fileName=0
fileSize=1

obj.sayHello(){
    echo Hello
}

obj.property(){
    if [ "$2" == "=" ]
    then
        obj_properties[$1]=$3
    else
        echo ${obj_properties[$1]}
    fi
}

obj.fileName(){
    if [ "$1" == "=" ]
    then
        obj.property fileName = $2
    else
        obj.property fileName
    fi
}

system.h

. system.class

system.class

system.stdout.printValue(){
    echo $($@)
}

system.stdout.printString(){
    echo $@
}

参考链接:关键是你不能创建对象,但是你可以在bash中模拟面向对象的编程。

**UPD:**经过这么多年,我决定给“继承”加上一个提示,因为很明显没有办法实现一个真正的继承,尽管如此,组合可以像一个继承一样直观地呈现出来。要做到这一点,我们在第一个例子中已经有了几乎所有的东西。有了上面所有的脚本,我们可以做一件非常简单的事情,比如:

obj2.h

obj2(){
    . <(sed "s/obj2/$1/g" obj2.class)
}

obj2.class

# Class named "obj2" for bash Object

obj2.sayGoodbye(){
    echo Goodbye
}

以及www.example.com的更新版本example.sh

#!/bin/bash

# include class headers
. obj.h
. obj2.h
. system.h

# create class object
obj myobject
obj2 myobject

# use object methods
myobject.sayHello
myobject.sayGoodbye # method "inherited" from obj2

myobject.fileName = "file1"

system.stdout.printString "value is"
system.stdout.printValue myobject.fileName

所以,如果你让obj myobjectobj2 myobject看起来像inherit myobject from obj obj2,这很简单,它看起来更像一个继承(当然,它仍然不是一个继承)。

**UPD2:**跟进关于在bash3上运行的评论。应该很容易修复。只需将www.example.com中的$1替换obj.property为${!1}并尝试运行它。

z3yyvxxp

z3yyvxxp2#

Bash是一种脚本语言,不支持OOP,所以你不能。试试Python。
你唯一能做的就是有几个数组,但那很混乱,用索引来链接它们。

z9smfwbn

z9smfwbn3#

所以我记得几年前检查了这个问题和答案...然后在想...什么!
然后上周我仔细看了一下@马克西姆的答案,然后就清楚了。
我花了最后一周的时间,创建了一个bash类转发器和类对象的类加载器,方法和其他好东西..所有的原因,我想创建一个终端动画基础设施:

因此,虽然这只是一个开始,我发现这是一个超级酷和具有挑战性的冒险。。I hope my code would help someone else as well
顺便说一句:只在Mac OS上测试过,所以可能需要一些调整:)

xeufq47z

xeufq47z4#

虽然在Bash中没有真正的方法来创建类,但你可以有一点创造性。多年来我发现,我更喜欢的方法是创建一个函数,该函数返回一个命令,执行该命令可以改变示例的状态或读取属性。示例数据可以存储在数组中。
例如,如果你想创建一个二叉搜索树类,你可以在BinarySearchTree.sh中创建这样的类:

__BINARYSEARCHTREE_INSTANCE_DATA__=()

__BINARYSEARCHTREE_INSTANCE_DATA_LENGTH__=()
__BINARYSEARCHTREE_INSTANCE_DATA_SIZE__=()

BinarySearchTree()
{
    echo "__BinarySearchTree__ $RANDOM "
}

__BinarySearchTree__()
{
    local id="$1"
    local code="$2"

    case "$code" in
        '.insert' | '[insert]' | "['insert']" | '["insert"]')
            local value="$3"

            if [ "${__BINARYSEARCHTREE_INSTANCE_DATA__["$id", 0] + set}" ]; then
                local length="${__BINARYSEARCHTREE_INSTANCE_DATA_LENGTH__["$id"]}"
                local new_node="$length"

                __BINARYSEARCHTREE_INSTANCE_DATA__["$id", "$length"]="$value"

                length=$((length + 1))
                __BINARYSEARCHTREE_INSTANCE_DATA__["$id", "$length"]=''

                length=$((length + 1))
                __BINARYSEARCHTREE_INSTANCE_DATA__["$id", "$length"]=''

                local current_node=0
                local parent

                while [ 1 ]; do
                    parent="$current_node"

                    if [ "$value" -lt "${__BINARYSEARCHTREE_INSTANCE_DATA__["$id", "$((current_node))"]}" ]; then
                        current_node="${__BINARYSEARCHTREE_INSTANCE_DATA__["$id", "$((current_node + 1))"]}"

                        if [ "$current_node" == '' ]; then
                            __BINARYSEARCHTREE_INSTANCE_DATA__["$id", "$((parent + 1))"]="$new_node"

                            break
                        fi
                    else
                        current_node="${__BINARYSEARCHTREE_INSTANCE_DATA__["$id", "$((current_node + 2))"]}"

                        if [ "$current_node" == '' ]; then
                            __BINARYSEARCHTREE_INSTANCE_DATA__["$id", "$((parent + 2))"]="$new_node"

                            break
                        fi
                    fi
                done

                __BINARYSEARCHTREE_INSTANCE_DATA_LENGTH__["$id"]="$((length + 1))"
                __BINARYSEARCHTREE_INSTANCE_DATA_SIZE__["$id"]="$((${__BINARYSEARCHTREE_INSTANCE_DATA_SIZE__["$id"]} + 1))"
            else
                __BINARYSEARCHTREE_INSTANCE_DATA__["$id", 0]="$value"
                __BINARYSEARCHTREE_INSTANCE_DATA__["$id", 1]=''
                __BINARYSEARCHTREE_INSTANCE_DATA__["$id", 2]=''
                __BINARYSEARCHTREE_INSTANCE_DATA_LENGTH__["$id"]=3
                __BINARYSEARCHTREE_INSTANCE_DATA_SIZE__["$id"]=1
            fi;;

        '.has' | '[has]' | "['has']" | '["has"]')
            local value="$3"

            local current_node=0

            if [ "${__BINARYSEARCHTREE_INSTANCE_DATA__["$id", 0] + set}" ]; then
                while [ 1 ]; do
                    local current_value="${__BINARYSEARCHTREE_INSTANCE_DATA__["$id", "$((current_node))"]}"

                    if [ "$current_value" == "$value" ]; then
                        return 0
                    fi

                    if [ "$value" -lt "$current_value" ]; then
                        current_node=${__BINARYSEARCHTREE_INSTANCE_DATA__["$id", "$((current_node + 1))"]}
                    else
                        current_node=${__BINARYSEARCHTREE_INSTANCE_DATA__["$id", "$((current_node + 2))"]}
                    fi

                    if [ "$current_node" == '' ]; then
                        return 1
                    fi
                done
            else
                return 1
            fi;;

        '.size' | '[size]' | "['size']" | '["size"]')
            if [ "${__BINARYSEARCHTREE_INSTANCE_DATA__["$id", 0] + set}" ]; then
                echo "${__BINARYSEARCHTREE_INSTANCE_DATA_SIZE__["$id"]}"
            else
                echo 0
            fi;;

        '.empty' | '[empty]' | "['empty']" | '["empty"]')
            if [ "${__BINARYSEARCHTREE_INSTANCE_DATA__["$id", 0] + set}" ]; then
                return 1
            else
                return 0
            fi;;

        '.clear' | '[clear]' | "['clear']" | '["clear"]')
            unset "__BINARYSEARCHTREE_INSTANCE_DATA__[$id, 0]"
    esac
}

然后制作这样的对象:

source './BinarySearchTree.sh'

process()
{
    local tree="$1"

    $tree.insert 52
    $tree.insert -150
    $tree.insert 42

    if $tree.has 42; then
        echo 'Has 42!'
    else
        echo 'Does not have 42!'
    fi

    $tree.clear

    echo "Size: $($tree.size)"
}

main()
{
    local tree=$(BinarySearchTree)

    process "$tree"
}

main "$#" "$@"

这个方法的优点是对象可以被传递给其他函数,并且没有外部文件操作。尽管这看起来不切实际,但它实际上使Bash成为一种很好的语言,因为你可以模块化你的类。

x4shl7ld

x4shl7ld5#

尝试使用 * BashX *:https://github.com/reduardo7/bashx(这是我的项目,我在其他几个项目上使用它)

示例

#!/usr/bin/env bash

# ...

@Actions.action1() { # \\n Action without arguments
  set -x
  pwd
  @log "
  Action 1
  Multi-Line
"
  ls -la
  bash
}

@Actions.action2() { # param1 [param2] \\n Action with arguments\\n\\tdescription second line\\nother line
  eval "$(@user.options 'new:-n|-N' 'path:-p|--path:true')"
  set -x

  @log "'n' or 'N' parameter: ${user_options_new}"
  @log "'p' or 'path' parameter: ${user_options_path[@]} (${#user_options_path[@]})"

  local param1="$1"
  local param2="$2"
  [[ "$param1" != 'asd' ]] && @throw.invalidParam param1

  @log Action 2
  @log Param1: $1
  @log Param2: $2
}

@app.run "$@"

用法

./myscript action1
./myscript action2 -n -p /tmp 'my param 1'

相关问题