我想声明一些快捷命令来在我的各种编码项目之间切换,所以我想出了以下脚本。
projects=$(ls -d ~/Workspace/*/)
prefix="/Users/myuser/Workspace/"
for f in $projects
do
temp=${f#$prefix}
temp=${temp/%\//}
c="alias $temp='cd $f'"
echo $c
eval $c
done
我把它放在我的主文件夹中的一个文件中.workspace-shotcuts.sh
,然后我chmod +X .workspace-shotcuts.sh
就可以了。当我运行它时,使用./.workspace-shotcuts.sh
我得到
alias project1='cd /Users/myuser/Workspace/project1/'
alias project2='cd /Users/myuser/Workspace/project2/'
在控制台中。但别名没有声明( zsh: command not found: project1
)。
另外,在文件末尾.zshrc
我添加了/bin/sh .workspace-shotcuts.sh
,它提供了相同的输出,但仍然没有别名。
任何人都可以告诉我我错过了什么?我想指出的是,我不是一个优秀的 *nix 用户,所以你可能需要向我 ELI5 一些东西。
编辑:
建议我改用source
,我已经这样做了,但这是我收到的错误消息:
(eval):2: permission denied: /Users/myuser/Workspace/project1/
(eval):3: permission denied: /Users/myuser/Workspace/project2/
(eval):4: permission denied: /Users/myuser/Workspace/project3/
(eval):5: permission denied: /Users/myuser/Workspace/project4/
(eval):6: permission denied: /Users/myuser/Workspace/project5/
(eval):7: permission denied: /Users/myuser/Workspace/project6/
(eval):8: permission denied: /Users/myuser/Workspace/project7/
(eval):9: no such file or directory: /Users/myuser/Workspace/project1=cd /Users/myuser/Workspace/project1/\n/Users/myuser/Workspace/project2/\n/Users/myuser/Workspace/project3/\n/Users/myuser/Workspace/project4/\n/Users/myuser/Workspace/project5/\n/Users/myuser/Workspace/project6/\n/Users/myuser/Workspace/project7/
怎么了?我需要授予我的脚本一些特殊许可吗?
答案1
您的问题之一是您在单独的 shell 进程中执行了代码片段,这对父 shell 没有影响。这与中的问题相同如何使 shell 脚本中“导出”的环境变量保留下来?。您需要使用source
内置(也可以在名称下使用.
)在同一 shell 中执行脚本。
source ~/.workspace-shotcuts.sh
另一个问题是您正在尝试解析ls
.不要那样做。在 sh 和 bash 等 shell 中,您可以摆脱它,因为$projects
在引号之外写入会在分隔文件名的换行符处分割值。但它实际上不起作用:例如,如果文件名包含空格,它们将被分成以空格分隔的部分。在 shell 脚本中,不要解析 的输出ls
,而是使用通配符。这在 zsh 中相当简单。
projects=(~/Workspace/*/)
for f in $projects; do …
接下来你要做的事情相当复杂。你不需要eval
这里;使用它只会让你引用错误。由于您使用的是 zsh,因此您可以使用历史修改器 t
提取路径的最后一个组成部分,而不需要使用字符串操作结构:$f:t
。如果文件名包含特殊字符,您应该保护它们,并且 zsh 再次使这变得容易,这要归功于参数扩展标志 q
:${(q)f}
为您提供可在别名定义中使用的带引号的文件名。
projects=(~/Workspace/*/)
for f in $projects
do
alias $f:t="cd ${(q)f}"
done
但实际上,你只是在重新发明cdpath
加auto_cd
。刮掉所有这些并使用
setopt auto_cd
cdpath+=~/Workspace
该auto_cd
选项允许您键入要更改的目录名称,而无需cd
在其前面键入。这cdpath
是一个目录前缀数组,如果当前目录中cd foo
没有调用的子目录,则会尝试该数组。foo
如果 bash 用户看到这个线程:别名方法将是
projects=(~/Workspace/*/)
for f in "${projects[@]}"; do
f=${f%/}
alias ${f##*/}="cd '${f//\'/\'\\\'\'}'"
done
方法CDPATH
是
CDPATH=$CDPATH:$HOME/Workspace
shopt -s autocd