または、より一般的には、Bash環境変数でコロンで区切られたリストから項目を削除するにはどうすればよいですか?
私はこの数年前に、より高度な形式のBash変数展開を使用して簡単な方法を見たことがあると思っていましたが、もしそうなら、それを追跡できませんでした。 Googleのクイック検索では、驚くほど関連する結果はほとんど見つかりませんでしたが、「シンプル」または「エレガント」と呼ぶものは見つかりませんでした。たとえば、それぞれsedとawkを使用する2つのメソッド:
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()関数に類似したものはありますか?
更新:
意図的に曖昧な質問に対して謝罪する必要があるようです。良い議論をするよりも、特定のユースケースを解決することに興味がなかった。幸いなことに、私はそれを得た!
ここには非常に巧妙なテクニックがいくつかあります。最後に、次の3つの関数をツールボックスに追加しました。魔法は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
を使用して末尾のコロンを削除することです。とはいえ、Martinの残りのソリューションがいかに簡単かを考えると、私はそれを受け入れて喜んでいます!
Awkで1分:
# 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/:*$//')
これは、最後のエントリを削除することで残っているコロンを削除します。これにより、.
パスへ。
私の汚いハック:
echo ${PATH} > t1
vi t1
export PATH=$(cat t1)
代替の大きな問題はエンドケースであるため、エンドケースを他のケースと変わらないようにするのはどうですか?パスの最初と最後に既にコロンが含まれている場合は、コロンでラップされた目的の文字列を単純に検索できます。そのままで、これらのコロンを簡単に追加し、後で削除できます。
# 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
純粋なbash :)。
ここに私が考案できる最も簡単な解決策があります:
#!/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[*]}"
上記の例は、「usr」を含む$ PATHの要素を削除します。 「* usr *」を「/ home/user/bin」に置き換えて、その要素だけを削除できます。
updateper sschuberth
$PATH
はhorribleのアイデアです。これを処理するソリューションを次に示します。
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[*]}"
現在の accepted および highestrated の回答にもかかわらず、見えない文字をPATHに追加せず、スペースを含むパスに対処できるワンライナーを次に示します。
export PATH=$(p=$(echo $PATH | tr ":" "\n" | grep -v "/cygwin/" | tr "\n" ":"); echo ${p%:})
個人的にも、これは読みやすく、理解しやすいと思います。これには、awkを使用する代わりに一般的なコマンドのみが含まれます。
以下がその解決策です。
IFS
は変更されません。PATH
内の引数のすべての出現を削除します。
removeFromPath(){ local pd p = ":$ 1:" d = ":$ PATH:" d = $ { d // $ p /:} d = $ {d /#:/} PATH = $ {d /%:/} }
これまでに見つけた最高の純粋な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
}
これは まったく正解ではない to まだ存在しない場合は$ PATHにディレクトリを追加する に基づいています。
関数__path_remove(){
local D = ":$ {PATH}:";
["$ {D /:$ 1:/:}"!= "$ D"] && PATH = "$ {D /:$ 1:/:}";
PATH = "$ {PATH /#:/}";
export PATH = "$ {PATH /%:/}";
}
.bashrcファイルからそれを掘り出しました。 PATHをいじってみると、それが失われると、awk/sed/grepは利用できなくなります:-)
1991年以降明らかにbashディストリビューションの関数を使用しているところです。これらは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" <[email protected]>
#Message-Id: <[email protected]>
#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 <[email protected]>
# @(#)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;:\$;;"`
}
私はこれに対する答えを書きました here (awkも使用)。しかし、私はそれがあなたが探しているものだかわかりませんか?少なくとも、1行に収めようとするのではなく、それが何をするのかが明確に見えます。ただ、物を取り除くだけのシンプルなライナーの場合、私はお勧めします
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 を参照してください。
まあ、bashでは、正規表現をサポートしているので、私は単にそうします:
PATH=${PATH/:\/home\/user\/bin/}
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))")"
これらの再利用可能なシェル関数を作成するには、たとえば、.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))")"
}
Linux from Scratchは、/etc/profile
で3つの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
@BenBlankの元の質問に対する更新で示されている3つの関数が気に入っています。それらを一般化するには、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"
また、スペースを含むパス名を適切に処理できるように引用符も追加していることに注意してください。
はい。たとえば、PATHの末尾にコロンを入れると、パスの削除が少し不格好になり、エラーが発生しやすくなります。
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
$ PATHのduplicatesを削除することを懸念している場合、最もエレガントな方法であるIMHOは、そもそもそれらを追加しないことです。 1行で:
if ! $( echo "$PATH" | tr ":" "\n" | grep -qx "$folder" ) ; then PATH=$PATH:$folder ; fi
$ folderは任意のものに置き換えることができ、スペースを含めることができます( "/ home/user/my documents")
これまでに見つけた最もエレガントな純粋な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"
}
他の提案されたソリューションのほとんどは、文字列の一致のみに依存しており、.
、..
、または~
などの特別な名前を含むパスセグメントを考慮しません。以下の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'
Perlのワンライナーは次のとおりです。
PATH=`Perl -e '$a=shift;$_=$ENV{PATH};s#:$a(:)|^$a:|:$a$#$1#;print' /home/usr/bin`
$a
変数は、削除するパスを取得します。 s
(代替)およびprint
コマンドは、$_
変数。
この質問は誰もが好むBASHについて質問することは知っていますが、対称性を楽しんでおり、時々「csh」を使用する必要があるため、「path_prepend()」、「path_append()」、「path_remove」に相当するものを構築しました() "上記のエレガントなソリューション。
要点は、「csh」には関数がないため、関数のように動作する小さなシェルスクリプトを個人のbinディレクトリに配置することです。これらのスクリプトをSOURCEにエイリアスを作成して、指定された環境変数を変更します。
〜/ bin/_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
〜/ bin/_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
〜/ bin/_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
〜/ bin/.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
末尾の「:」は、区切り文字ではなく行末を設定しているために発生します。私はリソースが制限されたユニットを使用し、これらの奇妙なことなく、すべてを単一のスクリプトに詰め込みます:
path_remove () {
PATH="$(echo -n $PATH | awk -v RS=: -v ORS= '$0 != "'$1'"{print s _ $0;s=":"}')"
}
@litbと同様に、「 シェルスクリプトで$ PATH要素を操作する方法 」という質問に対する回答を提供しました。したがって、私の主な回答はそこにあります。
bash
およびその他のBourne Shell派生物の「分割」機能は、$IFS
、フィールド間セパレータ。たとえば、位置引数($1
、$2
、...)PATHの要素に、次を使用します。
set -- $(IFS=":"; echo "$PATH")
$ PATHにスペースがなければ、問題なく動作します。スペースを含むパス要素に対して機能させることは簡単な作業であり、興味のある読者に任されています。 Perlなどのスクリプト言語を使用して対処する方がおそらく簡単です。
clnpath
というスクリプトもあります。これは、PATHの設定に広く使用しています。 「 cshでPATH変数が重複しないようにする方法 」に対する回答に文書化しました。
拡張グロビングを有効にすると、次のことが可能になります。
# 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
私はここでほとんどの人とは少し異なるアプローチを取り、特に文字列操作だけに焦点を当てました。
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 my dotfiles で利用できます。 PATH文字列の先頭/中央/末尾での削除/追加/先頭/挿入を完全にサポートしています。
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
これは非常に古いスレッドですが、このソリューションは興味深いものになると思いました。
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
これで見つけました ブログ投稿 。私はこれが一番好きだと思う:)
PATHから/ path/to/somethingへの参照を「削除」しましょう。
バッシュ:
PATH=${PATH/something/nope/}
Windows Batchのボーナス回答:
set PATH=%PATH:something=nope%
誰でも簡単な解決策がありますか? :)
これは確かにエレガントですが、外部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" ":")
Path_remove_allで(proxxyによって):
-newPATH="${newPATH//:+(${@:${i}:1})*([^:])/}"
+newPATH="${newPATH//:${@:${i}:1}*([^:])/}" # s/:\/path[^:]*//g
この問題をいらいらさせるのは、最初と最後の要素の間のフェンスポストのケースです。この問題は、IFSを変更して配列を使用することでエレガントに解決できますが、パスが配列形式に変換されたらコロンを再導入する方法がわかりません。
文字列操作のみを使用して$PATH
から1つのディレクトリを削除する、わずかにエレガントなバージョンを次に示します。私はそれをテストしました。
#!/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"
拡張グロビングワンライナー(まあ、並べ替え):
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; }
ここに良いもの。私はこれを使用して、そもそもデュープを追加しないようにします。
#!/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
これは確かにエレガントですが、外部sedを使用します。さらに、検索文字列$ 1を含むすべてのパスを削除します。また、削除されたパスがPATHの最後である場合、最後にぶら下がりを残しません。
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" ":")
IS NOエレガントな方法のように、これは非常に問題が多い傾向があるため、解決策を再配置することで問題を回避することをお勧めします。
あなたの本当の問題の文脈を知っていれば、私はもっと具体的になるかもしれません。その間、コンテキストとしてソフトウェアビルドを使用します。
ソフトウェアビルドの一般的な問題は、最終的に誰かがデフォルトのシェル(PATHおよび他の環境変数)を構成した方法が原因で、一部のマシンで破損することです。エレガントなソリューションは、シェル環境を完全に指定することにより、ビルドスクリプトを無効にすることです。ビルドスクリプトをコーディングして、コンパイラ、ライブラリ、ツール、コンポーネントなどの場所など、制御するアセンブリに基づいてPATHおよびその他の環境変数を設定します。各構成可能なアイテムを個別に設定、検証、および次に、スクリプトで適切に使用します。
たとえば、新しい雇用主で継承したMavenベースのWebLogicをターゲットとしたJavaビルドがあります。ビルドスクリプトは壊れやすいことで有名で、別の新しい従業員と私は3週間過ごしました(フルタイムではなく、あちこちにありますが、まだ何時間も)マシン上で動作するようにするために不可欠なステップです。どのJava、どのMaven、どのWebLogicが呼び出されているかを正確に把握できるように、 。これらの各ツールを指す環境変数を作成し、それらに加えて他のいくつかに基づいてPATHを計算し、最終的に再現可能なビルドを作成するまで、同様の手法で他の構成可能な設定を調整しました。
ちなみに、Mavenは使用しないでください。Javaは問題ありません。クラスタ化が絶対に必要な場合にのみWebLogicを購入してください(ただし、独自の機能は不要です)。
ご多幸を祈る。