使用.bash_profile中定义的xargs调用函数

问题描述 投票:0回答:1

我在我的.bash_profile中添加了以下两个函数

function dc(){
    local command="docker container $@"
    echo $command
    eval $command
}

function dcp(){
    local params=$@
    local result=""
    for attr in $params
    do
        result=$result"{{.$attr}}\t"
    done

    local params="--format \"table $result\""

    echo "$params"
}

现在请在采购后找到以下执行.bash_profile: -

~ $

dc ls
docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
bb1bb407f422        busybox             "sh"                2 hours ago         Up 2 hours                              foo
6b0bfe6d8615        busybox             "sh"                2 hours ago         Up 2 hours                              baz

~ $

dcp Image ID
--format "table {{.Image}}\t{{.ID}}\t"

~ $

dcp Image ID | xargs docker container ls
IMAGE               CONTAINER ID
busybox             bb1bb407f422
busybox             6b0bfe6d8615

~ $

dcp Image ID | xargs dc ls
dc: unrecognized option `--format'
Usage: dc [OPTION] [file ...]
  -e, --expression=EXPR    evaluate expression
  -f, --file=FILE          evaluate contents of file
  -h, --help               display this help and exit
  -V, --version            output version information and exit

Email bug reports to:  [email protected] .

现在,xargs dc ls没有转换为xargs docker容器ls

如何告诉xargs扩展dc ls调用


编辑1: -

按照建议,我更新.bash_profile中的代码,如下所示: -

dcCall(){
    echo "params are : >$@<"
    local command=( docker images "$@" )
    echo ${command[*]}
    ${command[@]}
}

export -f dcCall
alias dc="xargs bash -c 'dcCall "$@"'"


dcp(){
    local params=$@
    local result=""
    for attr in $params
    do
        result=$result"{{.$attr}}\t"
    done

    local params="--format \"table $result\""

    echo "$params"
}

现在,dc被声明为别名,因此它可以像: -

dcp Repository ID | dc

但执行上述命令会得到以下结果: -

~ $

dcp Repository ID | dc
params are : ><
docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
clouderassh                    latest              93f38a6c0288        34 hours ago        6.81GB
busybox                        latest              d8233ab899d4        8 days ago          1.2MB
microsoft/mssql-server-linux   2017-CU8            229d30f7b467        8 months ago        1.43GB
cloudera/quickstart            latest              4239cd2958c6        2 years ago         6.34GB

现在,dcp存储库ID的参数没有传递给dc,并且params在dcCall函数中变为空。

bash function expand
1个回答
1
投票
  1. 您不需要同时使用“function”关键字和括号。
  2. I'm trying to put a command in a variable, but the complex cases always fail!
  3. Security implications of forgetting to quote a variable in bash/POSIX shells

使用数组来存储命令,然后你不需要eval

dc() {
    local command=( docker container "$@" )
    echo "${command[*]}"   # print it
    "${command[@]}"        # execute it
}

并通过xargs访问您的功能:

dcp Image ID | xargs bash -XXX 'dc "$@"' _ ls
  1. 如果你把dc函数放在〜/ .profile或〜/ .bash_profile中,那么-XXX就是-lc
  2. 如果你把dc函数放在〜/ .bashrc中,那么-XXX就是-ic
  3. 如果你export -f dc,那么-XXX就是-c

ref:https://www.gnu.org/software/bash/manual/bash.html#Bash-Startup-Files


你的“编辑1”:

  • 缺少dcCall函数中所需的双引号(如上面的函数所示)
  • 别名是用双引号字符串定义的,因此在定义别名时将展开shell变量。

别名不是答案。如果你想要dcp Repository ID | dc ls的行为,那么

dc() {
    xargs docker container "$@"
}

从更大的图片来看,似乎dcp函数专门为docker container ls命令生成参数,不是吗?如果是,那么我将该xargs管道折叠成一个函数:

dls() {
    local OPTIND OPTARG
    local params=()

    while getopts ':p:' opt; do
        case $opt in
            p) params+=( "{{.$OPTARG}}"$'\t' ) ;;
            ?) echo "unknown option: -$OPTARG" >&2 ;;
        esac
    done
    shift $((OPTIND - 1))

    local docker_params=()
    if (( ${#params[@]} != 0)); then 
        docker_params+=( --format "table ${params[*]}" )
    fi

    echo docker container ls "${docker_params[@]}" "$@"
}

而你就像使用它一样

dls -p Image -p ID
© www.soinside.com 2019 - 2024. All rights reserved.