我用的是tcsh。我希望根据我所在的目录或环境的其他关键方面更改提示格式(着色/突出显示)。
我还不是一个外壳黑客,不知道如何做到这一点。
当前目录的所有权
如果我位于“我的”目录之一(即我是当前工作目录的所有者),那么它应该具有正常的外观。但是,如果我在其他人的目录中(我为其他人的工作领域提供了大量支持cd
),那么我希望提示看起来明显不同。
这是提醒我不要在别人的目录中输入不礼貌的命令。 (认为make clobber
或p4 sync
等)
关键环境变量设置
我的环境的另一个重要信息是是否设置了某个环境变量,称之为 SWDEV。如果未设置 SWDEV,则我的脚本和流程来自其默认位置。但是,如果设置了此变量,那么它将被视为我的脚本和流程的新根位置,行为会根据该位置的脚本而变化。
重要的是要提醒这个变量的设置,以免我期望“正常”行为,但却心不在焉地从新位置运行代码。
答案1
好吧,如果外部脚本是可接受的解决方案,您可以执行以下操作:
#!/usr/bin/env perl
use Cwd;
my $cwd=getcwd();
$cwd =~ /$ENV{HOME}/ ?
print "$cwd % " :
print "%{\033[1;31m%}CAREFUL\\\!%{\033[0m%} $cwd % ";
将其保存在您的$PATH
as中的某个位置make_prompt.pl
并使其可执行。然后,在你的~/.tcshrc
:
alias precmd 'set prompt="`make_prompt.pl`"'
这将导致:
您还可以添加更多条件以在不同目录中以特定方式更改提示:
#!/usr/bin/env perl
use Cwd;
my $cwd=getcwd();
## Here are some colors to choose from
my $red="%{\033[1;31m%}";
my $green="%{\033[0;32m%}";
my $yellow="%{\033[1;33m%}";
my $blue="%{\033[1;34m%}";
my $magenta="%{\033[1;35m%}";
my $cyan="%{\033[1;36m%}";
my $white="%{\033[0;37m%}";
## This resets the color, you need it after each color command
my $end="%{\033[0m%}";
## If you are in $HOME or one of its sub dirs, print a green prompt
if($cwd =~ /$ENV{HOME}/){
print "$green$cwd$end % ";
}
## If you are in /usr or one of its sub dirs, print a red prompt
elsif($cwd=~ /\/usr/){
print "$red$cwd$end % ";
}
## If you are in /etc or one of its sub dirs, print a blue prompt
elsif($cwd=~/\/etc/){
print "$blue$cwd$end % ";
}
## If you're in /root. As you can see, colors can be combined
elsif($cwd=~/\/root/){
print $red . "OY\\! You're not allowed in here\\!" .
$end . $magenta . " $cwd$end % ";
}
## For wherever else, just print a plain prompt
else {
print "$cwd % ";
}
答案2
我不知道如何在 shell (tcsh) 中本地执行此操作,但我确实使用 Perl 脚本解决了该问题。
使用 Perl 脚本,您可以拥有复杂的逻辑,例如检查您是否拥有 $cwd、设置了哪些环境变量等。然后,让脚本打印您想要的提示字符串。
tcsh 有一个特殊的precmd
别名,每次在打印提示之前都会执行该别名。因此,有一个 Perl 脚本“formatPrompt.pl”
#!/home/utils/perl-5.8.8/bin/perl
use strict;
use warnings;
use Cwd;
# "SWDEV" is an env var special to our environment. Want to be reminded in the prompt of its setting.
use Env qw(SWDEV prompt);
my $prompt = '%U{%m}%~%u> ';
my $prefix = '';
if (defined $SWDEV) {
# set a prompt prefix if special env var is set. use "Boldface" highlighting.
$prefix = "%Bspecial env var SWDEV=$SWDEV%b\\n";
}
if (! -o getcwd) {
# change the highlighting of the prompt if not your dir.
$prompt = '%U{%m}-->%~<--%u> ';
}
$prompt = $prefix . $prompt;
print $prompt;
exit 0;
和一个定义这样的别名
% alias precmd
set prompt="`perl /home/source/perl/formatPrompt.pl`"
可以生产
{o-xterm-62}~> setenv SWDEV "/some/special/env/var/value"
special env var SWDEV=/some/special/env/var/value
{o-xterm-62}~> cd /usr
special env var SWDEV=/some/special/env/var/value
{o-xterm-62}-->/usr<--> unsetenv SWDEV
{o-xterm-62}-->/usr<--> cd ~
{o-xterm-62}~>
(请注意,如果设置了 SWDEV,则打印其值,并且如果该目录不属于用户,则 cwd 会被 -->cwd<-- 包围。尝试其他提示突出显示,例如 %S%~%s,还。)
答案3
为了好玩,我根据我在这里看到的其他人所做的事情,使用简单的if
语句提供了另一个原型;make_prompt
:
#!/bin/tcsh
set red="%{\033[1;31m%}"
set green="%{\033[1;32m%}"
set yellow="%{\033[1;33m%}"
set blue="%{\033[1;34m%}"
set magenta="%{\033[1;35m%}"
set cyan="%{\033[1;36m%}"
set white="%{\033[0;37m%}"
set end="%{\033[0m%}"
if ("$dirstack[1]" == "/") then
echo " ${blue}r${magenta}o${cyan}o${green}t${end} "
else if ("$dirstack[1]" =~ "/home/thisguy*") then
echo " ${yellow}Watch this guy out\\!${end} "
else if ("$dirstack[1]" =~ "/hom*") then
echo " ${red}Be mindful of the home dir\\!${end} "
else if ("$dirstack[1]" =~ "/usr*") then
echo " ${magenta}You're in /usr now\\!${end} "
else if ("$dirstack[1]" =~ "/etc*") then
echo " ${green}-=etc=-${end} "
endif
使用进入的位.tcshrc
,选择使用rprompt
而不是prompt
自动将信息对齐到右侧:
alias precmd 'set rprompt="`if "$?" == 0 echo "\(ok\)"``if "$?" == 1 echo "\(err\)"``if ("$?" != 0 && "$?" != 1) echo "\($?\)"``make_prompt`"'
还添加了一个简单的指示退出状态最后一个命令的值(ok = 0,err = 1,$?
其他)。
/home/thisguy
限制是,在脚本中为其他目录中的对象(即与此处的对象)制作自定义消息时,需要特定的顺序(从特定到一般)/home
。