似乎无法弄清楚问题是什么。这是在具有默认设置(bash、gnome 等...)的 Fedora 37 上。
我想要实现的是创建一个别名来创建一个 python 虚拟环境,其中虚拟环境的文件夹名称是当前工作目录的名称(类似于python3 -m venv $cwd
)。
这很有用,特别是在激活 venv(以及稍后在项目之间切换目录)时,您可以轻松识别启用了哪个 venv。
但由于某种奇怪的原因,这并没有像我预期的那样工作。需要注意的是,我在创建复杂别名方面没有太多经验,但仍然如此。我在中创建了以下变量.bashrc
:
export cwd="pwd | rev | cut -d '/' -f1 | rev"
test
如果我在终端中运行它,它会根据需要显示目录名称,但是当$cwd
在终端中运行时,我得到home/<USERNAME>/Projects/VueJS/test
export cwd2="${PWD##*/}"
- 由于某种原因,这个只是显示我的用户名。我在 stackoverflow 上搜索过,这是获取当前目录名称的建议方法之一
关于如何开始或在哪里查找信息的一些指示值得赞赏。我尝试搜索多个来源,但我似乎无法弄清楚。我在某处读到双引号和单引号有区别,但我无法理解为什么以及它是否会影响这种行为。
编辑:为了澄清,我希望我的别名运行的是:
python3 -m venv <CURRENT_DIRECTORY_NAME> && source <CURRENT_DIRECTORY_NAME>/bin/activate && [ ! -f ./requirements.txt ] || pip install -r requirements.txt
- 这为 python 项目创建了一个虚拟项目
python3 -m venv <CURRENT_DIRECTORY_NAME> && source <CURRENT_DIRECTORY_NAME>/bin/activate && pip install nodeenv && nodeenv -p
- 这为依赖于nodejs的项目创建了虚拟环境,而nodejs本身又依赖于python venv
答案1
出什么问题了$cwd
?
当您使用cwd="pwd | rev | cut -d '/' -f1 | rev"
然后$cwd
您实际上正在pwd
使用参数运行(您不通过管道输出)。所以基本上你正在运行这样的东西:
pwd '|' rev '|' cut '-d' "'/'" '-f1' '|' rev
您不会看到任何错误,因为pwd
将忽略非选项参数。如果您使用/bin/pwd
而不是pwd
内置的,您会注意到以下消息:
$> /bin/pwd '|'
#Output
/bin/pwd: ignoring non-option arguments
您可以使用以下简单的方法测试该行为script.sh
:
#! /usr/bin/env bash
printf "I got: %s\n" "$@"
确保将执行权限设置为script.sh
现在将您的更改cwd
为:
cwd="./script.sh | rev | cut -d '/' -f1 | rev"
并运行$cwd
:
(shell)> $cwd
#Output
I got: |
I got: rev
I got: |
I got: cut
I got: -d
I got: '/'
I got: -f1
I got: |
I got: rev
正如您在上面看到的,脚本./script.sh
实际上获取了值,因为它们是作为参数传递的,因此它们没有通过管道传输。
如果您确实想通过管道传输存储在变量中的内容,$cwd
则必须使用eval
,如下所示:
eval $cwd
#Output:
test
我建议您使用functions
而不是使用字符串来运行命令(您将避免此类问题):
getBaseName() {
pwd | rev | cut -d '/' -f1 | rev
}
getBaseName
#Output:
test
顺便说一句,您想要做的事情(仅打印测试)可以通过使用以下命令来实现basename
:
basename $(pwd)
#Output:
test
关于你的命令您想为它们创建一个别名。再次,我建议您使用函数(在我看来,别名应该用于简短/非复杂的命令)
因此,您可以为两个脚本创建一个函数。另外我建议您使用.
as<CURRENT_DIRECTORY_NAME>
因为使用 a.
将引用您当前的目录。如果您传递此输出,$cwd
则不会引用您的当前路径,而是引用当前路径中可能不存在的目录。
我上面的意思是,如果你位于这条路径下:
home/<USERNAME>/Projects/VueJS/test
你用$cwd
它来传递当前工作目录像这样的 python venv:python3 -m venv "$cwd"
你实际传递的是这个路径,home/<USERNAME>/Projects/VueJS/test/$cwd
在你的情况下cwd
,test
你传递的真实路径是:home/<USERNAME>/Projects/VueJS/test/test
。
解决你的“别名”
createVenv() {
python3 -m venv . && source ./bin/activate && [ ! -f ./requirements.txt ] || pip install -r requirements.txt
}
createVenvNode(){
python3 -m venv . && source ./bin/activate && pip install nodeenv && nodeenv -p
}
或者,由于您确实想venv
在新文件夹中创建一个环境(其名称应该是当前目录的基本名称),那么函数将是:
createVenv() {
# dest="${PWD##*/}"
# You can run the function `getBaseName` and assign its output like this:
dest=$(getBaseName)
if python3 -m venv "$dest" ; then
cd "$dest"
source "./bin/activate"
[ ! -f "./requirements.txt" ] || pip install -r requirements.txt
echo You are now in new venv environment
else
echo "Failed to create 'venv' environment" >&2
fi
}
createVenvNode(){
# dest="${PWD##*/}"
# You can run the function `getBaseName` and assign its output like this:
dest=$(getBaseName)
if python3 -m venv "$dest" ; then
cd "$dest"
source "./bin/activate"
# You can test the exit status of these commands with an if statement too
pip install nodeenv && nodeenv -p
echo You are now in new venv environment
else
echo "Failed to create 'venv' environment" >&2
}
答案2
这不是你做别名的方式......尝试
alias cwd="pwd | rev | cut -d '/' -f1 | rev"
你的情况是,当 bashrc 被获取时,它们会被评估一次,并且你的用户名恰好是你的主目录的名称,即 bashrc 被获取时的最后一个路径元素。