英文:
Using function instead alias misunderstands argument in zsh
问题
**问题**
我想将一个已经存在的别名更改为一个具有指定参数的函数。
原始代码:
```bash
# support Compose v2 as docker CLI plugin
(( ${+commands[docker-compose]} )) && dccmd='docker-compose' || dccmd='docker compose'
...
alias dcdn="$dccmd down"
...
我想要实现的:
# support Compose v2 as docker CLI plugin
(( ${+commands[docker-compose]} )) && dccmd='docker-compose' || dccmd='docker compose'
dcdn() {
if [ "$1" != "" ]
then
'$dccmd -f "$1" down'
else
"$dccmd down"
fi
}
我的期望
当我执行 dcdn
时,期望的结果是 docker-compose down
,如果我执行 dcdn docker-compose-dev.yml
,则应该运行 docker-compose -f docker-compose-dev.yml down
。
而实际上我得到的结果是 ''« down» 命令未找到''。
我尝试过的事情
我尝试了几种其他方法,但都没有成功,只是得到相同的错误或奇怪的“权限被拒绝”:
'$dccmd down' # $dccmd down not found
"dccmd down" # $dccmd down not found
"$aliases[dccmd] down" # «down» not found
"$dccmd" down # permission denied
'$dccmd' down # $dccmd not found
$dccmd down # «down» not found
dccmd down # «dccmd» not found
我甚至尝试了一些使用 eval 的选项,但结果仍然相同。
如果我直接使用 docker-compose down
,它可以正常工作,但那时我没有使用 dccmd 中存储的命令。
注意:我在其他帖子中看到“权限被拒绝”的原因可能是 dccmd 为空,但是为什么别名可以工作呢?
<details>
<summary>英文:</summary>
**The problem**
I want to change an already existing alias into a function to specify an argument.
The original code:
# support Compose v2 as docker CLI plugin
(( ${+commands[docker-compose]} )) && dccmd='docker-compose' || dccmd='docker compose'
...
alias dcdn="$dccmd down"
...
What I want to achieve:
# support Compose v2 as docker CLI plugin
(( ${+commands[docker-compose]} )) && dccmd='docker-compose' || dccmd='docker compose'
dcdn() {
if [ "$1" != "" ]
then
'$dccmd -f "$1" down'
else
"$dccmd down"
fi
}
**What I expect**
Then when I execute `dcdn` the result expected is `docker-compose down` and if I execute `dcdn docker-compose-dev.yml` it should runs `docker-compose -f docker-compose-dev.yml down`.
Instead the result I get is '« down» command not found'.
**Things I've tried**
I tried several other ways and nothing work, just givin same error or a strange "permission denied":
'$dccmd down' # $dccmd down not found
"dccmd down" # $dccmd down not found
"$aliases[dccmd] down" # «down» not found
"$dccmd" down # permission denied
'$dccmd' down # $dccmd not found
$dccmd down # «down» not found
dccmd down # «dccmd» not found
I even tried a few options with eval with same results.
If I use `docker-compose down` directly it works, but then I'm not using the command stored in dccmd.
NOTE: I saw in other posts that the permission denied could be because dccmd is "" but then why the alias works?
</details>
# 答案1
**得分**: 2
你的引用不正确。你不想要将命令及其所有参数放在一个单一的 shell 单词中,这正是引用整个命令所实现的。
```bash
dcdn () {
if [ -n "$1" ]
then
"$dccmd" -f "$1" down
else
"$dccmd" down
fi
}
然而,这依然不会工作,原因类似:如果你设置 dccmd="docker compose"
,现在 "$dccmd"
展开不是两个单词,一个命令和它的第一个参数,而是一个包含空格的单词,而字符串 docker compose
不是一个命令的名称。
解决方案是定义另一个函数,而不是一个参数。
if (( ${+commands[docker-compose]} )); then
dccmd () { docker-compose "$@" }
else
dccmd () { docker compose "$@" }
fi
dcdn () {
if [ -n "$1" ]
then
dccmd -f "$1" down
else
dccmd down
fi
}
英文:
Your quoting is incorrect. You don't want the command and all its arguments in a single shell word, which is what quoting the entire command accomplishes.
dcdn () {
if [ -n "$1" ]
then
"$dccmd" -f "$1" down
else
"$dccmd" down
fi
}
This still won't work, though for a similar reason: if you set dccmd="docker compose"
, now "$dccmd"
expands not to two words, a command and its first argument, but to a single word that contains a space, and the string docker compose
is not the name of a command.
The solution is to define another function, not a parameter.
if (( ${+commands[docker-compose]} )); then
dccmd () { docker-compose "$@" }
else
dccmd () { docker compose "$@" }
fi
dcdn () {
if [ -n "$1" ]
then
dccmd -f "$1" down
else
dccmd down
fi
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论