或者更一般地说,如何从Bash环境变量中以冒号分隔的列表中删除项目?
我以为我在几年前看到了一种简单的方法,使用更高级的Bash变量扩展形式,但如果是这样的话,我已经忘记了它。对谷歌的快速搜索出乎意料地少了几个相关结果,没有一个我称之为“简单”或“优雅”。例如,两个方法分别使用sed和awk:
PATH=$(echo $PATH | sed -e 's;:\?/home/user/bin;;' -e 's;/home/user/bin:\?;;')
PATH=!(awk -F: '{for(i=1;i<=NF;i++){if(!($i in a)){a[$i];printf s$i;s=":"}}}'<<<$PATH)
没有直接存在吗?有什么类似于Bash中的split()函数吗?
更新
看起来我需要为我的故意模糊的问题道歉;我对解决特定用例的兴趣不如激发良好的讨论。幸运的是,我明白了!
这里有一些非常聪明的技巧。最后,我在工具箱中添加了以下三个功能。魔法发生在path_remove中,主要基于Martin York巧妙使用awk
的RS变量。
path_append () { path_remove $1; export PATH="$PATH:$1"; }
path_prepend () { path_remove $1; export PATH="$1:$PATH"; }
path_remove () { export PATH=`echo -n $PATH | awk -v RS=: -v ORS=: '$0 != "'$1'"' | sed 's/:$//'`; }
唯一真正的缺点是使用sed
来移除尾随结肠。考虑到马丁解决方案的其余部分是多么简单,我非常愿意接受它!
答案 0 :(得分:52)
我的肮脏黑客:
echo ${PATH} > t1
vi t1
export PATH=$(cat t1)
答案 1 :(得分:41)
与awk一分钟:
# Strip all paths with SDE in them.
#
export PATH=`echo ${PATH} | awk -v RS=: -v ORS=: '/SDE/ {next} {print}'`
$ export a="/a/b/c/d/e:/a/b/c/d/g/k/i:/a/b/c/d/f:/a/b/c/g:/a/b/c/d/g/i"
$ echo ${a}
/a/b/c/d/e:/a/b/c/d/f:/a/b/c/g:/a/b/c/d/g/i
## Remove multiple (any directory with a: all of them)
$ echo ${a} | awk -v RS=: -v ORS=: '/a/ {next} {print}'
## Works fine all removed
## Remove multiple including last two: (any directory with g)
$ echo ${a} | awk -v RS=: -v ORS=: '/g/ {next} {print}'
/a/b/c/d/e:/a/b/c/d/f:
## Works fine: Again!
export PATH=$(echo ${PATH} | awk -v RS=: -v ORS=: '/SDE/ {next} {print}' | sed 's/:*$//')
这会删除通过删除最后一个条目而留下的所有尾随冒号,这会有效地将.
添加到您的路径中。
答案 2 :(得分:40)
由于替换的大问题是最终案例,如何使最终案例与其他案件没有什么不同?如果路径在开始和结束时已经有冒号,我们可以简单地搜索用冒号包裹的所需字符串。事实上,我们可以轻松添加这些冒号并在之后删除它们。
# PATH => /bin:/opt/a dir/bin:/sbin
WORK=:$PATH:
# WORK => :/bin:/opt/a dir/bin:/sbin:
REMOVE='/opt/a dir/bin'
WORK=${WORK/:$REMOVE:/:}
# WORK => :/bin:/sbin:
WORK=${WORK%:}
WORK=${WORK#:}
PATH=$WORK
# PATH => /bin:/sbin
Pure bash:)。
答案 3 :(得分:26)
这是我可以设计的最简单的解决方案:
#!/bin/bash
IFS=:
# convert it to an array
t=($PATH)
unset IFS
# perform any array operations to remove elements from the array
t=(${t[@]%%*usr*})
IFS=:
# output the new array
echo "${t[*]}"
上面的示例将删除$ PATH中包含“usr”的任何元素。您可以将“* usr *”替换为“/ home / user / bin”以仅删除该元素。
每sschuberth更新
尽管我认为$PATH
中的空格是可怕的主意,但这是一个处理它的解决方案:
PATH=$(IFS=':';t=($PATH);n=${#t[*]};a=();for ((i=0;i<n;i++)); do p="${t[i]%%*usr*}"; [ "${p}" ] && a[i]="${p}"; done;echo "${a[*]}");
或
IFS=':'
t=($PATH)
n=${#t[*]}
a=()
for ((i=0;i<n;i++)); do
p="${t[i]%%*usr*}"
[ "${p}" ] && a[i]="${p}"
done
echo "${a[*]}"
答案 4 :(得分:11)
这是一个单线程,尽管有当前的accepted和highest rated答案,但它不会向PATH添加不可见的字符,并且可以处理包含空格的路径:
export PATH=$(p=$(echo $PATH | tr ":" "\n" | grep -v "/cygwin/" | tr "\n" ":"); echo ${p%:})
就个人而言,我也觉得这很容易阅读/理解,它只涉及常见命令而不是使用awk。
答案 5 :(得分:8)
以下是一个解决方案:
IFS
,删除PATH
中所有出现的参数。
removeFromPath() { local p d p=":$1:" d=":$PATH:" d=${d//$p/:} d=${d/#:/} PATH=${d/%:/} }
答案 6 :(得分:6)
function __path_remove(){
本地D =“:$ {PATH}:”;
[“$ {D /:$ 1:/:}”!=“$ D”]&amp;&amp; PATH = “$ {d /:$ 1:/:}”;
PATH = “$ {PATH /#:/}”;
export PATH =“$ {PATH /%:/}”;
}
从我的.bashrc文件中挖出来。 当您使用PATH时,它会丢失,awk / sed / grep变得不可用: - )
答案 7 :(得分:6)
到目前为止,我发现的最佳纯bash选项如下:
function path_remove {
PATH=${PATH/":$1"/} # delete any instances in the middle or at the end
PATH=${PATH/"$1:"/} # delete any instances at the beginning
}
这是基于超级用户的not quite correct answer到Add directory to $PATH if it's not already there结束。
答案 8 :(得分:5)
我刚刚使用bash发行版中的函数,这些函数自1991年以来一直存在。这些函数仍然在Fedora上的bash-docs包中,过去常用于/etc/profile
,但没有更...
$ rpm -ql bash-doc |grep pathfunc
/usr/share/doc/bash-4.2.20/examples/functions/pathfuncs
$ cat $(!!)
cat $(rpm -ql bash-doc |grep pathfunc)
#From: "Simon J. Gerraty" <sjg@zen.void.oz.au>
#Message-Id: <199510091130.VAA01188@zen.void.oz.au>
#Subject: Re: a shell idea?
#Date: Mon, 09 Oct 1995 21:30:20 +1000
# NAME:
# add_path.sh - add dir to path
#
# DESCRIPTION:
# These functions originated in /etc/profile and ksh.kshrc, but
# are more useful in a separate file.
#
# SEE ALSO:
# /etc/profile
#
# AUTHOR:
# Simon J. Gerraty <sjg@zen.void.oz.au>
# @(#)Copyright (c) 1991 Simon J. Gerraty
#
# This file is provided in the hope that it will
# be of use. There is absolutely NO WARRANTY.
# Permission to copy, redistribute or otherwise
# use this file is hereby granted provided that
# the above copyright notice and this notice are
# left intact.
# is $1 missing from $2 (or PATH) ?
no_path() {
eval "case :\$${2-PATH}: in *:$1:*) return 1;; *) return 0;; esac"
}
# if $1 exists and is not in path, append it
add_path () {
[ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="\$${2:-PATH}:$1"
}
# if $1 exists and is not in path, prepend it
pre_path () {
[ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="$1:\$${2:-PATH}"
}
# if $1 is in path, remove it
del_path () {
no_path $* || eval ${2:-PATH}=`eval echo :'$'${2:-PATH}: |
sed -e "s;:$1:;:;g" -e "s;^:;;" -e "s;:\$;;"`
}
答案 9 :(得分:4)
我确实写了这个here的答案(也使用了awk)。但我不确定那是你在寻找什么?它至少让我看清楚它的作用,而不是试图融入一条线。但是,对于一个简单的衬垫,只能去除东西,我建议
echo $PATH | tr ':' '\n' | awk '$0 != "/bin"' | paste -sd:
更换
echo $PATH | tr ':' '\n' |
awk '$0 != "/bin"; $0 == "/bin" { print "/bar" }' | paste -sd:
或(更短但可读性更低)
echo $PATH | tr ':' '\n' | awk '$0 == "/bin" { print "/bar"; next } 1' | paste -sd:
无论如何,对于同一个问题以及许多有用的答案,请参阅here。
答案 10 :(得分:3)
好吧,在bash中,因为它支持正则表达式,我只会这样做:
PATH=${PATH/:\/home\/user\/bin/}
答案 11 :(得分:1)
从Bash中的$ PATH变量中删除路径的最优雅方法是什么?
什么比awk更优雅?
path_remove () { export PATH=`echo -n $PATH | awk -v RS=: -v ORS=: '$0 != "'$1'"' | sed 's/:$//'`;
的Python!它是一个更具可读性和可维护性的解决方案,并且很容易检查它是否真正做到了你想要的。
您是否要删除第一个路径元素?
PATH="$(echo "$PATH" | python -c "import sys; path = sys.stdin.read().split(':'); del path[0]; print(':'.join(path))")"
(而不是来自echo
的管道,os.getenv['PATH']
会更短,并提供与上面相同的结果,但我担心Python可能会对该环境变量做些什么,所以最好直接从你关心的环境中进行管道处理。)
与从末尾删除类似:
PATH="$(echo "$PATH" | python -c "import sys; path = sys.stdin.read().split(':'); del path[-1]; print(':'.join(path))")"
要制作这些可重复使用的shell函数,例如,可以粘贴在.bashrc文件中:
strip_path_first () {
PATH="$(echo "$PATH" |
python -c "import sys; path = sys.stdin.read().split(':'); del path[0]; print(':'.join(path))")"
}
strip_path_last () {
PATH="$(echo "$PATH" |
python -c "import sys; path = sys.stdin.read().split(':'); del path[-1]; print(':'.join(path))")"
}
答案 12 :(得分:1)
我喜欢@BenBlank对原始问题的更新中显示的三个功能。为了概括它们,我使用了一个2参数形式,它允许我设置PATH或我想要的任何其他环境变量:
path_append () { path_remove $1 $2; export $1="${!1}:$2"; }
path_prepend () { path_remove $1 $2; export $1="$2:${!1}"; }
path_remove () { export $1="`echo -n ${!1} | awk -v RS=: -v ORS=: '$1 != "'$2'"' | sed 's/:$//'`"; }
使用示例:
path_prepend PATH /usr/local/bin
path_append PERL5LIB "$DEVELOPMENT_HOME/p5/src/perlmods"
请注意,我还添加了一些引号,以便正确处理包含空格的路径名。
答案 13 :(得分:1)
Scratch的Linux在/etc/profile
中定义了三个Bash函数:
# Functions to help us manage paths. Second argument is the name of the
# path variable to be modified (default: PATH)
pathremove () {
local IFS=':'
local NEWPATH
local DIR
local PATHVARIABLE=${2:-PATH}
for DIR in ${!PATHVARIABLE} ; do
if [ "$DIR" != "$1" ] ; then
NEWPATH=${NEWPATH:+$NEWPATH:}$DIR
fi
done
export $PATHVARIABLE="$NEWPATH"
}
pathprepend () {
pathremove $1 $2
local PATHVARIABLE=${2:-PATH}
export $PATHVARIABLE="$1${!PATHVARIABLE:+:${!PATHVARIABLE}}"
}
pathappend () {
pathremove $1 $2
local PATHVARIABLE=${2:-PATH}
export $PATHVARIABLE="${!PATHVARIABLE:+${!PATHVARIABLE}:}$1"
}
export -f pathremove pathprepend pathappend
参考:http://www.linuxfromscratch.org/blfs/view/svn/postlfs/profile.html
答案 14 :(得分:1)
是的,例如,在PATH的末尾添加一个冒号会使删除路径不那么笨拙&amp;容易出错。
path_remove () {
declare i newPATH
newPATH="${PATH}:"
for ((i=1; i<=${#@}; i++ )); do
#echo ${@:${i}:1}
newPATH="${newPATH//${@:${i}:1}:/}"
done
export PATH="${newPATH%:}"
return 0;
}
path_remove_all () {
declare i newPATH
shopt -s extglob
newPATH="${PATH}:"
for ((i=1; i<=${#@}; i++ )); do
newPATH="${newPATH//+(${@:${i}:1})*([^:]):/}"
#newPATH="${newPATH//+(${@:${i}:1})*([^:])+(:)/}"
done
shopt -u extglob
export PATH="${newPATH%:}"
return 0
}
path_remove /opt/local/bin /usr/local/bin
path_remove_all /opt/local /usr/local
答案 15 :(得分:1)
大多数其他建议的解决方案仅依赖于字符串匹配,并且不考虑包含.
,..
或~
等特殊名称的路径段。下面的bash函数解析其参数和路径段中的目录字符串,以查找逻辑目录匹配以及字符串匹配。
rm_from_path() {
pattern="${1}"
dir=''
[ -d "${pattern}" ] && dir="$(cd ${pattern} && pwd)" # resolve to absolute path
new_path=''
IFS0=${IFS}
IFS=':'
for segment in ${PATH}; do
if [[ ${segment} == ${pattern} ]]; then # string match
continue
elif [[ -n ${dir} && -d ${segment} ]]; then
segment="$(cd ${segment} && pwd)" # resolve to absolute path
if [[ ${segment} == ${dir} ]]; then # logical directory match
continue
fi
fi
new_path="${new_path}${IFS}${segment}"
done
new_path="${new_path/#${IFS}/}" # remove leading colon, if any
IFS=${IFS0}
export PATH=${new_path}
}
测试:
$ mkdir -p ~/foo/bar/baz ~/foo/bar/bif ~/foo/boo/bang
$ PATH0=${PATH}
$ PATH=~/foo/bar/baz/.././../boo/././../bar:${PATH} # add dir with special names
$ rm_from_path ~/foo/boo/../bar/. # remove same dir with different special names
$ [ ${PATH} == ${PATH0} ] && echo 'PASS' || echo 'FAIL'
答案 16 :(得分:1)
如果您担心在$ PATH中删除重复项,那么最优雅的方式是恕我直言,首先不会添加它们。一行:
if ! $( echo "$PATH" | tr ":" "\n" | grep -qx "$folder" ) ; then PATH=$PATH:$folder ; fi
$ folder可以被任何东西替换,并且可以包含空格(“/ home / user / my documents”)
答案 17 :(得分:1)
迄今为止我发现的最优雅的纯粹bash解决方案:
pathrm () {
local IFS=':'
local newpath
local dir
local pathvar=${2:-PATH}
for dir in ${!pathvar} ; do
if [ "$dir" != "$1" ] ; then
newpath=${newpath:+$newpath:}$dir
fi
done
export $pathvar="$newpath"
}
pathprepend () {
pathrm $1 $2
local pathvar=${2:-PATH}
export $pathvar="$1${!pathvar:+:${!pathvar}}"
}
pathappend () {
pathrm $1 $2
local pathvar=${2:-PATH}
export $pathvar="${!pathvar:+${!pathvar}:}$1"
}
答案 18 :(得分:0)
让我们从PATH中“删除”对/ path / to / something的引用:
重击:
PATH=${PATH/something/nope/}
Windows批处理的奖励答案:
set PATH=%PATH:something=nope%
有人有更简单的解决方案吗? :)
答案 19 :(得分:0)
我知道这个问题是关于BASH的,每个人都应该更喜欢,但是因为我喜欢对称,有时候我需要使用“csh”,我构建了相当于“path_prepend()”,“path_append()”和“path_remove()”上面的优雅解决方案。
要点是“csh”没有函数,所以我在我的个人bin目录中放了一些shell脚本,就像函数一样。我创建别名来SOURCE这些脚本,以使指定的环境变量发生变化。
〜/斌/ _path_remove.csh:
set _resolve = `eval echo $2`
setenv $1 `eval echo -n \$$1 | awk -v RS=: -v ORS=: '$1 != "'${_resolve}'"' | sed 's/:$//'`;
unset _resolve
〜/斌/ _path_append.csh:
source ~/bin/_path_remove.csh $1 $2
set _base = `eval echo \$$1`
set _resolve = `eval echo $2`
setenv $1 ${_base}:${_resolve}
unset _base _resolve
〜/斌/ _path_prepend.csh:
source ~/bin/_path_remove.csh $1 $2
set _base = `eval echo \$$1`
set _resolve = `eval echo $2`
setenv $1 ${_resolve}:${_base}
unset _base _resolve
〜/仓/ .cshrc中:
…
alias path_remove "source ~/bin/_path_remove.csh '\!:1' '\!:2'"
alias path_append "source ~/bin/_path_append.csh '\!:1' '\!:2'"
alias path_prepend "source ~/bin/_path_prepend.csh '\!:1' '\!:2'"
…
你可以像这样使用它们......
%(csh)> path_append MODULEPATH ${HOME}/modulefiles
答案 20 :(得分:0)
尾随&#39;:&#39;是由于您设置行结束而不是分隔符。我使用资源限制单位,并喜欢将所有内容打包到一个脚本中,没有这些奇怪之处:</ p>
path_remove () {
PATH="$(echo -n $PATH | awk -v RS=: -v ORS= '$0 != "'$1'"{print s _ $0;s=":"}')"
}
答案 21 :(得分:0)
这当然很优雅,但确实使用外部sed。
此外,它会删除包含搜索字符串$1
的所有路径。它也没有留下悬挂:最后,如果删除的路径是PATH的最后一条。
PATH=`echo $PATH | sed 's/:[^:]*$1[^:]*//g'`
这个替代方案确实留下了一个悬空的决赛:然而。
PATH=`echo $PATH | tr ":" "\n" | grep -v $1 | tr "\n" ":"`
PS:我不知道如何在代码中显示我的后退。 所以,替代方案是:
PATH=$(echo $PATH | sed 's/:[^:]*$1[^:]*//g')
PATH=$(echo $PATH | tr ":" "\n" | grep -v $1 | tr "\n" ":")
答案 22 :(得分:0)
这当然很优雅,但确实使用外部sed。 此外,它删除包含搜索字符串$ 1的所有路径。它也没有留下悬挂:如果移除的路径是路径上的最后一个路径,最后会发生悬空。
PATH=`echo $PATH | sed 's/:[^:]*$1[^:]*//g'`
这个替代方案确实留下了一个悬空的决赛:然而。
PATH=`echo $PATH | tr ":" "\n" | grep -v $1 | tr "\n" ":"`
没有反引号的替代方案是:
PATH=$(echo $PATH | sed 's/:[^:]*$1[^:]*//g')
PATH=$(echo $PATH | tr ":" "\n" | grep -v $1 | tr "\n" ":")
答案 23 :(得分:0)
我采用了与大多数人略有不同的方法,专注于字符串操作,如下所示:
path_remove () {
if [[ ":$PATH:" == *":$1:"* ]]; then
local dirs=":$PATH:"
dirs=${dirs/:$1:/:}
export PATH="$(__path_clean $dirs)"
fi
}
__path_clean () {
local dirs=${1%?}
echo ${dirs#?}
}
以上是我使用的最终功能的简化示例。我还创建了path_add_before
和path_add_after
,允许您在已经在PATH中的指定路径之前/之后插入路径。
我的path_helpers.sh dotfiles中提供了完整的功能集。它们完全支持在PATH字符串的开头/中间/结尾删除/附加/前置/插入。
答案 24 :(得分:0)
虽然这是一个非常古老的主题,但我认为这个解决方案可能很有意义:
PATH="/usr/lib/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
REMOVE="ccache" # whole or part of a path :)
export PATH=$(IFS=':';p=($PATH);unset IFS;p=(${p[@]%%$REMOVE});IFS=':';echo "${p[*]}";unset IFS)
echo $PATH # outputs /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
在blog post上找到了它。我想我最喜欢这个:)
答案 25 :(得分:0)
在path_remove_all(通过proxxy):
-newPATH="${newPATH//:+(${@:${i}:1})*([^:])/}"
+newPATH="${newPATH//:${@:${i}:1}*([^:])/}" # s/:\/path[^:]*//g
答案 26 :(得分:0)
向PATH添加冒号我们也可以执行以下操作:
path_remove () {
declare i newPATH
# put a colon at the beginning & end AND double each colon in-between
newPATH=":${PATH//:/::}:"
for ((i=1; i<=${#@}; i++)); do
#echo ${@:${i}:1}
newPATH="${newPATH//:${@:${i}:1}:/}" # s/:\/fullpath://g
done
newPATH="${newPATH//::/:}"
newPATH="${newPATH#:}" # remove leading colon
newPATH="${newPATH%:}" # remove trailing colon
unset PATH
PATH="${newPATH}"
export PATH
return 0
}
path_remove_all () {
declare i newPATH extglobVar
extglobVar=0
# enable extended globbing if necessary
[[ ! $(shopt -q extglob) ]] && { shopt -s extglob; extglobVar=1; }
newPATH=":${PATH}:"
for ((i=1; i<=${#@}; i++ )); do
newPATH="${newPATH//:+(${@:${i}:1})*([^:])/}" # s/:\/path[^:]*//g
done
newPATH="${newPATH#:}" # remove leading colon
newPATH="${newPATH%:}" # remove trailing colon
# disable extended globbing if it was enabled in this function
[[ $extglobVar -eq 1 ]] && shopt -u extglob
unset PATH
PATH="${newPATH}"
export PATH
return 0
}
path_remove /opt/local/bin /usr/local/bin
path_remove_all /opt/local /usr/local
答案 27 :(得分:0)
扩展的globbing one-liner(好吧,有点):
path_remove () { shopt -s extglob; PATH="${PATH//+(${1})+([^:])?(:)/}"; export PATH="${PATH%:}"; shopt -u extglob; return 0; }
似乎没有必要在$ 1中转义斜杠。
path_remove () { shopt -s extglob; declare escArg="${1//\//\\/}"; PATH="${PATH//+(${escArg})+([^:])?(:)/}"; export PATH="${PATH%:}"; shopt -u extglob; return 0; }
答案 28 :(得分:0)
启用扩展通配符后,可以执行以下操作:
# delete all /opt/local paths in PATH
shopt -s extglob
printf "%s\n" "${PATH}" | tr ':' '\n' | nl
printf "%s\n" "${PATH//+(\/opt\/local\/)+([^:])?(:)/}" | tr ':' '\n' | nl
man bash | less -p extglob
答案 29 :(得分:0)
这里好东西。 我用这个来防止首先添加欺骗。
#!/bin/bash
#
######################################################################################
#
# Allows a list of additions to PATH with no dupes
#
# Patch code below into your $HOME/.bashrc file or where it
# will be seen at login.
#
# Can also be made executable and run as-is.
#
######################################################################################
# add2path=($HOME/bin .) ## uncomment space separated list
if [ $add2path ]; then ## skip if list empty or commented out
for nodup in ${add2path[*]}
do
case $PATH in ## case block thanks to MIKE511
$nodup:* | *:$nodup:* | *:$nodup ) ;; ## if found, do nothing
*) PATH=$PATH:$nodup ## else, add it to end of PATH or
esac ## *) PATH=$nodup:$PATH prepend to front
done
export PATH
fi
## debug add2path
echo
echo " PATH == $PATH"
echo
答案 30 :(得分:0)
这是一个Perl单行:
PATH=`perl -e '$a=shift;$_=$ENV{PATH};s#:$a(:)|^$a:|:$a$#$1#;print' /home/usr/bin`
$a
变量获取要删除的路径。 s
(替代)和print
命令隐含地对$_
变量进行操作。
答案 31 :(得分:0)
让这个问题烦人的是第一个和最后一个元素中的fencepost案例。通过更改IFS和使用数组可以很好地解决问题,但是一旦路径转换为数组形式,我不知道如何重新引入冒号。
这是一个稍微不那么优雅的版本,仅使用字符串操作从$PATH
中删除一个目录。我测试了它。
#!/bin/bash
#
# remove_from_path dirname
#
# removes $1 from user's $PATH
if [ $# -ne 1 ]; then
echo "Usage: $0 pathname" 1>&2; exit 1;
fi
delendum="$1"
NEWPATH=
xxx="$IFS"
IFS=":"
for i in $PATH ; do
IFS="$xxx"
case "$i" in
"$delendum") ;; # do nothing
*) [ -z "$NEWPATH" ] && NEWPATH="$i" || NEWPATH="$NEWPATH:$i" ;;
esac
done
PATH="$NEWPATH"
echo "$PATH"
答案 32 :(得分:0)
与@litb一样,我回答了问题“How do I manipulate $PATH elements in shell scripts”,所以我的主要答案就在那里。
bash
和其他Bourne shell衍生产品中的“拆分”功能通过域间分隔符$IFS
得到最清晰的实现。例如,要将位置参数($1
,$2
,...)设置为PATH的元素,请使用:
set -- $(IFS=":"; echo "$PATH")
只要$ PATH中没有空格,它就能正常工作。使其适用于包含空格的路径元素是一项非常重要的练习 - 留给感兴趣的读者。使用像Perl这样的脚本语言来处理它可能更简单。
我还有一个脚本clnpath
,我广泛用它来设置我的PATH。我在“How to keep from duplicating PATH variable in csh”的答案中记录了它。
答案 33 :(得分:0)
由于这往往很成问题,因为没有优雅的方式,我建议通过重新安排解决方案来避免这个问题:建立你的PATH而不是试图把它拆掉。
如果我知道你真正的问题背景,我会更具体。在此期间,我将使用软件构建作为上下文。
软件构建的一个常见问题是它在某些机器上中断,最终是由于某人如何配置其默认shell(PATH和其他环境变量)。优雅的解决方案是通过完全指定shell环境使您的构建脚本免疫。对构建脚本进行编码,以根据您控制的组件来设置PATH和其他环境变量,例如编译器的位置,库,工具,组件等。使每个可配置项都可以单独设置,验证和然后在你的剧本中适当使用。
例如,我有一个基于Maven的WebLogic目标Java构建,我在新雇主那里继承了它。构建脚本因脆弱而臭名昭着,而另一位新员工和我花了三个星期(不是全职,只是在这里和那里,但仍然需要很长时间)让它在我们的机器上工作。一个重要的步骤是我控制了PATH,以便我确切地知道哪个Java,哪个Maven以及哪个WebLogic被调用。我创建了环境变量来指向每个工具,然后我根据这些工具加上其他几个来计算PATH。类似的技术驯服了其他可配置的设置,直到我们最终创建了一个可重现的构建。
顺便说一下,不要使用Maven,Java是可以的,只有在你绝对需要它的集群时才购买WebLogic(但是否则没有,尤其不是它的专有功能)。
祝福。