Domanda

Esiste un modo idiomatico di rimuovere elementi da variabili shell tipo PATH?

Questo è quello che voglio prendere

PATH=/home/joe/bin:/usr/local/bin:/usr/bin:/bin:/path/to/app/bin:.

e rimuovi o sostituisci il / path / to / app / bin senza ostruire il resto della variabile. Punti extra per avermi permesso di mettere nuovi elementi in posizioni arbitrarie. Il target sarà riconoscibile da una stringa ben definita e potrebbe verificarsi in qualsiasi punto dell'elenco.

So di averlo visto fatto e probabilmente posso mettere insieme qualcosa da solo, ma sto cercando un approccio piacevole. Portabilità e standardizzazione un vantaggio.

Uso bash, ma anche gli esempi sono i benvenuti nella tua shell preferita.


Il contesto qui è quello di dover passare convenientemente tra più versioni (una per fare analisi, un'altra per lavorare sul framework) di un ampio pacchetto di analisi scientifica che produce una dozzina di eseguibili, ha i dati racchiusi nel filesystem e usa la variabile d'ambiente per aiutare a trovare tutte queste cose. Vorrei scrivere uno script che seleziona una versione e devo poter rimuovere gli elementi $ PATH relativi alla versione attualmente attiva e sostituirli con gli stessi elementi relativi alla nuova versione.


Questo è legato al problema di prevenire elementi $ PATH ripetuti quando si rieseguono script di login e simili.


È stato utile?

Soluzione

Indirizzare la soluzione proposta da dmckee:

  1. Mentre alcune versioni di Bash possono consentire trattini nei nomi delle funzioni, altre (MacOS X) no.
  2. Non vedo la necessità di utilizzare return immediatamente prima della fine della funzione.
  3. Non vedo la necessità di tutti i punti e virgola.
  4. Non vedo perché hai esportato un valore percorso elemento per modello. Pensa a export come equivalente all'impostazione (o persino alla creazione) di una variabile globale - qualcosa da evitare quando possibile.
  5. Non sono sicuro di cosa ti aspetti che faccia < sostituisci percorso PATH $ PERCORSO / usr , ma non fa ciò che mi aspetto.

Prendi in considerazione un valore PERCORSO che inizia con:

.
/Users/jleffler/bin
/usr/local/postgresql/bin
/usr/local/mysql/bin
/Users/jleffler/perl/v5.10.0/bin
/usr/local/bin
/usr/bin
/bin
/sw/bin
/usr/sbin
/sbin

Il risultato che ho ottenuto (da ' replace-path PATH $ PATH / usr ') è:

.
/Users/jleffler/bin
/local/postgresql/bin
/local/mysql/bin
/Users/jleffler/perl/v5.10.0/bin
/local/bin
/bin
/bin
/sw/bin
/sbin
/sbin

Mi sarei aspettato di recuperare il mio percorso originale poiché / usr non appare come un elemento (completo) del percorso, solo come parte di un elemento del percorso.

Questo può essere risolto in replace-path modificando uno dei comandi sed :

export $path=$(echo -n $list | tr ":" "\n" | sed "s:^$removestr\$:$replacestr:" |
               tr "\n" ":" | sed "s|::|:|g")

Ho usato ':' invece di '|' separare parti del sostituto dal '|' potrebbe (in teoria) apparire in una componente del percorso, mentre per definizione di PERCORSO, un colon non può. Osservo che il secondo sed potrebbe eliminare l'attuale directory dal mezzo di un PERCORSO. Cioè, un valore legittimo (sebbene perverso) di PATH potrebbe essere:

PATH=/bin::/usr/local/bin

Dopo l'elaborazione, la directory corrente non sarà più sul PERCORSO.

Una modifica simile per ancorare la corrispondenza è appropriata in path-element-by-pattern :

export $target=$(echo -n $list | tr ":" "\n" | grep -m 1 "^$pat\
# path_tools.bash
#
# A set of tools for manipulating ":" separated lists like the
# canonical $PATH variable.
#
# /bin/sh compatibility can probably be regained by replacing $( )
# style command expansion with ` ` style
###############################################################################
# Usage:
#
# To remove a path:
#    replace_path         PATH $PATH /exact/path/to/remove
#    replace_path_pattern PATH $PATH <grep pattern for target path>
#
# To replace a path:
#    replace_path         PATH $PATH /exact/path/to/remove /replacement/path
#    replace_path_pattern PATH $PATH <target pattern> /replacement/path
#
###############################################################################

# Remove or replace an element of $1
#
#   $1 name of the shell variable to set (e.g. PATH)
#   $2 a ":" delimited list to work from (e.g. $PATH)
#   $3 the precise string to be removed/replaced
#   $4 the replacement string (use "" for removal)
function replace_path () {
    path=$1
    list=$2
    remove=$3
    replace=$4        # Allowed to be empty or unset

    export $path=$(echo "$list" | tr ":" "\n" | sed "s:^$remove\$:$replace:" |
                   tr "\n" ":" | sed 's|:$||')
}

# Remove or replace an element of $1
#
#   $1 name of the shell variable to set (e.g. PATH)
#   $2 a ":" delimited list to work from (e.g. $PATH)
#   $3 a grep pattern identifying the element to be removed/replaced
#   $4 the replacement string (use "" for removal)
function replace_path_pattern () {
    path=$1
    list=$2
    removepat=$3
    replacestr=$4        # Allowed to be empty or unset

    removestr=$(echo "$list" | tr ":" "\n" | grep -m 1 "^$removepat\
#!/usr/bin/perl -w
#
#   "@(#)$Id: echopath.pl,v 1.7 1998/09/15 03:16:36 jleffler Exp 
echo
xpath=$PATH
replace_path xpath $xpath /usr
echopath $xpath

echo
xpath=$PATH
replace_path_pattern xpath $xpath /usr/bin /work/bin
echopath xpath

echo
xpath=$PATH
replace_path_pattern xpath $xpath "/usr/.*/bin" /work/bin
echopath xpath
quot; # # Print the components of a PATH variable one per line. # If there are no colons in the arguments, assume that they are # the names of environment variables. @ARGV = $ENV{PATH} unless @ARGV; foreach $arg (@ARGV) { $var = $arg; $var = $ENV{$arg} if $arg =~ /^[A-Za-z_][A-Za-z_0-9]*$/; $var = $arg unless $var; @lst = split /:/, $var; foreach $val (@lst) { print "$val\n"; } }
quot;) replace_path "$path" "$list" "$removestr" "$replacestr" }
quot;)

Prendo atto che grep -m 1 non è standard (è un'estensione GNU, disponibile anche su MacOS X). E, in effetti, anche l'opzione -n per echo non è standard; staresti meglio semplicemente cancellando i due punti finali aggiunti in virtù della conversione della nuova riga dall'eco in due punti. Poiché il percorso elemento per modello viene usato una sola volta, ha effetti collaterali indesiderati (blocca qualsiasi variabile esportata preesistente chiamata $ removestr ), può essere sostituita sensibilmente dal suo corpo. Questo, insieme a un uso più liberale delle virgolette per evitare problemi con spazi o l'espansione indesiderata dei nomi di file, porta a:

.
/Users/jleffler/bin
/usr/local/postgresql/bin
/usr/local/mysql/bin
/Users/jleffler/perl/v5.10.0/bin
/usr/local/bin
/usr/bin
/bin
/sw/bin
/usr/sbin
/sbin

.
/Users/jleffler/bin
/usr/local/postgresql/bin
/usr/local/mysql/bin
/Users/jleffler/perl/v5.10.0/bin
/usr/local/bin
/work/bin
/bin
/sw/bin
/usr/sbin
/sbin

.
/Users/jleffler/bin
/work/bin
/usr/local/mysql/bin
/Users/jleffler/perl/v5.10.0/bin
/usr/local/bin
/usr/bin
/bin
/sw/bin
/usr/sbin
/sbin

Ho uno script Perl chiamato echopath che trovo utile quando eseguo il debug di problemi con variabili tipo PATH:

replace_path PATH /usr/bin /work/bin

Quando eseguo la soluzione modificata sul codice di test riportato di seguito:

list=$(eval echo '

L'output è:

# path_tools.bash
#
# A set of tools for manipulating ":" separated lists like the
# canonical $PATH variable.
#
# /bin/sh compatibility can probably be regained by replacing $( )
# style command expansion with ` ` style
###############################################################################
# Usage:
#
# To remove a path:
#    replace_path         PATH /exact/path/to/remove
#    replace_path_pattern PATH <grep pattern for target path>
#
# To replace a path:
#    replace_path         PATH /exact/path/to/remove /replacement/path
#    replace_path_pattern PATH <target pattern> /replacement/path
#
###############################################################################

# Remove or replace an element of $1
#
#   $1 name of the shell variable to set (e.g. PATH)
#   $2 the precise string to be removed/replaced
#   $3 the replacement string (use "" for removal)
function replace_path () {
    path=$1
    list=$(eval echo '

Questo mi sembra corretto, almeno per la mia definizione di quale sia il problema.

Prendo atto che echopath LD_LIBRARY_PATH valuta $ LD_LIBRARY_PATH . Sarebbe bello se le tue funzioni fossero in grado di farlo, quindi l'utente potrebbe digitare:

echo
xpath=$PATH
replace_path xpath /usr
echopath xpath

echo
xpath=$PATH
replace_path_pattern xpath /usr/bin /work/bin
echopath xpath

echo
xpath=$PATH
replace_path_pattern xpath "/usr/.*/bin" /work/bin
echopath xpath

Questo può essere fatto usando:

<*>

Questo porta a questa revisione del codice:

<*>

Ora funziona anche il seguente test rivisto:

<*>

Produce lo stesso output di prima.

$path)

L'output è:

<*>

Questo mi sembra corretto, almeno per la mia definizione di quale sia il problema.

Prendo atto che echopath LD_LIBRARY_PATH valuta $ LD_LIBRARY_PATH . Sarebbe bello se le tue funzioni fossero in grado di farlo, quindi l'utente potrebbe digitare:

<*>

Questo può essere fatto usando:

<*>

Questo porta a questa revisione del codice:

<*>

Ora funziona anche il seguente test rivisto:

<*>

Produce lo stesso output di prima.

$path) remove=$2 replace=$3 # Allowed to be empty or unset export $path=$(echo "$list" | tr ":" "\n" | sed "s:^$remove\$:$replace:" | tr "\n" ":" | sed 's|:$||') } # Remove or replace an element of $1 # # $1 name of the shell variable to set (e.g. PATH) # $2 a grep pattern identifying the element to be removed/replaced # $3 the replacement string (use "" for removal) function replace_path_pattern () { path=$1 list=$(eval echo '

Questo mi sembra corretto, almeno per la mia definizione di quale sia il problema.

Prendo atto che echopath LD_LIBRARY_PATH valuta $ LD_LIBRARY_PATH . Sarebbe bello se le tue funzioni fossero in grado di farlo, quindi l'utente potrebbe digitare:

<*>

Questo può essere fatto usando:

<*>

Questo porta a questa revisione del codice:

<*>

Ora funziona anche il seguente test rivisto:

<*>

Produce lo stesso output di prima.

$path)

L'output è:

<*>

Questo mi sembra corretto, almeno per la mia definizione di quale sia il problema.

Prendo atto che echopath LD_LIBRARY_PATH valuta $ LD_LIBRARY_PATH . Sarebbe bello se le tue funzioni fossero in grado di farlo, quindi l'utente potrebbe digitare:

<*>

Questo può essere fatto usando:

<*>

Questo porta a questa revisione del codice:

<*>

Ora funziona anche il seguente test rivisto:

<*>

Produce lo stesso output di prima.

$path) removepat=$2 replacestr=$3 # Allowed to be empty or unset removestr=$(echo "$list" | tr ":" "\n" | grep -m 1 "^$removepat\<*>quot;) replace_path "$path" "$removestr" "$replacestr" }

Questo mi sembra corretto, almeno per la mia definizione di quale sia il problema.

Prendo atto che echopath LD_LIBRARY_PATH valuta $ LD_LIBRARY_PATH . Sarebbe bello se le tue funzioni fossero in grado di farlo, quindi l'utente potrebbe digitare:

<*>

Questo può essere fatto usando:

<*>

Questo porta a questa revisione del codice:

<*>

Ora funziona anche il seguente test rivisto:

<*>

Produce lo stesso output di prima.

$path)

L'output è:

<*>

Questo mi sembra corretto, almeno per la mia definizione di quale sia il problema.

Prendo atto che echopath LD_LIBRARY_PATH valuta $ LD_LIBRARY_PATH . Sarebbe bello se le tue funzioni fossero in grado di farlo, quindi l'utente potrebbe digitare:

<*>

Questo può essere fatto usando:

<*>

Questo porta a questa revisione del codice:

<*>

Ora funziona anche il seguente test rivisto:

<*>

Produce lo stesso output di prima.

Altri suggerimenti

Ripubblicando la mia risposta a Qual è il modo più elegante per rimuovere un percorso dalla variabile $ PATH in 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[*]}"

o one-liner:

PATH=$(IFS=':';t=($PATH);unset IFS;t=(${t[@]%%*usr*});IFS=':';echo "${t[*]}");

Per cancellare un elemento puoi usare sed:

#!/bin/bash
NEW_PATH=$(echo -n $PATH | tr ":" "\n" | sed "/foo/d" | tr "\n" ":")
export PATH=$NEW_PATH

eliminerà i percorsi che contengono " foo " dal percorso.

Puoi anche usare sed per inserire una nuova riga prima o dopo una data riga.

Modifica: puoi rimuovere i duplicati eseguendo il piping tramite sort e uniq:

