Lo schermo GNU non erediterà il mio PERCORSO su 10.5.8


11

Uso lo schermo su base giornaliera per le esigenze dei miei terminali e ne sono abbastanza soddisfatto. Recentemente, però, ho fatto alcuni aggiornamenti ai miei file di configurazione bash e ho notato che stavo installando vari PATHelementi ( PATH, MANPATH, INFOPATH, ecc) in 2 posti. Ho modificato i file per essere quelli che dovrebbero essere e ora tutte le mie variabili di ambiente vengono impostate una volta dentro .bash_profile. Qui sta il mio problema.

Apparentemente, il motivo per cui li stavo impostando in due punti era a causa dello schermo. lo schermo sembra solo eseguire .bashrce non sembra ereditare PATHcorrettamente la mia o qualsiasi altra variabile d'ambiente dalla mia shell bash originale. Poiché viene eseguito solo .bashrce ora imposto solo le mie variabili .bash_profile, ottengo un incompleto PATH.

La mia domanda, quindi, è come ottenere le mie variabili di ambiente sullo schermo senza la duplicazione. Leggere i Bashdocumenti sembra indicare che potrebbe essere il tipo di shell utilizzato dallo schermo per accedere, ovvero una shell interattiva senza accesso, ma non sono riuscito a capire come forzare lo schermo a utilizzare un particolare tipo di shell, solo il shell da usare via -s /bin/bash.

Puoi consultare i miei file di configurazione nella mia pagina GitHub . Questo è il commit commit che ha rotto lo schermo .

EDIT: sto usando Screen version 4.00.03 (FAU) 23-Oct-06e tendo a invocarloscreen -h 50000

EDIT: ora sono stato in grado di testarlo su Cygwin ( CYGWIN_NT-5.1 1.7.1(0.218/5/3) i686, Screen version 4.00.03 (FAU) 23-Oct-06) e mostra un comportamento diverso rispetto al mio Mac.

Il comportamento specifico che ho scoperto ora è che in Cygwin le modifiche apportate PATHa .bash_profile vengono duplicate quando si accede a screen e quindi la successiva creazione di finestre dello schermo non duplica il percorso ma re-source .bash_profile.

Per illustrare il comportamento di cui sto parlando:

Uscita da un nuovo terminale:

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Uscita dalla prima chiamata dello schermo:

[~]$ screen -h 50000 -s -/bin/bash

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Chiamate successive a C-a c:

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Puoi vedere


La duplicazione è perché bash è configurato per aggiungere incondizionatamente queste voci con una shell 'login', e stai dicendo a screen di invocare bash come shell 'login'. Ho riscritto la mia risposta per cercare di affrontare i problemi generali delle shell, dello schermo e delle variabili di ambiente.
Chris Johnsen,

Risposte:


16

schermo e variabili d'ambiente

Per impostazione predefinita, lo schermo passa alle sue shell (e ad altri processi) qualunque sia la variabile di ambiente che aveva all'avvio della sessione (cioè la riconnessione non cambia quali variabili di ambiente vengono assegnate alle nuove shell). Ma poiché sia ​​i file di configurazione dello schermo che quelli delle shell cambiano comunemente le variabili di ambiente, ci sono molti posti in cui è possibile introdurre cambiamenti imprevisti. Ci sono alcune variabili, come TERM , che lo schermo cambia quasi sempre, ma sono generalmente richieste per le funzionalità fornite dallo schermo .

Diciamo che né la configurazione della shell, né la configurazione dello schermo modificheranno una variabile chiamata FOOBAR (abbastanza probabilmente, tutto sommato). Se si avvia una sessione con FOOBAR=foo screen, tutte le shell create in quella sessione avranno una variabile di ambiente denominata FOOBAR con un valore di foo.

Le cose si complicano per le variabili che possono essere modificate dallo schermo o dalla shell.

Impostazioni mancanti durante l'utilizzo della schermata

Shell di accesso

Se scopri che mancano alcune impostazioni nelle shell avviate dallo schermo , potrebbe essere perché la tua shell è configurata solo per aggiornare quelle impostazioni per le shell 'login'. La maggior parte delle shell comprende una convenzione speciale (in C:) **argv == '-'che lo schermo può essere configurato per l'uso.

Per la documentazione dello schermo :

comando shell

