简体   繁体   English

zsh:没有这样的文件或目录:-但文件存在

[英]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?显然awkdirnamewhich中存在意外行为,谁能解释错误原因?

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.不要使用typewhich :它们是显示附加消息的最终用户命令。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM