Come testare possibili conflitti durante l'utilizzo dell'alias in bashrc?


12

Esiste un modo semplice per elencare tutti i conflitti di comandi che si sono verificati nel sistema a causa dell'aggiornamento bashrc che coinvolge comandi alias?

Ad esempio, qualcuno scrive alias ls=/path/to/user-generated/executablein bashrc. Come si può scoprire che si tratta di mascherare un comando effettivo ( ls). Un modo sembra essere quello di eseguire tutti gli alias prima e dopo l'approvvigionamento di bashrc e diff l'output. Ci sono modi migliori?

Sto eseguendo Ubuntu 12.04.

bash: versione

GNU bash, versione 4.2.24 (1) -release (i686-pc-linux-gnu)


Come nota a margine, in genere è più utile alle persone che rispondono se si fornisce la versione di bash, anziché la versione del sistema operativo quando si pone una domanda specifica per bash.
Giordania,

@jordanm Aggiornato.
user13107,

Risposte:


8

Per scoprire quali comandi sono mascherati dagli alias, fai qualcosa del genere:

alias | sed 's/^[^ ]* *\|=.*$//g' | while read a; do
  printf "%20.20s : %s\n" $a "$(type -ta $a | tr '\n' ' ')"
done | awk -F: '$2 ~ /file/'

Spiegazione

aliasda solo elenca gli alias definiti ed sedestrae il loro nome. Il ciclo while viene eseguito type -tasu ciascuno di essi e awkstampa le righe che contengono alias e file.


15

Puoi usare typeper scoprire come un comando verrebbe interpretato da bash.


Ad esempio, type lsstampa ls is aliased to `ls --color=auto'qui.
l0b0

Lo stesso funziona con which, ma ora non so se entrambi i tipi di shell (tipo, quali) sono uguali.
matematica

@math: type whichte lo dice which is /usr/bin/which, quindi non è incorporato. Pertanto, non può dirti se qualcosa è incorporato o meno (ad es. which echoContro type echo).
Choroba,

Immagino che dipenda dalla shell che usi: type which which is a shell builtinsto usando zsh.
matematica

@math: la domanda originale è taggata / bash.
Choroba,

7

Come prima domanda, non c'è modo di elencare i conflitti, poiché bash usa internamente una tabella hash, registra solo l'ultima sostituzione.

Per scoprire se un comando è un alias, usa alias lsnel tuo caso, se ti dice qualcosa come "non trovato", allora non è un alias, altrimenti lo è.

Per avviare la funzione originale trascurando l'alias, prefissare una barra, ad esempio \lsavvierà il hash reale ls, ignorando l'alias.

MODIFICARE

Se vuoi sapere rapidamente se un comando è un alias, puoi abilitare la modalità di debug da set -x, ora se esegui ls:

inserisci qui la descrizione dell'immagine

Vedrai un output di debug del comando reale in esecuzione

Per annullare la modalità di debug, utilizzare set -


Grazie. Ma non ho ottenuto la aliasparte. Cosa succede se un utente non sa che esiste un comando (ad es. ls)? L'unica cosa che sembra sapere dopo l'esecuzione alias lsè ciò a cui è mappato e non a cosa è stato originariamente associato. Immagino che si dovranno eseguire tutti i comandi con e senza \ per trovare conflitti.
user13107,

@ user13107 ha aggiornato la risposta
daisy il

Grazie. Come posso annullare la traccia?
user13107,

@ user13107 aggiornato di nuovo ;-P
margherita

1
"Non c'è modo di elencare i conflitti" - non sei abbastanza fantasioso.
Camh,

6

È possibile utilizzare il built-in bash compgenper ottenere un elenco di tutti i comandi e tutti gli alias che utilizzano compgen -ac. Qualsiasi comando che è anche un alias verrà duplicato in questo elenco, quindi la semplice soluzione ingenua è quella di cercare duplicati nell'output di compgen -ac.

Tuttavia, possono anche apparire duplicati se un comando si trova sul percorso due volte. Ad esempio, ho /bin/whiche /usr/bin/whichquindi compgen -acelencherò whichdue volte anche se non è un alias.

Quindi è necessario ottenere tutti i duplicati compgen -ace confrontarli con un elenco di alias. Solo i duplicati che sono anche alias sono quegli alias che nascondono i comandi. Possiamo farlo con il comm(1)comando e con la sostituzione del processo bash.

comm -12 <(compgen -a | sort) <(compgen -ac | sort | uniq -d) 

compgen -a | sortè l'elenco di tutti gli alias (ordinati per comm). compgen -ac | sort | uniq -dè l'elenco di tutti i duplicati dall'elenco di comandi e alias. comm -12produce solo quelle linee comuni a entrambi.


5

Puoi usare la funzione di debug della shell per vedere esattamente cosa sta succedendo quando bash invoca una shell interattiva. Quanto segue dovrebbe mostrare tutti gli alias assegnati quando una shell interattiva viene generata da una shell di accesso:

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x -> abilita il debug
  • -l -> login shell
  • -i -> shell interattiva
  • -c -> comando

L'esecuzione del comando exit è necessaria affinché la shell ritorni. Il -iè necessario in questo caso perché bash non impostare un ambiente interattivo per eseguire un comando altrimenti.

Ecco un esempio dal mio sistema:

$ bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
++ alias 'ls=ls --color=auto'
$ alias -p
alias ls='ls --color=auto'

Per vedere quale file è stato acquistato l'ultima volta quando è stato assegnato l'alias per determinare il file che si è verificato, è possibile estendere grep:

bash -x -l -i -c 'exit' 2>&1 | grep -E ' (alias|[.]|source) '

Ciò può restituire falsi positivi, ma dovrebbe andare bene se si stanno controllando manualmente i dati restituiti. Il numero di simboli "+" davanti al comando eseguito indica la profondità.

+ . /home/jordan/.bashrc
++ alias 'ls=ls --color=auto'
++ . /home/jordan/.foo
+++ alias t=test
++ alias t=test2

In questo esempio di output, mostra che .bashrc imposta un alias per ls, .foo aliases t, e quindi .bashrc sostituisce l'alias precedente di t.


Grazie. Questo è certamente utile, ma non è in grado di vedere come trova il conflitto creando alias.
user13107,

@ user13107 Ho aggiunto alcuni dettagli che dovrebbero essere utili. L'impostazione di un alias su un nuovo valore non è un alias "in conflitto". Si tratta di un normale comportamento documentato, motivo per cui è necessario un metodo circolare.
Giordania,
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.