Imposta il comando da utilizzare per creare una nuova shell. Questo sostituisce il valore della variabile di ambiente $ SHELL. Ciò è utile se si desidera eseguire un potenziatore tty che prevede di eseguire il programma specificato in $ SHELL. Se il comando inizia con un carattere '-', la shell verrà avviata come shell di login.

Per avere le shell di avvio dello schermo come shell di "login", avvia lo schermo con screen -s -/bin/basho aggiungi questa riga al tuo .screenrc:

shell -/bin/bash

Regola il percorso di qualunque shell tu stia usando.

configurazione dello schermo

Mancanti o variabili d'ambiente di ripristino potrebbe anche essere a causa di setenve unsetenvcomandi in uno schermata di file di configurazione. Dovrai controllare sia il .screenrc nella tua home directory sia il file che la tua compilation di screen sta usando come "system screenrc" (potresti provare un comando come strings "$(which screen)" | fgrep -i screenrctrovare il percorso che è stato configurato al momento della compilazione - di solito è / etc / screenrc per una schermata installata dal sistema ; le installazioni aggiuntive probabilmente useranno qualche altro nome percorso). È possibile utilizzare SCREENRC=/dev/null SYSSCREENRC=/dev/null screenper evitare temporaneamente questi file di impostazioni, ma esiste un'opzione di compilazione che impedisce l'uso efficace di SYSSCREENRC (presumibilmente in modo che gli amministratori di sistema possano forzare un po 'di configurazione iniziale).

Impostazioni duplicate quando si utilizza lo schermo

