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

时间:2019-02-23 13:36:53

标签: bash function expand

我在.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:  bug-dc@gnu.org .

现在, 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 函数中的 dc 参数为空

1 个答案:

答案 0 :(得分: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函数中缺少必需的双引号(如我上面的函数所示)
  • 别名是用双引号引起来的字符串定义的,因此定义别名时将扩展外壳变量

别名不是答案。如果您想要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