我的默认 shell(在 Ubuntu 上)是 bash。但是,对于特定程序,我需要更改为 C-shell。为此,我设置了一个 .cshrc 文件,但是,如果我以交互方式更改为 C-shell(为此我使用 tcsh 命令),我注意到所有 bash 路径都会被导入。
有没有办法停止导入这些路径,因为其中一些路径与我需要运行的程序不兼容。即当我处于 C-shell 环境中时,我希望能够在 .cshrc 文件中定义我需要的所有内容,以便我可以控制它。不过,我不想永久更改我的登录 shell。
答案1
环境变量始终从父进程继承[†],因此需要.cshrc
手动设置或删除任何不需要的环境变量
setenv PATH /bin:/other/dirs/here:/and/more
unsetenv PS1
请注意,这些是互斥操作(遗憾的是,英语“or”缺乏布尔特殊性)。setenv PATH
设置PATH
环境变量并unsetenv PS1
删除不需要的PS1
环境。unsetenv PATH
这样做setenv PATH ...
只会浪费 CPU 周期。相反,只需将其设置PATH
为您想要的即可。 (编辑PATH
是一项更加复杂的任务,需要拆分:
然后为每个目录元素应用代码等等......为什么要这么麻烦?设置PATH
为它需要的内容。)
或者,可以使用env -i csh
完全空白环境,在这种情况下,.cshrc
最好设置所有必要的内容(各种基本环境变量由login(1)
或等效的设置,诸如此类HOME
):
$ env perl -E 'say $ENV{SHELL}'
/opt/local/bin/mksh
$ env -i perl -E 'say $ENV{SHELL}'
$
[†] Bourne shell 通过将仅限 shell 的变量放置在与PS1
其余变量相同的名称空间中,然后使用一个布尔值(via export
)来标记那些通过 via 传递给extern char **environ
子进程的变量,从而使这一情况变得复杂;请参阅environ(7)
和execve(2)
手册页,了解有关发生的情况的更多详细信息,而无需 shell 的复杂化。
答案2
有没有办法停止导入这些路径
如果您正在编辑.cshrc
或.tcshrc
无论如何,您可能更愿意允许环境变量您不希望或您想要更改其值的对象被传递给tcsh
。然后取消设置它们或修改它们的值。就是这样thrig的出色回答解释了如何做。
然而,你能完全按照您的要求进行操作:tcsh
在没有您不需要的环境变量的情况下运行,或者为它们提供不同的值。
如果你正在tcsh
逃离伯恩风格的外壳喜欢bash
然后你可以VAR=val
在命令之前写对为该命令设置环境变量。例如:
PATH=/sbin:/bin:/usr/sbin:/usr/bin tcsh
这是不是与将赋值作为单独的命令发出相同(通过在其后面添加换行符或字符;
)。如果你这样做,它不会将变量导出到环境子流程就像tcsh
,即使在下一个命令运行完毕后,分配仍将保留。
您也可以通过这种方式设置多个环境变量:
BAR=barval PATH=/sbin:/bin:/usr/sbin:/usr/bin tcsh
请注意,对于在以下位置运行的后续命令,环境变量保持不变bash
:
ek@Io:~$ echo "$LANG"
en_US.UTF-8
ek@Io:~$ LANG=C tcsh -c 'echo "$LANG"'
C
ek@Io:~$ echo "$LANG"
en_US.UTF-8
您可以以相同的方式将空字符串分配给环境变量:
FOO= tcsh
但是,这与从环境中完全删除变量不同。为此,您可以使用env
带有选项的命令-u
:
env -u FOO tcsh
你也可以放环境变量env
:
env PATH=/sbin:/bin:/usr/sbin:/usr/bin tcsh
你通常不会需要不过,从 执行此操作bash
,因为bash
支持VAR=val
语法。
env
您可以使用单个命令设置多个环境变量,也可以取消设置变量。这就是说你做不是需要链接env
命令。例如,您可以使用:
env -u FOO BAR=barval PATH=/sbin:/bin:/usr/sbin:/usr/bin tcsh
实际的命令env
运行从第一个不包含符号的非选项参数开始=
。