Nyligen använde jag echo-kommandot med prefixet $. Till min förvåning var det ett fel. Mitt kommando var ungefär så här.

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

Felet var ..

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

Kan någon förklara vad som händer här. Tack på förhand.

Svar

$(echo a) är ett ”kommandosubstitution”. $(...) kommer att ersättas med utdata från kommandot inom . Utgången i detta fall är a, som skalet sedan försöker utföra. Skalet kan inte hitta kommandot a och du får felmeddelandet.

Det är oklart vad din avsikt med detta var eller vad du förväntade dig att hända . Det är mycket ovanligt att vilja utföra resultatet av en kommandosubstitution.


Vissa program matar ut strängar som ska utvärderas av skalet. Det är därför möjligt att se kod som

eval "$(ssh-agent)" 

som utvärderar (kör) utdata för det givna kommandot. Dessa kommandon har en strikt specificerad utgång och anses i allmänhet vara säkra att köra i I exemplet ovan startar ssh-agent SSH-agentprocessen och matar ut några kommandon som ställer in lämpliga miljövariabler som ssh klienten kommer senare att behöva använda agenten, till exempel

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

Detta utvärderas sedan av eval.

eval används här snarare än bara helt enkelt att använda $(ssh-agent) eftersom utdata från ssh-agent -kommandot är mer ett sammansatt kommando. Utan eval skulle kommandoterminatorerna ; vara speciella.

Exempel:

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

Kommentarer

  • OTOH, eval "$(dircolors)" är en rimlig sak att göra. Samma som med flera andra kommandon som följer det mönstret, som gpg-agent.
  • @derobert Ja och $(ssh-agent). Bra poäng.

Svar

Du kan använda set -x för att se vad skalet gör:

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

Skalet kör echo a och lägger utdata på kommandoraden. Detta är samma som om du hade försökt att utföra den här kommandoraden:

a 

Skalet letar efter ett kommando a i sökvägen (och till och med tidigare i funktionen, alias och hashlistor), hittar den inte och kastar därmed ett fel.

Det fungerar om utgången är ett giltigt kommando:

$(echo "ls") 

Kommentarer

  • kan du berätta för mig, vad för egentligen använder vi $ andra än att anropa en variabel.
  • @Ashu Det används uppenbarligen också för kommandosubstitution – ditt fall. Förutom det visas i beräkning (echo $((1+2+3))), strängskapande ($'foo\nbar' / $"foo") och (mindre skalrelaterat) i regexerna som bash förstår ([[ foo =~ ^f..$ ]]). Den används också för att ändra variabler på flera sätt: ${foo#bar}

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *