如何避免在csh中复制路径变量

时间:2020-03-06 14:44:47  来源:igfitidea点击:

通常,在cshrc文件中包含以下内容以设置路径:

set path = ( . $otherpath $path )

但是,当我们多次获取cshrc文件时,路径会重复,那么如何防止重复?

编辑:这是一种不干净的方法:

set localpaths = ( . $otherpaths )
echo ${path} | egrep -i "$localpaths" >& /dev/null
if ($status != 0) then
    set path = ( . $otherpaths $path )
endif

解决方案

我总是在.cshrc中设置从头开始的路径。
那是我从一条基本路径开始的,就像:

set path = (. ~/bin /bin /usr/bin /usr/ucb /usr/bin/X11)

(取决于系统)。

然后执行:

set path = ($otherPath $path)

添加更多的东西

我们可以使用以下Perl脚本来修剪重复项的路径。

#!/usr/bin/perl
#
# ^^ ensure this is pointing to the correct location.
#
# Title:    SLimPath
# Author:   David "Shoe Lace" Pyke <[email protected] >
#   :   Tim Nelson 
# Purpose: To create a slim version of my envirnoment path so as to eliminate
#       duplicate entries and ensure that the "." path was last.
# Date Created: April 1st 1999
# Revision History:
#   01/04/99: initial tests.. didn't wok verywell at all
#       : retreived path throught '$ENV' call
#   07/04/99: After an email from Tim Nelson <[email protected]> got it to
#         work.
#       : used 'push' to add to array
#       : used 'join' to create a delimited string from a list/array.
#   16/02/00: fixed cmd-line options to look/work better
#   25/02/00: made verbosity level-oriented
#
#

use Getopt::Std;

sub printlevel;

$initial_str = "";
$debug_mode = "";
$delim_chr = ":";
$opt_v = 1;

getopts("v:hd:l:e:s:");

OPTS: {
    $opt_h && do {
print "\n
case $PATH in
    *:$HOME/bin | *:$HOME/bin:* ) ;;
    *) export PATH=$PATH:$HOME/bin
esac
[-v level] [-d level] [-l delim] ( -e varname | -s strname | -h )"; print "\nWhere:"; print "\n -h This help"; print "\n -d Debug level"; print "\n -l Delimiter (between path vars)"; print "\n -e Specify environment variable (NB: don't include $ sign)"; print "\n -s String (ie.
:   "@(#)$Id: clnpath.sh,v 1.6 1999/06/08 23:34:07 jleffler Exp $"
#
#   Print minimal version of $PATH, possibly removing some items

case $# in
0)  chop=""; path=${PATH:?};;
1)  chop=""; path=;;
2)  chop=; path=;;
*)  echo "Usage: `basename 
export PATH=$(clnpath /new/bin:/other/bin:$PATH /old/bin:/extra/bin)
.sh` [$PATH [remove:list]]" >&2 exit 1;; esac # Beware of the quotes in the assignment to chop! echo "$path" | ${AWK:-awk} -F: '# BEGIN { # Sort out which path components to omit chop="'"$chop"'"; if (chop != "") nr = split(chop, remove); else nr = 0; for (i = 1; i <= nr; i++) omit[remove[i]] = 1; } { for (i = 1; i <= NF; i++) { x=$i; if (x == "") x = "."; if (omit[x] == 0 && path[x]++ == 0) { output = output pad x; pad = ":"; } } print output; }'
-s $PATH:/looser/bin/)"; print "\n -v Verbosity (0 = quiet, 1 = normal, 2 = verbose)"; print "\n"; exit; }; $opt_d && do { printlevel 1, "You selected debug level $opt_d\n"; $debug_mode = $opt_d; }; $opt_l && do { printlevel 1, "You are going to delimit the string with \"$opt_l\"\n"; $delim_chr = $opt_l; }; $opt_e && do { if($opt_s) { die "Cannot specify BOTH env var and string\n"; } printlevel 1, "Using Environment variable \"$opt_e\"\n"; $initial_str = $ENV{$opt_e}; }; $opt_s && do { printlevel 1, "Using String \"$opt_s\"\n"; $initial_str = $opt_s; }; } if( ($#ARGV != 1) and !$opt_e and !$opt_s){ die "Nothing to work with -- try
set path=(`echo $path | tr ' ' '\n' | sort | uniq | tr '\n' ' '`)
-h\n"; } $what = shift @ARGV; # Split path using the delimiter @dirs = split(/$delim_chr/, $initial_str); $dest; @newpath = (); LOOP: foreach (@dirs){ # Ensure the directory exists and is a directory if(! -e ) { printlevel 1, "$_ does not exist\n"; next; } # If the directory is ., set $dot and go around again if($_ eq '.') { $dot = 1; next; } # if ($_ ne `realpath $_`){ # printlevel 2, "$_ becomes ".`realpath $_`."\n"; # } undef $dest; #$_=Stdlib::realpath($_,$dest); # Check for duplicates and dot path foreach $adir (@newpath) { if($_ eq $adir) { printlevel 2, "Duplicate: $_\n"; next LOOP; }} push @newpath, $_; } # Join creates a string from a list/array delimited by the first expression print join($delim_chr, @newpath) . ($dot ? $delim_chr.".\n" : "\n"); printlevel 1, "Thank you for using
foreach dir ( $localdirs )
    echo ${path} | egrep -i "$dir" >& /dev/null
    if ($status != 0) then
        set path = ( $dir $path )
    endif
end
\n"; exit; sub printlevel { my($level, $string) = @_; if($opt_v >= $level) { print STDERR $string; } }

我希望那是有用的。

好的,不是在csh中,但这是我将$ HOME / bin添加到bash中的路径中的方法...

##代码##

品尝的季节...

十年来,我一直在使用以下(Bourne / Korn / POSIX / Bash)脚本:

##代码##

在Korn Shell中,我使用:

##代码##

这给我留下了PATH,它在最前面包含新的bin目录和其他bin目录,以及在主路径值中每个目录名称的一个副本,除了旧的bin目录和多余的bin目录都已删除bin。

我们必须对此进行调整以适应C Shell(对不起,但我坚信C Shell编程被认为有害)中阐明的真理。首先,我们不必摆弄冒号分隔符,因此生活实际上更轻松。

好吧,如果我们不在乎路径的顺序,则可以执行以下操作:

##代码##

这将对路径进行排序,并删除所有相同的其他路径。如果你有 。在路径中,我们可能需要使用grep -v删除它,并在最后将其重新添加。

这是一个长而未排序的单线:
设置路径=(echo $ path | tr''\ n'| perl -e'while(&lt;>){打印$ _除非$ s {$ _} ++;}'| tr'\ n''')

dr_peper,

我通常更喜欢坚持使用我所居住的shell的脚本功能。使其更具可移植性。因此,我喜欢使用csh脚本的解决方案。我只是将其扩展为在localdirs中的每个目录上工作,以使其自己工作。

##代码##