Perché systemctl \ {restart, status} \ sshd \; opera?


14

L'output del comando precedente quando viene passato tramite echo è:

# echo systemctl\ {restart,status}\ sshd\;
systemctl restart sshd; systemctl status sshd;

Anche se incollo l'output sul terminale, il comando funziona. Ma quando provo ad eseguire direttamente il comando, ottengo:

# systemctl\ {restart,status}\ sshd\;
bash: systemctl restart sshd;: command not found...

Ho due domande ..

  1. Come si chiama esattamente questo metodo di sostituzione ed espansione? (In modo che io possa ricercarlo e saperne di più su di esso e su come usarlo correttamente).
  2. Cosa ho fatto di sbagliato qui? Perché non funziona?

Risposte:


26

È una forma di espansione del rinforzo eseguita nella shell. L'idea di espansione del rinforzo è corretta, ma il modo in cui è stato utilizzato non è corretto qui. Quando intendevi fare:

systemctl\ {restart,status}\ sshd\;

La shell interpreta systemctl restart sshd;un unico comando lungo e tenta di eseguirlo, e non è stato in grado di individuare un binario per eseguirlo in quel modo. Perché in questa fase, la shell tenta di tokenizzare gli elementi nella riga di comando prima di creare il comando completo con argomenti - ma non è ancora successo.

Per tali valori di espansione noti, è possibile utilizzare evaled essere ancora al sicuro, ma assicurarsi di ciò che si sta tentando di espandere con esso.

eval systemctl\ {restart,status}\ sshd\;

Ma preferirei usare un ciclo invece con for, invece di provare a scrivere una riga o usare eval:

for action in restart status; do
    systemctl "$action" sshd
done

19

Questo si chiama espansione di parentesi graffe (come indica il tag).

Cosa ho fatto di sbagliato qui? Perché non funziona?

Considera le fasi coinvolte nella lettura e nell'esecuzione di una riga di comando in bash (ad esempio):

  1. legge una riga
  2. analizza un comando eventualmente composto in comandi semplici componenti
  3. fa varie espansioni sui semplici comandi (espansione parentesi graffa, divisione di parole, globbing, ecc.)
  4. quindi esegue i comandi semplici (con altre fasi omesse per chiarezza).

Quello che stai cercando di fare è influenzare (2) da (3). La suddivisione basata su ;è nello stage (2), quando analizza i comandi composti. Quando (3) si sta verificando l'espansione del controvento, è già troppo tardi per provare a creare un comando composto.


6

La prima riga

echo systemctl\ {restart,status}\ sshd\;

espandi come token 3

  • eco
  • systemctl restart sshd;
  • systemctl status sshd;

quindi eco echo gli ultimi due token e sembra OK.

allo stesso modo la seconda riga

systemctl\ {restart,status}\ sshd\;

si espande come 2 token

  • systemctl restart sshd;
  • systemctl status sshd;

e bash prova a cercare un eseguibile systemctl restart sshd;che non è riuscito a trovare.

Potresti desiderare di iniziare il tuo viaggio sul lato oscuro facendo eval systemctl\ {restart,status}\ sshd\;attenzione agli imprevisti.


quindi, la soluzione sarebbe la divisione delle parole, giusto? Come si può fare?
Somenath Sinha,
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.