[英]zsh: no such file or directory: - but file exists
Background: I already have a working alias my-tool
as follows:背景:我已经有一个工作别名
my-tool
如下:
alias my-tool='~/path/to/src/my-tool.py'
I want another alias that depends on that alias' path (so I don't write the path in two places):我想要另一个依赖于该别名路径的别名(所以我不在两个地方写路径):
alias other-tool=$'$(dirname $(dirname $(which my-tool | awk \'{ print($NF) }\')))/script/other-tool.sh'
which outputs the error输出错误
zsh: no such file or directory: ~/path/to/script/other-tool.sh
but it exists!但它存在!
Strangely, if I replace the alias with奇怪的是,如果我将别名替换为
alias other-tool=$'$(dirname $(dirname ~/path/to/src/my-tool.py))/script/other-tool.sh'
it works, but again I want to avoid entering the ~/path/to/..
twice它有效,但我想再次避免输入
~/path/to/..
两次
Clearly there's unexpected behavior in either awk
, dirname
or which
, can anyone explain why the error?显然
awk
, dirname
或which
中存在意外行为,谁能解释错误原因?
There are definitely better ways to do this (I like the path prefix variable mentioned by @Luuk in a comment), but a working equivalent to what you're trying is:肯定有更好的方法来做到这一点(我喜欢@Luuk 在评论中提到的路径前缀变量),但与您正在尝试的工作等效的是:
alias other-tool=$'loc=($(type my-tool)); ${~loc[-1]:h:h}/script/other-tool.sh'
Instead of running awk
and a couple of dirname
processes each time you run the alias, this uses zsh
parameter substutitions intead - first it sets the loc
array variable to the result of running type my-tool
, with each word its own element, then for the last element (The path): The :h
modifier acts like dirname
, done twice, and then the ~
turns on the GLOB_SUBST
option for that expansion, which among other things does filename expansion, catching the ~
.每次运行别名时都不会运行
awk
和几个dirname
进程,而是使用zsh
参数替换 - 首先它将loc
数组变量设置为运行type my-tool
的结果,每个单词都有自己的元素,然后为最后一个元素(路径): :h
修饰符的作用类似于dirname
,执行两次,然后~
为该扩展打开GLOB_SUBST
选项,其中包括文件名扩展,捕获~
。
There's a tilde character at the beginning of the alias.别名的开头有一个波浪号。 This works when the alias is invoked as a command, because the result of the alias expansion undergoes word expansion.
这在将别名作为命令调用时有效,因为别名扩展的结果会经历单词扩展。 But then you attempt to do some processing on the text of the alias, which results in a string that you want to use as a path.
但是随后您尝试对别名的文本进行一些处理,这会产生一个您想要用作路径的字符串。 That string still contains a tilde character, so you're attempting to use a directory called
~
.该字符串仍然包含一个波浪号,因此您正在尝试使用一个名为
~
的目录。
If you really want to use the my-tool
alias as a basis for defining the other-tool
alias, do the string processing at the time you define the alias.如果您确实想使用
my-tool
别名作为定义other-tool
别名的基础,请在定义别名时进行字符串处理。 Don't use type
or which
: they're end-user commands that display additional messages.不要使用
type
或which
:它们是显示附加消息的最终用户命令。 Reach directly for the text of the alias, using the aliases
associative array .使用
aliases
关联数组直接获取别名文本。 Use zsh's built-in constructs for manipulating strings ( parameter expansion ) or paths (history modifiers ): they're easier to get right than using external tools.使用 zsh 的内置构造来操作字符串( 参数扩展)或路径(历史修饰符):它们比使用外部工具更容易正确处理。
alias other-tool=$aliases[my-tool]:h:h/scripts/other-tool.sh
or或者
alias other-tool=${aliases[my-tool]%/*/*}/scripts/other-tool.sh
But it would be both conceptually simpler and more reliable to instead define a variable with the root path, and use that variable in both aliases.但是,用根路径定义一个变量,并在两个别名中使用该变量,这在概念上会更简单也更可靠。
tool_root=~/path/to
alias my-tool='$tool_root/src/my-tool.py'
alias other-tool='$tool_root/scripts/other-tool.py'
the way i deal with tilde ( ~
) is simply expand it out once instead of hard-quoting them with single quotes ( '
)- this way i wouldn't have to go manually replace it with "${HOME}"
:我处理波浪号(
~
)的方式只是将其展开一次,而不是用单引号( '
)硬引用它们——这样我就不必 go 手动将其替换为"${HOME}"
:
testfn="$( grealpath -ePq ~/.zshenv )" # g- for gnu
echo "${testfn}"
ls -AlF "${testfn}"
/Users/user123/.bash_profile
-rw-r--r-- 1 user123 staff 1746187 Aug 27 23:54 /Users/user123/.bash_profile
And that's actually a correct output, since my zsh
environment file is actually a symlink:这实际上是一个正确的 output,因为我的
zsh
环境文件实际上是一个符号链接:
lr--r--r-- 1 user123 staff 15 Dec 31 2019 /Users/user123/.zshenv -> ./.bash_profile
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.