J'essaie de compiler wxWidgets en utilisant MingW, et j'ai cygwin sur mon chemin, ce qui semble être en conflit. Je voudrais donc supprimer /d/Programme/cygwin/bin
à partir de la variable PATH et je me demande s'il existe une manière élégante de le faire.
L'approche naïve serait de l'écho dans un fichier, de le supprimer manuellement et de le source, mais je parie qu'il y a une meilleure approche à cela.
Il n'y a pas d'outils standard pour "éditer" la valeur de $ PATH (c'est-à-dire "ajouter un dossier uniquement lorsqu'il n'existe pas déjà" ou "supprimer ce dossier"). Vous exécutez simplement:
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
ce serait pour la session en cours, si vous voulez changer de façon permanente, ajoutez-le à n'importe quel .bashrc, bash.bashrc,/etc/profile - tout ce qui convient à votre système et aux besoins des utilisateurs. Cependant, si vous utilisez BASH, vous pouvez également effectuer les opérations suivantes si, disons, vous souhaitez supprimer le répertoire /home/wrong/dir/
à partir de votre variable PATH, en supposant que c'est à la fin:
PATH=$(echo "$PATH" | sed -e 's/:\/home\/wrong\/dir$//')
Donc, dans votre cas, vous pouvez utiliser
PATH=$(echo "$PATH" | sed -e 's/:\/d\/Programme\/cygwin\/bin$//')
En bash:
directory_to_remove=/d/Programme/cygwin/bin
PATH=:$PATH:
PATH=${PATH//:$directory_to_remove:/:}
PATH=${PATH#:}; PATH=${PATH%:}
Si vous n'utilisez pas de variable intermédiaire, vous devez protéger le /
caractères dans le répertoire à supprimer afin qu'ils ne soient pas traités comme la fin du texte de recherche.
PATH=:$PATH:
PATH=${PATH//:\/d\/Programme\/cygwin\/bin:/:}
PATH=${PATH#:}; PATH=${PATH%:}
La première et la troisième ligne sont là pour faire en sorte que chaque composant du chemin de recherche soit entouré par :
, pour éviter de placer dans un boîtier spécial le premier et le dernier composant. La deuxième ligne supprime le composant spécifié.
Après avoir examiné les autres options présentées ici et ne pas avoir compris comment certaines d'entre elles fonctionnaient, j'ai développé mon propre path_remove
, que j'ai ajoutée à mon .bashrc
:
function path_remove {
# Delete path by parts so we can never accidentally remove sub paths
PATH=${PATH//":$1:"/":"} # delete any instances in the middle
PATH=${PATH/#"$1:"/} # delete any instance at the beginning
PATH=${PATH/%":$1"/} # delete any instance in the at the end
}
Cela s'est avéré assez proche de la solution de Gilles mais a été présenté comme une fonction bash qui pourrait être facilement utilisée sur la ligne de commande.
Il a les avantages qu'en tant que fonction bash, il fonctionne comme un programme sans avoir besoin d'être un programme sur le chemin, et il ne nécessite aucun programme externe pour s'exécuter, juste une manipulation de chaîne bash.
Il semble assez robuste, en particulier il ne tourne pas somepath:mypath/mysubpath
en somepath/mysubpath
: si vous exécutez path_remove mypath
, qui était un problème que j'avais avec mon précédent path_remove
une fonction.
Une excellente explication du fonctionnement de la manipulation de chaînes bash peut être trouvée dans le Advanced Bash-Scripting Guide .
Donc, en combinant les réponses de @gilles et @ bruno-a (et quelques autres astuces sed), j'ai trouvé ce one-liner, qui supprimera (chaque) REMOVE_PART de PATH, qu'il se produise au début, milieu ou fin de CHEMIN
PATH=$(REMOVE_PART="/d/Programme/cygwin/bin" sh -c 'echo ":$PATH:" | sed "s@:$REMOVE_PART:@:@g;s@^:\(.*\):\$@\1@"')
C'est un peu lourd, mais c'est bien de pouvoir le faire en un seul coup. Le ;
Est utilisé pour réunir les deux commandes sed distinctes:
s@:$REMOVE_PART:@:@g
(Qui remplace :$REMOVE_PART:
Par un seul :
)s@^:\(.*\):\$@\1@
(qui supprime les deux-points avant et arrière que nous avons ajoutés avec la commande echo)Et dans le même ordre d'idées, je suis juste parvenu à trouver cette doublure pour ajouter un ADD_PART au PATH, seulement si le PATH ne le contient pas déjà
PATH=$(ADD_PART="/d/Programme/cygwin/bin" sh -c 'if echo ":$PATH:" | grep -q ":$ADD_PART:"; then echo "$PATH"; else echo "$ADD_PART:$PATH"; fi')
Remplacez la dernière partie par echo "$PATH:$ADD_PART"
Si vous souhaitez ajouter ADD_PART à la fin de PATH plutôt qu'au début.
...
... ou pour rendre cela encore plus facile, créez un script appelé remove_path_part
avec le contenu
echo ":$PATH:" | sed "s@:$1:@:@g;s@^:\(.*\):\$@\1@"
et un script appelé prepend_path_part
avec le contenu
if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$1:$PATH"; fi
et un script appelé append_path_part
avec le contenu
if echo ":$PATH:" | grep -q ":$1:"; then echo "$PATH"; else echo "$PATH:$1"; fi
rendez-les tous exécutables, puis appelez-les comme:
PATH=$(remove_path_part /d/Programme/cygwin/bin)
PATH=$(prepend_path_part /d/Programme/cygwin/bin)
PATH=$(append_path_part /d/Programme/cygwin/bin)
Bien, même si je le dis moi-même :-)
Une doublure beaucoup plus simple.
export PATH = `echo $ PATH | tr ":" "\ n" | grep -v "anaconda" | tr "\ n" ":" `
C'est un exercice intéressant d'écrire une fonction bash pour supprimer un répertoire d'une variable de chemin.
Voici quelques fonctions que j'utilise dans mes fichiers .bash * pour ajouter/ajouter des répertoires aux chemins. Ils ont le mérite de supprimer les entrées en double, le cas échéant, et fonctionnent avec tout type de variable de chemin séparé par deux points (PATH, MANPATH, INFOPATH, ...). la fonction remove_from supprime le répertoire.
# {app,pre}pend_to path-var-name dirpath
# remove_from path-var-name dirpath
#
# Functions to manipulate a path-style variable. {app,pre}pend_to
# both remove any other instances of dirname before adding it to
# the start or end of the path-var-name variable.
#
# Calling example:
# append_to PATH "/usr/local/bin"
#
# Uses eval to allow target path varname to be passed in.
function remove_from() {
# add surrounging colons
eval tmp_path=":\$${1}:"
# if dir is already there, remove it
(echo "${tmp_path}" | grep --silent ":${2}:") &&
tmp_path=`echo "$tmp_path" | sed "s=:${2}:=:=g"`
# remove surrounding colons
tmp_path=`echo "$tmp_path" | sed 's=^:==; s=:$=='`
eval export $1=\"$tmp_path\"
}
function append_to() {
remove_from "$1" "$2" # clean the path contents
eval export $1=\"\$${1}:$2\"
}
function prepend_to() {
remove_from "$1" "$2" # clean the path contents
eval export $1=\"${2}:\$$1\"
}
Voici le code révisé de la solution de Greg Tarsa. Seules les commandes intégrées bash sont utilisées ici. Ainsi, cela économisera beaucoup d'appels système fork ().
# Calling example:
# append_to PATH "/usr/local/bin"
function remove_from()
{
local path="${1}"
local dir="${2}"
local -a dirs=()
local old_ifs="${IFS}"
IFS=":"
set -- ${!path}
while [ "$#" -gt "0" ]
do
[ "${1}" != "${dir}" ] && dirs+=("${1}")
shift
done
eval "export ${path}=\"${dirs[*]}\""
IFS="${old_ifs}"
}
function append_to()
{
remove_from "${1}" "${2}"
[ -d "${2}" ] || return
if [ -n "${!1}" ]
then
eval "export ${1}=\"${!1}:${2}\""
else
eval "export ${1}=\"${2}\""
fi
}
function prepend_to()
{
remove_from "${1}" "${2}"
[ -d "${2}" ] || return
if [ -n "${!1}" ]
then
eval "export ${1}=\"${2}:${!1}\""
else
eval "export ${1}=\"${2}\""
fi
}
Cette méthode gère le délimiteur de chemin de début/fin:
echo $PATH | sed 's/:/\n/g' | grep -v <path description> | xargs | tr ' ' ':'
Explication:
echo
la variable $ PATH en sed
qui remplace ':' par des sauts de ligne
grep
la sortie et supprimez les lignes correspondant à notre requête
xargs
la sortie pour remplacer les sauts de ligne par des espaces
tr
la sortie pour remplacer les espaces par des deux-points
xargs
gère le découpage des valeurs de fin
chaîne quelques grep
s pour supprimer un tas de chemins
Pour compléter/améliorer la réponse acceptée de Tushar, vous pouvez:
-e
option, selon la page de manuel sed : "Si aucune option -e, --expression, -f ou --file n'est donnée, le premier argument sans option est pris comme script sed à interpréter. "g
(global) pour supprimer toutes les occurrencesEn fin de compte, cela donne quelque chose comme ceci:
PATH=$(echo "$PATH" | sed 's@:/home/wrong/dir$@@g')
Les réponses actuelles ne résolvent pas mon problème similaire en ce sens que je dois supprimer plusieurs chemins. Tous ces chemins sont des sous-répertoires d'un seul répertoire. Dans ce cas, ce one-liner fonctionne pour moi: (supposons que le modèle est cygwin
, c'est-à-dire, en supprimant tous les chemins qui contiennent cygwin
)
pattern=cygwin; export PATH=$(echo $PATH|tr ':' '\n'|sed "\#${pattern}#d" |tr '\n' ':')