echo -n $PATH | tr ":" "\n" | sort | uniq -c | sed -n "/ 1 / s/.*1 \(.*\)/\1/p" | sed "/foo/d" | tr "\n" ":"

Esistono un paio di programmi pertinenti nelle risposte a " Come evitare di duplicare la variabile del percorso in csh " ;. Si concentrano maggiormente sull'assicurare che non vi siano elementi ripetuti, ma lo script che fornisco può essere usato come:

export PATH=$(clnpath $head_dirs:$PATH:$tail_dirs $remove_dirs)

Supponendo che tu abbia una o più directory in $ head_dirs e una o più directory in $ tail_dirs e una o più directory in $ remove_dirs, quindi usa la shell per concatenare le parti head, current e tail in un valore enorme, e quindi rimuove ciascuna delle directory elencate in $ remove_dirs dal risultato (non un errore se non esistono), oltre a eliminare le seconde e successive occorrenze di qualsiasi directory nel percorso.

Non si tratta di mettere i componenti del percorso in una posizione specifica (tranne all'inizio o alla fine, e solo indirettamente). Notativamente, specificare dove si desidera aggiungere il nuovo elemento o quale elemento si desidera sostituire è disordinato.

Solo una nota che bash stesso può fare ricerca e sostituire. Può fare tutte le normali opzioni "una volta o tutte", in casi sensibili [in] che ti aspetteresti.

Dalla pagina man:

$ {parametro / modello / stringa}

Il pattern viene espanso per produrre un pattern proprio come nell'espansione del nome percorso. Il parametro viene espanso e la corrispondenza più lunga del modello rispetto al suo valore viene sostituita con stringa. Se Ipattern inizia con /, tutte le corrispondenze del modello vengono sostituite con stringa. Normalmente viene sostituita solo la prima partita. Se il modello inizia con #, deve corrispondere all'inizio del valore espanso del parametro. Se il modello inizia con%, deve corrispondere alla fine del valore espanso del parametro. Se la stringa è nulla, le corrispondenze del modello vengono eliminate e il modello / seguente può essere omesso. Se il parametro è @ o *, l'operazione di sostituzione viene applicata a turno a ciascun parametro posizionale e l'espansione è l'elenco risultante. Se il parametro è una variabile di matrice sottoscritta con @ o *, l'operazione di sostituzione viene applicata a turno a ciascun membro dell'array e l'espansione è l'elenco risultante.

Puoi anche dividere i campi impostando $ IFS (separatore dei campi di input) sul delimitatore desiderato.

OK, grazie a tutti i rispondenti. Ho preparato una versione incapsulata della risposta di Florin. Il primo passaggio è simile al seguente:

# path_tools.bash
#
# A set of tools for manipulating ":" separated lists like the
# canonical $PATH variable.
#
# /bin/sh compatibility can probably be regained by replacing $( )
# style command expansion with ` ` style
###############################################################################
# Usage:
#
# To remove a path:
#    replace-path         PATH $PATH /exact/path/to/remove    
#    replace-path-pattern PATH $PATH <grep pattern for target path>    
#
# To replace a path:
#    replace-path         PATH $PATH /exact/path/to/remove /replacement/path   
#    replace-path-pattern PATH $PATH <target pattern> /replacement/path
#    
###############################################################################
# Finds the _first_ list element matching $2
#
#    $1 name of a shell variable to be set
#    $2 name of a variable with a path-like structure
#    $3 a grep pattern to match the desired element of $1
function path-element-by-pattern (){ 
    target=$1;
    list=$2;
    pat=$3;

    export $target=$(echo -n $list | tr ":" "\n" | grep -m 1 $pat);
    return
}

# Removes or replaces an element of $1
#
#   $1 name of the shell variable to set (i.e. PATH) 
#   $2 a ":" delimited list to work from (i.e. $PATH)
#   $2 the precise string to be removed/replaced
#   $3 the replacement string (use "" for removal)
function replace-path () {
    path=$1;
    list=$2;
    removestr=$3;
    replacestr=$4; # Allowed to be ""

    export $path=$(echo -n $list | tr ":" "\n" | sed "s|$removestr|$replacestr|" | tr "\n" ":" | sed "s|::|:|g");
    unset removestr
    return 
}

# Removes or replaces an element of $1
#
#   $1 name of the shell variable to set (i.e. PATH) 
#   $2 a ":" delimited list to work from (i.e. $PATH)
#   $2 a grep pattern identifying the element to be removed/replaced
#   $3 the replacement string (use "" for removal)
function replace-path-pattern () {
    path=$1;
    list=$2;
    removepat=$3; 
    replacestr=$4; # Allowed to be ""

    path-element-by-pattern removestr $list $removepat;
    replace-path $path $list $removestr $replacestr;
}

Ho ancora bisogno di intercettare errori in tutte le funzioni, e probabilmente dovrei attaccare una soluzione a percorso ripetuto mentre ci sono.

Lo usi facendo un . /include/path/path_tools.bash nello script di lavoro e invocazione delle funzioni replace-path * .


Sono ancora aperto a risposte nuove e / o migliori.

È facile usare awk.

Sostituire

{
  for(i=1;i<=NF;i++) 
      if($i == REM) 
          if(REP)
              print REP; 
          else
              continue;
      else 
          print $i; 
}

Avvialo usando

function path_repl {
    echo $PATH | awk -F: -f rem.awk REM="$1" REP="$2" | paste -sd:
}

$ echo $PATH
/bin:/usr/bin:/home/js/usr/bin
$ path_repl /bin /baz
/baz:/usr/bin:/home/js/usr/bin
$ path_repl /bin
/usr/bin:/home/js/usr/bin

Append

Inserisce nella posizione data. Per impostazione predefinita, viene aggiunto alla fine.

{ 
    if(IDX < 1) IDX = NF + IDX + 1
    for(i = 1; i <= NF; i++) {
        if(IDX == i) 
            print REP 
        print $i
    }
    if(IDX == NF + 1)
        print REP
}

Avvialo usando

function path_app {
    echo $PATH | awk -F: -f app.awk REP="$1" IDX="$2" | paste -sd:
}

$ echo $PATH
/bin:/usr/bin:/home/js/usr/bin
$ path_app /baz 0
/bin:/usr/bin:/home/js/usr/bin:/baz
$ path_app /baz -1
/bin:/usr/bin:/baz:/home/js/usr/bin
$ path_app /baz 1
/baz:/bin:/usr/bin:/home/js/usr/bin

Rimuovi duplicati

Questo mantiene le prime occorrenze.

{ 
    for(i = 1; i <= NF; i++) {
        if(!used[$i]) {
            print $i
            used[$i] = 1
        }
    }
}

Inizia così:

echo $PATH | awk -F: -f rem_dup.awk | paste -sd:

Convalida se esistono tutti gli elementi

Di seguito verrà stampato un messaggio di errore per tutte le voci che non sono presenti nel filesystem e restituirà un valore diverso da zero.

echo -n $PATH | xargs -d: stat -c %n

Per controllare semplicemente se tutti gli elementi sono percorsi e ottenere un codice di ritorno, puoi anche utilizzare test :

echo -n $PATH | xargs -d: -n1 test -d

supponi

echo $PATH
/usr/lib/jvm/java-1.6.0/bin:lib/jvm/java-1.6.0/bin/:/lib/jvm/java-1.6.0/bin/:/usr/lib/qt-3.3/bin:/usr/lib/ccache:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/tvnadeesh/bin

Se vuoi rimuovere /lib/jvm/java-1.6.0/bin/ fai come di seguito

export PATH=$(echo $PATH | sed  's/\/lib\/jvm\/java-1.6.0\/bin\/://g')

sed prenderà l'input da echo $ PATH e sostituirà /lib/jvm/java-1.6.0/bin/: con vuoto

in questo modo è possibile rimuovere

  • L'ordine del PERCORSO non è disturbato
  • Gestisce casi angolari come percorso vuoto, spazio nel percorso con grazia
  • La corrispondenza parziale di dir non fornisce falsi positivi
  • Tratta il percorso in testa e in coda al PERCORSO in modo corretto. No : immondizia e simili.

Di 'che hai     / Foo: / qualche / percorso: / qualche / percorso / dir1: / qualche / percorso / dir2: / bar e vuoi sostituire     / Some / percorso Quindi sostituisce correttamente " / some / path " ma lascia " / some / path / dir1 " o " / some / path / dir2 " ;, come quello che ti aspetteresti.

function __path_add(){  
    if [ -d "$1" ] ; then  
        local D=":${PATH}:";   
        [ "${D/:$1:/:}" == "$D" ] && PATH="$PATH:$1";  
        PATH="${PATH/#:/}";  
        export PATH="${PATH/%:/}";  
    fi  
}
function __path_remove(){  
    local D=":${PATH}:";  
    [ "${D/:$1:/:}" != "$D" ] && PATH="${D/:$1:/:}";  
    PATH="${PATH/#:/}";  
    export PATH="${PATH/%:/}";  
}  
# Just for the shake of completeness
function __path_replace(){  
    if [ -d "$2" ] ; then  
        local D=":${PATH}:";   
        if [ "${D/:$1:/:}" != "$D" ] ; then
            PATH="${D/:$1:/:$2:}";  
            PATH="${PATH/#:/}";  
            export PATH="${PATH/%:/}";  
        fi
    fi  
}  

Post correlato Qual è il modo più elegante per rimuovere un percorso dalla variabile $ PATH in Bash?

Preferisco usare il rubino a artisti del calibro di awk / sed / foo in questi giorni, quindi ecco il mio approccio per gestire i duplicati,

# add it to the path
PATH=~/bin/:$PATH:~/bin
export PATH=$(ruby -e 'puts ENV["PATH"].split(/:/).uniq.join(":")')

crea una funzione per il riutilizzo,

mungepath() {
   export PATH=$(ruby -e 'puts ENV["PATH"].split(/:/).uniq.join(":")')
}

Hash, array e stringhe in un liner rubino :)

