web-dev-qa-db-fra.com

Supprimer les chemins redondants de la variable $ PATH

J'ai défini le même chemin dans la variable $ PATH 6 fois.

Je ne me déconnectais pas pour vérifier si cela fonctionnait.

Comment puis-je enlever les doublons?

La variable $ PATH ressemble à ceci:

echo $PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin

Comment pourrais-je le réinitialiser juste

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
119
charles hendry

Vous venez d'exécuter:

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

que ce soit pour la session en cours, si vous souhaitez le modifier de façon permanente, ajoutez-le à n’importe quel fichier .bashrc, bash.bashrc,/etc/profile - à votre convenance, selon les besoins de votre système et de vos utilisateurs.

111
hovanessyan

Si vous utilisez Bash, vous pouvez également procéder comme suit si, par exemple, vous souhaitez supprimer le répertoire /home/wrong/dir/ de votre variable PATH:

PATH=`echo $PATH | sed -e 's/:\/home\/wrong\/dir\/$//'`
63
sufinawaz

Si vous devez supprimer un chemin de la variable PATH avant l'exécution de votre script, ajoutez ceci au début du script:

PATH=$(echo $PATH | sed -e 's;:\?/home/user/bin;;' -e 's;/home/user/bin:\?;;')

Si vous avez besoin, vous pouvez l'ajouter à nouveau au début de la liste avec:

PATH=/home/user/bin:$PATH

Ou vous pouvez l'ajouter à la fin de la liste avec:

PATH=$PATH:/home/user/bin
14
Alex Jolig

Linux: Supprimer les chemins redondants de la variable $ PATH

Linux From Scratch a ceci fonction dans/etc/profile

# 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"
}

Ceci est destiné à être utilisé avec ces fonctions pour ajouter au chemin, afin que vous ne le fassiez pas de manière redondante:

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"
}

Une utilisation simple consiste simplement à donner à pathremove le chemin du répertoire à supprimer - mais gardez à l'esprit qu'il doit correspondre exactement:

$ pathremove /home/username/anaconda3/bin

Cela supprimera chaque instance de ce répertoire de votre chemin.

Si vous souhaitez que le répertoire se trouve dans votre chemin, mais sans les redondances, vous pouvez simplement utiliser l’une des autres fonctions, par exemple. - pour votre cas particulier:

$ pathprepend /usr/local/sbin
$ pathappend /usr/local/bin
$ pathappend /usr/sbin
$ pathappend /usr/bin
$ pathappend /sbin
$ pathappend /bin
$ pathappend /usr/games

Mais, à moins que la lisibilité ne soit la préoccupation principale, il est préférable que vous fassiez comme suit:

$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Ce qui précède fonctionnerait-il dans toutes les coquilles connues de l'homme?

Je suppose que ce qui précède fonctionne dans sh, dash et bash au moins. Je serais surpris d'apprendre que cela ne fonctionne pas dans csh, fish', orksh`. Je doute que cela fonctionne dans la commande Windows Shell ou Powershell.

Si vous avez Python, le type de commande suivant devrait faire ce qui est demandé directement (c’est-à-dire, supprimer les chemins redondants):

$ PATH=$( python -c "
import os
path = os.environ['PATH'].split(':')
print(':'.join(sorted(set(path), key=path.index)))
" )

Un one-liner (pour éviter les problèmes multilignes):

$ PATH=$( python -c "import os; path = os.environ['PATH'].split(':'); print(':'.join(sorted(set(path), key=path.index)))" )

Ce qui précède supprime les chemins redondants ultérieurs. Pour supprimer les chemins redondants précédents, utilisez l'index d'une liste inversée et inversez-le à nouveau:

$ PATH=$( python -c "
import os
path = os.environ['PATH'].split(':')[::-1]
print(':'.join(sorted(set(path), key=path.index, reverse=True)))
" )
10
Aaron Hall

Voici un code d'une ligne qui nettoie le PATH

  • Il ne perturbe pas l'ordre du PATH, supprime simplement les doublons
  • Traite: et empth PATH avec grâce
  • Aucun caractère spécial utilisé, donc ne nécessite pas d'échappement
  • Utilise /bin/awk pour que cela fonctionne même lorsque PATH est cassé

    export PATH="$(echo "$PATH" |/bin/awk 'BEGIN{RS=":";}
    {sub(sprintf("%c$",10),"");if(A[$0]){}else{A[$0]=1;
    printf(((NR==1)?"":":")$0)}}')";
    
7
GreenFox

Si vous souhaitez simplement supprimer les chemins en double, j'utilise le script que j'ai écrit il y a quelque temps, car j'avais des problèmes avec plusieurs chemins Perl5/bin:

#!/bin/bash
#
# path-cleanup
#
# This must be run as "source path-cleanup" or ". path-cleanup"
# so the current Shell gets the changes.

pathlist=`echo $PATH | sed 's/:/\n/g' | uniq`

# echo "Starting PATH: $PATH"
# echo "pathlist: $pathlist"
unset PATH
# echo "After unset, PATH: $PATH"
for dir in $pathlist
do
    if test -d $dir ; then
        if test -z $PATH; then
            PATH=$dir
        else
            PATH=$PATH:$dir
        fi
    fi
done
export PATH
# echo "After loop, PATH: $PATH"

Et je le mets dans mon ~ /. Profil à la fin. Comme j'utilise presque exclusivement BASH, je ne l'ai pas essayé dans d'autres coquilles.

2
Kevin Nathan

En bash, vous pouvez simplement $ {var/find/replace}

PATH=${PATH/%:\/home\/wrong\/dir\//}

Ou dans ce cas (comme le bit de remplacement est vide), il suffit de:

PATH=${PATH%:\/home\/wrong\/dir\/}

Je suis arrivé ici le premier, mais je suis allé dans un autre magasin car je pensais qu'il y aurait un expansion des paramètres pour le faire. Plus facile que sed !.

Comment remplacer le caractère de substitution ou le mot dans variable par la valeur d'une autre variable dans Bash?

2
sabgenton

Pour un modèle de copier-coller facile, j’utilise cet extrait de code Perl:

PATH=`echo $PATH | Perl -pe s:/path/to/be/excluded::`

De cette façon, vous n'avez pas besoin d'échapper aux barres obliques pour l'opérateur substitué.

1
Alexander Shcheblikin
  1. Juste echo $PATH
  2. copier les détails dans un éditeur de texte
  3. supprimer les entrées indésirables
  4. PATH= # pass new list of entries
1
ckwagaba

Il n’existe aucun outil standard pour "éditer" la valeur de $PATH (c'est-à-dire "ajouter un dossier uniquement s'il n'existe pas déjà" ou "supprimer ce dossier").

Pour vérifier quel serait le chemin lors de votre prochaine connexion, utilisez telnet localhost (ou telnet 127.0.0.1). Il vous demandera ensuite votre nom d'utilisateur et votre mot de passe.

Cela vous donne un nouveau shell de connexion (c'est-à-dire un tout nouveau qui n'hérite de rien de l'environnement actuel).

Vous pouvez vérifier la valeur du $PATH et éditer vos fichiers rc jusqu’à ce qu’elle soit correcte. Cela est également utile pour savoir si vous pouvez vous connecter à nouveau après avoir modifié un fichier important.

0
Aaron Digulla

Comment avez-vous ajouté ces chemins dupliqués à votre variable PATH? Vous devez avoir édité l'un de vos fichiers .. (.tcshrc ou .bashrc, etc. selon votre système/shell particulier). La solution consiste à modifier à nouveau le fichier et à supprimer les chemins en double.

Si vous n'avez pas éditez des fichiers et que vous devez avoir modifié le PATH de manière interactive. Dans ce cas, les modifications ne "resteront" pas, c.-à-d. Que si vous ouvrez un autre Shell ou vous vous déconnectez et vous reconnectez, les modifications disparaîtront automatiquement.

Notez qu'il existe également des fichiers de configuration à l'échelle du système, mais il est peu probable que vous les ayez modifiés. Il est donc probable que vous modifierez des fichiers dans votre répertoire personnel (si vous souhaitez rendre ces modifications permanentes une fois que vous avez défini un ensemble de chemins).

0
Levon

En supposant que votre shell est Bash, vous pouvez définir le chemin avec

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

mais comme l'a dit Levon dans une autre réponse, dès que vous aurez terminé le Shell, les modifications auront disparu. Vous voudrez probablement configurer votre PATH dans ~/.bash_profile ou ~/.bashrc.

0
Leo