È abbastanza comune aggiungere elementi a una variabile di ambiente come PATH nei file di configurazione di una shell in modo che il valore aggiornato sia disponibile per le normali sessioni di shell (ad esempio xterm o altre finestre di terminale, sessioni di console, ecc.). Se tali elementi vengono aggiunti nella configurazione per shell di una shell (o, se si utilizza l' -/path/to/shellimpostazione descritta sopra, nella configurazione di shell per accesso), la shell avviata dalla schermata avrà probabilmente più copie degli elementi aggiunti.

Una strategia per evitarlo è quella di inserire tutte le aggiunte a variabili come PATH nella configurazione per login della shell ed evitare di utilizzare l' -/path/to/shellimpostazione della shell con schermo .

Un'altra strategia è quella di aggiungere solo in modo condizionale i nuovi elementi alla variabile. A seconda della shell, il codice per farlo può essere un po 'complicato, ma di solito può essere incapsulato in una funzione shell per un facile utilizzo.

Un'altra strategia è quella di iniziare sempre con un valore fisso nei file di configurazione. Questo a volte può causare problemi quando si spostano i file di configurazione da un sistema all'altro quando i valori predefiniti possono variare in modo significativo.

Diagnostica

Se non riesci a individuare direttamente dove si sta verificando una particolare modifica, puoi provare quanto segue per rintracciare dove sta avvenendo la modifica.

Controlla il valore corrente nella shell iniziale:

echo "$PATH"

Controlla come la shell stessa modifica il valore quando viene creata una sotto-shell:

/bin/bash -c 'echo "$PATH"'

Controlla come la shell modifica il valore quando viene creata una sotto-shell 'login':

perl -e '$s=shift;exec {$s} "-$s", @ARGV or die "unable to start shell"' /bin/bash
echo "$PATH"
exit

Controlla come lo schermo modifica il valore:

printf '#!/bin/sh\nl=/tmp/echo-var.log;rm -f "$l"; echo $PATH >"$l"' >/tmp/echo-var &&
chmod a+x /tmp/echo-var &&
screen -s /tmp/echo-var &&
cat /tmp/echo-var.log

Questo risolve parte del mio problema. Sfortunatamente non è completo. Ora, lo schermo funziona bene screen -s -/bin/bashma non si comporta come mi aspettavo che si comportasse sotto Cygwin sulla mia macchina da lavoro. Su quella macchina, corro screen -h 50000e semplicemente eredita il mio PATHsenza effettivamente approvare di nuovo il file. Questo funziona sia ogni volta che lancio una nuova finestra.
Tim Visher,

L'ambiente del processo dello schermo dovrebbe essere sempre ereditato da tutti i suoi figli (ad eccezione di cose come TERM che potrebbe sovrascrivere). Prova a FOOBAR=baz screencontrollare echo $FOOBARnelle finestre della shell da screene screen -s -/bin/bash. Entrambe le varianti dovrebbero avere FOOBAR= baz. Se il tuo PATHviene modificato, dovrai rintracciare ciò che lo sta facendo. Prova SYSSCREENRC=/dev/null SCREENRC=/dev/null screen, se questo ti lascia PATHpassare, allora probabilmente è un setenv PATHin /etc/screenrco ~/.screenrc. Altrimenti è qualcosa che stai .bashrcfacendo.
Chris Johnsen,

Ho fatto una grande riscrittura / aggiunta alla mia risposta.
Chris Johnsen

2

L'ultima volta che ho visto un problema simile, l'ho risolto utilizzando screen -lall'avvio della schermata.

È possibile utilizzare l' -lopzione quando si richiama screen(attivare la modalità di accesso ; controllata anche dai comandi deflogine loginin .screenrc) per impostare se lo schermo deve accedere alla finestra per impostazione predefinita (aggiungendo / rimuovendo la voce / etc / utmp).

La modalità di accesso è attiva per impostazione predefinita, ma può essere modificata in fase di compilazione. Se lo schermo non è compilato con il supporto utmp, questi comandi non sono disponibili.

Sembra che non mi serva la -lmodalità nella schermata predefinita di Debian Lenny (v4.0.3); sembra essere attivo di default. Mio ~/.profilee ~/.bashrcsto leggendo correttamente. Come stai invocando screen? Quale versione stai usando?


secondo questa teoria, nonscreen -ln dovrebbe funzionare il mio , e ancora funziona. quindi prova la bandiera, ma questa probabilmente non è la risposta giusta. lo lascerò qui per il momento. ~/.profile-l
Quack Quixote,

Sembra che -lcontrolli solo se screenaggiunge una voce al utmpfile, non se invoca nuove shell con la propria -lopzione o usa la -custom exec-with- -prefix.
Chris Johnsen,


1

Non c'è niente di sbagliato nel reperire il tuo .bashrc dall'interno di .bash_profile. Se stai usando la tua macchina solo localmente, nella maggior parte dei casi il tuo .bash_profile verrà fornito solo quando esegui il tuo login iniziale (ci sono ovviamente altre volte che vengono acquistate).

Organizzo i miei file in modo che se voglio che qualcosa venga fatto solo quando eseguo l'accesso, inserisco le informazioni in .bash_profile e per tutto il resto le inserisco in .bashrc. PATH è una cosa che ho inserito nel mio .bashrc e ho creato il sorgente .bashrc nel mio .bash_profile.


Ti andrebbe di pubblicare post .bashrce .bash_profilefile da qualche parte in modo da poterli vedere? Il problema che ho riscontrato mentre facevo qualcosa di simile era che PATHcresceva ogni volta che creavo una nuova istanza dello schermo perché ereditava quella vecchia PATHe quindi aggiungeva nuovamente tutto.
Tim Visher,

Scusa Tim, non l'ho visto ... Ho cambiato molte cose in giro, quindi non avranno molto senso, ma questo è fondamentalmente quello che faccio. # .bash_profile se [-f ~ / .bashrc]; poi . ~ / .bashrc fi Quindi inserisco tutto il resto in .bashrc, ad eccezione delle cose che voglio iniziare al primo accesso, che vanno anche in .bash_profile. PATH viene gestito in .bashrc come una serie di righe anziché come una definizione di percorso come la maggior parte esporta PATH = / path / to / binaries1: $ PATH export PATH = / path / to / binaries2: $ PATH

0

Ogni volta che ho qualche problema del genere creo un file $HOME/.debuge in tutti i file di origine / eseguiti durante il login / invocazione della shell (per esempio ~/.bashrc, ~/.bash_profile, ~/.profile, /etc/bashrc, ecc) ho come la prima linea

test -f $HOME/.debug && echo $HOME/.bashrc 1>&2

o simili. Per il debug specifico puoi anche aggiungere cose come

test -f $HOME/.debug && echo PATH now equals $PATH 1>&2

In questo modo puoi essere sicuro al 100% di quali file siano o meno utilizzati.

Il reindirizzamento a stderr è importante, non vuoi che qualcosa si rovini stdout in molte situazioni.


0

Puoi rimanere con .profile poiché il sistema non tocca bashrc (come la sessione grafica) Ora hai semplicemente due diversi set di ambienti - uno da .profile, l'altro per bash da .bashrc.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.