La prima cosa che mi viene in mente di cambiare solo parte di una stringa è una sostituzione sed.

Esempio: se echo $ PATH = > & Quot; / usr / pkg / bin: / usr / bin: / bin: / usr / pkg / giochi: / usr / pkg / X11R6 / bin " quindi per cambiare " / usr / bin " a " / usr / local / bin " potrebbe essere fatto in questo modo:

## produce file di output standard

## the " = " viene utilizzato il carattere anziché la barra (" / ") poiché sarebbe disordinato,  # Il carattere di citazione alternativo dovrebbe essere improbabile nel PERCORSO

## il carattere separatore di percorso ": " viene rimosso e aggiunto nuovamente qui,  # potrebbe desiderare un punto in più dopo l'ultimo percorso

echo $ PATH | sed '= / usr / bin: = / usr / local / bin: ='

Questa soluzione sostituisce un intero elemento path quindi potrebbe essere ridondante se new-element è simile.

Se i nuovi PATH non sono dinamici ma sempre all'interno di un insieme costante, è possibile salvare quelli in una variabile e assegnarli secondo necessità:

PATH = $ TEMP_PATH_1;  # comandi ...; \ n PATH = $ TEMP_PATH_2;  # comandi ecc ...;

Potrebbe non essere quello che stavi pensando. alcuni dei comandi rilevanti su bash / unix sarebbero:

pushd popd CD ls # forse l -1A per singola colonna; trova grep quale # potrebbe confermare che il file è da dove pensi che sia venuto; ENV Tipo

..e tutto il resto ha alcuni attinenti a PATH o directory in generale. La parte che modifica il testo può essere eseguita in vari modi!

Qualunque soluzione scelta avrebbe 4 parti:

1) recupera il percorso così com'è 2) decodifica il percorso per trovare la parte che necessita di modifiche 3) determinare quali cambiamenti sono necessari / integrare tali cambiamenti 4) validazione / integrazione finale / impostazione della variabile

In linea con la risposta di dj_segfault , lo faccio negli script che aggiungono / antepongono variabili di ambiente che potrebbero essere eseguite più volte :

ld_library_path=${ORACLE_HOME}/lib
LD_LIBRARY_PATH=${LD_LIBRARY_PATH//${ld_library_path}?(:)/}
export LD_LIBRARY_PATH=${ld_library_path}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

Usare questa stessa tecnica per rimuovere, sostituire o manipolare le voci in PATH è banale dato la corrispondenza del modello simile all'espansione del nome file e il supporto dell'elenco dei modelli dell'espansione dei parametri della shell.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top