Onlangs heb ik het echo-commando gebruikt met het voorvoegsel $. Tot mijn verbazing was het resultaat een fout. Mijn commando was ongeveer zo.

# !/bin/bash $(echo "a") 

De fout was ..

./test1.sh: line 3: a: command not found 

Kan iemand uitleggen wat hier gebeurt? Bij voorbaat dank.

Answer

$(echo a) is een “opdrachtvervanging”. De $(...) zal worden vervangen door de uitvoer van het commando binnen . De uitvoer is in dit geval a, die de shell vervolgens probeert uit te voeren. De shell “kan het commando genaamd a niet vinden en je krijgt de foutmelding.

Het is onduidelijk wat je bedoeling hiermee was of wat je verwachtte dat er zou gebeuren . Het is hoogst ongebruikelijk om het resultaat van een opdrachtvervanging uit te willen voeren.


Sommige programmas voeren strings uit die door de shell moeten worden geëvalueerd. Het is daarom mogelijk om zie code zoals

eval "$(ssh-agent)" 

die de uitvoer van het gegeven commando evalueert (uitvoert). Deze commandos hebben een strikt gespecificeerde uitvoer en worden over het algemeen als veilig beschouwd om hierin uit te voeren manier. In het bovenstaande voorbeeld zal ssh-agent het SSH-agentproces starten en een paar opdrachten uitvoeren die de juiste omgevingsvariabelen instellen die de ssh client zal later nodig zijn om de agent te gebruiken, bijvoorbeeld

SSH_AUTH_SOCK=/tmp/ssh-Ppg1EO5eRIZp/agent.6017; export SSH_AUTH_SOCK; SSH_AGENT_PID=6018; export SSH_AGENT_PID; echo Agent pid 6018; 

Dit wordt vervolgens geëvalueerd door eval.

eval wordt hier gebruikt in plaats van alleen door simpelweg $(ssh-agent) te gebruiken, aangezien de uitvoer van het ssh-agent commando meer een samengesteld commando is. Zonder eval, zouden de ; opdrachtterminators net speciaal zijn.

Voorbeeld:

$ s="echo hello; echo world" $ $s hello; echo world $ eval "$s" hello world 

Reacties

  • OTOH, eval "$(dircolors)" is redelijk om te doen. Hetzelfde met verschillende andere commandos die dat patroon volgen, zoals gpg-agent.
  • @derobert Ja, en $(ssh-agent). Goed punt.

Antwoord

Je kunt set -x gebruiken om kijk wat de shell doet:

set -x $(echo "a") ++ echo a + a 

De shell voert echo a uit en plaatst de uitvoer op de opdrachtregel. Dit is hetzelfde als wanneer u had geprobeerd deze opdrachtregel uit te voeren:

a 

De shell zoekt naar een commando a in het pad (en zelfs daarvoor in de functie, alias en hash-lijsten), vindt het niet en genereert dus een fout.

Het werkt als de uitvoer een geldig commando is:

$(echo "ls") 

Reacties

  • kun je me vertellen waarvoor we eigenlijk $ other gebruiken dan een variabele aanroepen.
  • @Ashu Het wordt duidelijk ook gebruikt voor het vervangen van commandos – jouw geval. Bovendien verschijnt het in berekening (echo $((1+2+3))), het maken van tekenreeksen ($'foo\nbar' / $"foo") en (minder shell-gerelateerd) in de regexes die bash begrijpt ([[ foo =~ ^f..$ ]]). Het wordt ook gebruikt om variabelen op verschillende manieren te wijzigen: ${foo#bar}

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *