L'espansione della cronologia è disabilitata negli script?


9

Comprendo che il seguente errore è dovuto !all'espansione della cronologia utilizzata:

$ echo "Hello!Tim"
bash: !Tim: event not found

Tuttavia, se inserisco il comando in uno script ed eseguo lo script, non ci sono problemi:

$ cat myscript
echo "Hello!Tim"
$ bash myscript 
Hello!Tim

Perché? Il manuale di Bash menziona il motivo?


1
Bella domanda, semplicemente dichiarata. Molto ben fatto!
Carattere jolly

Sulla base di ciò che sto leggendo qui: gnu.org/software/bash/manual/html_node/History-Interaction.html Credo che dovresti usare una sorta di shoptmodificatore per farlo funzionare nella tua sceneggiatura. So che non è proprio la risposta che stai cercando.
jesse_b

Qual è il caso d'uso? Che tipo di sceneggiatura eseguiresti per espandere la tua storia precedente? O espanderebbe i comandi precedenti dallo script?
Jeff Schaller

@JeffSchaller, l'espansione della cronologia numerica in uno script con numeri positivi sembra un'idea davvero negativa, ma potrei facilmente immaginare casi d'uso !!o !-2(numeri storici negativi / relativi) o simili. Principalmente sarebbero risolti meglio in altri modi, ma è comunque una buona domanda su come funziona la shell (e quando devi / non hai bisogno di sfuggire ai tuoi esclamativi!).
Wildcard il

Risposte:


12

Sì, l'espansione della cronologia è abilitata per impostazione predefinita solo per le shell interattive.

Per abilitarlo per uno script di shell, scrivi:

set -H

Per disabilitarlo in una shell interattiva, scrivi:

set +H

Per determinare se l'espansione della cronologia è attualmente abilitata, utilizzare una qualche forma del seguente codice:

case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac

Iniziando a insegnare una classe di shell, ho approfondito il manuale per cercare di stabilire cosa sia realmente una "shell interattiva". È una domanda idromassaggio, quindi lascia che ti risparmi qualche problema:

La shell ha MOLTE opzioni. Alcune di queste opzioni sono inizializzate in diversi modi quando la shell ha un terminale di controllo (o quando inizia con -i, blah blah, qualunque cosa, vedi sotto).

TUTTE le opzioni della shell possono essere modificate individualmente.

Una "shell interattiva" è un termine ingannevole quando si tenta di definirlo con precisione. È davvero solo una raccolta di impostazioni delle opzioni.

Alla domanda su quali impostazioni rendono interattiva o meno una shell è impossibile rispondere; diventa ridicolo. È esattamente la stessa domanda filosofica della Nave di Teseo .

Se si avvia una shell interattiva, ma si disabilita l'espansione della cronologia, si usa il --noeditingflag, si imposta --norc, si spegne expand_aliases, ecc., Ecc., In che senso la shell è interattiva? Oppure, quando non diventa più interattivo? Non puoi rispondere a queste domande.

La verità è che "interattivo" è solo un'etichetta conveniente per una raccolta di varie opzioni di shell. Allo stesso modo "non interattivo". Stessa cosa; solo una raccolta di comportamenti che possono essere cambiati singolarmente.

In conclusione: la shell si comporta in modo diverso quando viene avviata "in modo interattivo" rispetto a quando viene avviata "in modo non interattivo". Cercare di definire con precisione questi termini dopo l'avvio è sciocco. Basta guardare ogni singola opzione della shell per capirne il comportamento.


Avevo dimenticato che oltre alla mia ricerca, l'ho pubblicato ampiamente su questo stesso sito.


Grazie. Nel manuale, trovo solo "Questa opzione è attivata per impostazione predefinita per le shell interattive" per set -H. È probabilmente la tua deduzione che "l'espansione della cronologia è abilitata di default solo per le shell interattive".
Tim

@ Tim, vedi il resto della mia risposta. Quella frase del manuale è molto scivolosa e cerca di ottenere la risposta a "che cos'è una shell interattiva?" uscire dalla pagina man è come parlare in cerchio. Non va da nessuna parte.
Carattere jolly

Quello che PUOI dire è che il seguente frammento di codice mostrerà sempre se l'espansione della cronologia è abilitata nella shell corrente:case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac
Wildcard

@Tim, a proposito, non ho idea di cosa tu voglia dire che è la mia "inferenza", perché questo è il chiaro significato di set -H. Questa è l'opzione histexpand.
Carattere jolly

1
Ho provato questo su uno script e non ha funzionato fino a quando non l'ho fatto anche io set -o history, dopo aver verificato set -odallo script che era disabilitato.
Daniel C. Sobral,
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.